/*
Copyright 2012-2013, Polyvi Inc. (http://polyvi.github.io/openxface)
This program is distributed under the terms of the GNU General Public License.
This file is part of xFace.
xFace is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
xFace is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with xFace. If not, see <http://www.gnu.org/licenses/>.
*/
package com.polyvi.xface.app;
import java.io.File;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import android.content.Context;
import com.polyvi.xface.XSecurityPolicy;
import com.polyvi.xface.XStartParams;
import com.polyvi.xface.core.XAppRunningMode;
import com.polyvi.xface.core.XConfiguration;
import com.polyvi.xface.core.XIResourceFilter;
import com.polyvi.xface.core.XISystemContext;
import com.polyvi.xface.core.XIdleWatcher;
import com.polyvi.xface.core.XLocalMode;
import com.polyvi.xface.util.XConstant;
import com.polyvi.xface.util.XFileUtils;
import com.polyvi.xface.util.XStringUtils;
import com.polyvi.xface.view.XAppWebView;
/**
* 用于描述一个app应用,包含app的描述信息、状态及UI界面
*/
public class XApplication implements XIApplication {
/** 所有应用图标所在目录的名称 */
public static final String APPS_ICON_DIR_NAME = "app_icons";
public static final String TAG_EXT_PERMISSIONS = "all";
/** 系统上下文环境 */
private XISystemContext mSysContext;
/** app对应的视图 */
private XAppWebView mAppView;
/** 应用描述信息 */
private XAppInfo mAppInfo;
/** app的workspace */
private String mWorkSpace = "";
/** 用于存放App的通信数据 */
private Map<String, Object> mDatas;
private boolean mIsOverrideBackbutton = false;
private boolean mIsOverrideVolumeButtonDown = false;
private boolean mIsOverrideVolumeButtonUp = false;
/** < 默认为本地运行模式 */
private XAppRunningMode mRunningMode = new XLocalMode();
/** 监视app是否处于空闲状态 */
private XIdleWatcher mWatcher;
/** app的安全策略 */
private XSecurityPolicy mSecurityPolicy;
public XApplication(XAppInfo appInfo) {
updateAppInfo(appInfo);
}
public XApplication(String appId) {
mAppInfo = new XAppInfo();
mAppInfo.setAppId(appId);
}
public void init(XISystemContext sysContext) {
mSysContext = sysContext;
mDatas = new Hashtable<String, Object>();
initWorkSpace();
}
/**
* 获取app对应的view
*/
public XAppWebView getView() {
return mAppView;
}
/**
* 获取应用描述信息
*
* @return
*/
public XAppInfo getAppInfo() {
return mAppInfo;
}
/**
* 设置应用配置信息
*/
public void updateAppInfo(XAppInfo appInfo) {
this.mAppInfo = appInfo;
initAppRunningMode();
}
/**
* 获取应用id
*/
public String getAppId() {
return mAppInfo.getAppId();
}
/**
* 获取应用视图id
*
* @return 应用id
*/
public int getViewId() {
return mAppView == null ? XAppWebView.EMPTPY_VIEW_ID : mAppView
.getViewId();
}
/**
* 将app加载到appView上面显示
*
* @param url
* [in] 应用的url
*/
public void loadAppIntoView(String url) {
mSysContext.loadView(this, url);
}
public void loadAppIntoView(String url, boolean showWaiting) {
mSysContext.loadView(this, url);
}
/**
* 获取app的图片url
*
* @return url
*/
public String getAppIconUrl() {
return mRunningMode.getIconUrl(mAppInfo);
}
/**
* 设置app运行模式
*
* @param mode
* [in] app运行模式
*/
public void setAppRunningMode(XAppRunningMode mode) {
if (mode != null)
mRunningMode = mode;
}
/**
* 初始化app的运行模式 根据app的配置文件指定运行模式
*/
private void initAppRunningMode() {
setAppRunningMode(XAppRunningMode.createAppRunningMode(mAppInfo
.getRunModeConfig()));
}
/**
* 初始化应用程序的工作目录,若不存在,创建该目录,然后设置工作目录为其他用户可读
*/
private void initWorkSpace() {
mWorkSpace = XConfiguration.getInstance().getAppInstallDir()
+ getAppId() + File.separator + XConstant.APP_WORK_DIR_NAME;
File appWorkDir = new File(mWorkSpace);
if (!appWorkDir.exists()) {
appWorkDir.mkdirs();
}
// 设置工作目录的权限为其它用户可执行
setWorkSpaceExecutableByOther();
}
/**
* 返回该应用程序的工作目录
*
* @return 应用程序的工作目录
*/
public String getWorkSpace() {
return mWorkSpace;
}
/**
* 设置工作目录的权限为其它用户可执行
*/
private void setWorkSpaceExecutableByOther() {
XFileUtils.setPermission(XFileUtils.EXECUTABLE_BY_OTHER, XConfiguration
.getInstance().getAppInstallDir());
XFileUtils.setPermission(XFileUtils.EXECUTABLE_BY_OTHER, XConfiguration
.getInstance().getAppInstallDir() + getAppId());
XFileUtils.setPermission(XFileUtils.EXECUTABLE_BY_OTHER, mWorkSpace);
}
/**
* 返回存放该应用程序数据的目录,若不存在,创建该目录 应用对该目录没有读写权限
*
* @return 存放该应用程序数据的目录
*/
public String getDataDir() {
String dataDirPath = XConfiguration.getInstance().getAppInstallDir()
+ getAppId() + File.separator + XConstant.APP_DATA_DIR_NAME;
File appDataDir = new File(dataDirPath);
if (!appDataDir.exists()) {
appDataDir.mkdirs();
}
return dataDirPath;
}
/**
* 获取资源迭代器
*
* @param filter
* 安全资源过滤器
* @return
*/
public Iterator<byte[]> getResourceIterator(XIResourceFilter filter) {
return mRunningMode.createResourceIterator(this, filter);
}
/**
* 当前app是否是活动状态的
*/
public boolean isActive() {
return null != mAppView;
}
/**
* 设置backbutton是否被重写
*
* @param overrideBackbutton
* 为true表示要重写 为false表示不重写
*/
public void setOverrideBackbutton(boolean overrideBackbutton) {
mIsOverrideBackbutton = overrideBackbutton;
}
/**
* 设置volume button down是否被重写
*
* @param overrideVolumeButtonDown
* 为true表示要重写 为false表示不重写
*/
public void setOverrideVolumeButtonDown(boolean overrideVolumeButtonDown) {
mIsOverrideVolumeButtonDown = overrideVolumeButtonDown;
}
/**
* 设置volume button up是否被重写
*
* @param overrideVolumeButtonUp
* 为true表示要重写 为false表示不重写
*/
public void setOverrideVolumeButtonUp(boolean overrideVolumeButtonUp) {
mIsOverrideVolumeButtonUp = overrideVolumeButtonUp;
}
/**
* 得到backbutton是否被重写
*
* @return 返回true表示被重写 返回false表示没有重写
*/
public boolean isOverrideBackbutton() {
return mIsOverrideBackbutton;
}
/**
* 得到volume button down是否被重写
*
* @return 返回true表示被重写 返回false表示没有重写
*/
public boolean isOverrideVolumeButtonDown() {
return mIsOverrideVolumeButtonDown;
}
/**
* 得到volume button up是否被重写
*
* @return 返回true表示被重写 返回false表示没有重写
*/
public boolean isOverrideVolumeButtonUp() {
return mIsOverrideVolumeButtonUp;
}
/**
* 存放app的数据的数据
*
* @param key
* @param value
*/
public void setData(String key, Object value) {
mDatas.put(key, value);
}
/**
* 删除数据
*
* @param key
*/
public void removeData(String key) {
mDatas.remove(key);
}
/**
* 获得数据
*
* @param key
* 键值
* @return
*/
public Object getData(String key) {
return mDatas.get(key);
}
public String getIntalledDir() {
return XConfiguration.getInstance().getAppInstallDir()
+ mAppInfo.getAppId() + File.separator;
}
/**
* 清理页面缓存.
* @param includeDiskFile 是否包含磁盘文件
*/
public void clearCache(boolean includeDiskFile) {
if (null != mAppView) {
mAppView.clearCache(includeDiskFile);
}
}
/**
* 卸载应用的缓存数据,例如:离线应用的缓存、http缓存、localStorage信息
*
* @param context
*/
public void releaseData(Context context) {
//发送清除webview的缓存的事件
this.clearCache(false);
mRunningMode.clearAppData(this, context);
}
/**
* 加载错误显示页面
*/
public void loadErrorPage() {
String errorPageUrl = XConstant.FILE_SCHEME + getDataDir()
+ File.separator + XConstant.ERROR_PAGE_NAME;
loadAppIntoView(errorPageUrl);
}
public void setView(XAppWebView view) {
mAppView = view;
view.setOwnerApp(this);
}
@Override
public boolean start(XStartParams params) {
// 处理启动参数 和页面
String pageEntry = null;
String startData = null;
if (null != params) {
pageEntry = params.pageEntry;
startData = params.data;
}
if (!XStringUtils.isEmptyString(pageEntry)) {
mAppInfo.setEntry(pageEntry);
}
if (!XStringUtils.isEmptyString(startData)) {
setData(XConstant.TAG_APP_START_PARAMS, startData);
}
if(null == mSecurityPolicy) {
//安全策略为空,则采用系统默认的安全策略
mSecurityPolicy = mSysContext.getSecurityPolicy();
}
mRunningMode.loadApp(this, mSecurityPolicy);
return true;
}
@Override
public boolean close() {
if (null != mWatcher) {
mWatcher.stop();
}
closeView();
return mSysContext.getSecurityPolicy().checkAppClose(this);
}
public String getBaseUrl() {
return mRunningMode.getAppUrl(this);
}
/**
* 启动监视器
*/
public void startIdleWatcher(long interval, Runnable task) {
if (null != mWatcher) {
stopIdleWatcher();
}
mWatcher = new XIdleWatcher();
mWatcher.start(interval, task);
}
/**
* 停止监视
*/
public void stopIdleWatcher() {
if (mWatcher != null) {
mWatcher.stop();
mWatcher = null;
}
}
/**
* 重置IdleWatcher
*/
public void resetIdleWatcher() {
if (null != mWatcher) {
mWatcher.notifyOperatered();
}
}
/**
* 关闭app view
*/
private void closeView() {
mAppView.willClosed();
mSysContext.unloadView(mAppView);
if (null != mAppView) {
this.mAppView.setValid(false);
}
mAppView = null;
}
/**
* 获取系统上下文环境
*
* @return
*/
public XISystemContext getSystemContext() {
return mSysContext;
}
/**
* 加载js
*
* @param statement
* js参数
*/
public void loadJavascript(String statement) {
StringBuffer sb = new StringBuffer();
sb.append("javascript:");
sb.append(statement);
this.getView().loadUrl(sb.toString());
}
/**
* 设置安全策略
* @param policy
*/
public void setAppSecurityPolicy(XSecurityPolicy policy) {
mSecurityPolicy = policy;
}
}