diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/Constant.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/Constant.java index b86e5dad..c165717d 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/Constant.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/Constant.java @@ -72,6 +72,11 @@ public class Constant { */ public static final String LOCAL_PLUGIN_APK_LIB_DIR = "p_n"; + /** + * "纯APK"插件同版本升级时插件、Odex、Native(SO库)的用于覆盖的存放目录 + */ + public static final String LOCAL_PLUGIN_APK_COVER_DIR = "p_c"; + /** * 插件文件名,name-low-high-current.jar * 插件文件名规范:barcode-1-10-2.jar diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/MP.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/MP.java index 676be69c..0bbfc0e3 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/MP.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/MP.java @@ -272,7 +272,7 @@ public static final boolean pluginUninstall(String pluginName) { if (LOG) { LogDebug.d(PLUGIN_TAG, "MP.pluginUninstall ... pluginName=" + pluginName); } - PluginInfo pi = getPlugin(pluginName, false); + PluginInfo pi = getPlugin(pluginName, true); // 插件未安装 if (pi == null) { diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginManager.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginManager.java index e06f3ea9..ab5118a4 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginManager.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginManager.java @@ -20,6 +20,7 @@ import android.text.TextUtils; import com.qihoo360.i.IPluginManager; +import com.qihoo360.mobilesafe.api.Tasks; import com.qihoo360.replugin.base.IPC; import com.qihoo360.replugin.component.process.PluginProcessHost; import com.qihoo360.replugin.helper.LogDebug; @@ -84,6 +85,8 @@ static final int getPluginProcessIndex() { */ @Deprecated static final void init(Context context) { + // 初始化操作,方便后面执行任务,不必担心Handler为空的情况 + Tasks.init(); // sUid = android.os.Process.myUid(); diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PmBase.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PmBase.java index a8f0cf30..aaf422f5 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PmBase.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PmBase.java @@ -1121,6 +1121,11 @@ final void pluginUninstalled(PluginInfo info) { LogDebug.d(PLUGIN_TAG, "Clear plugin cache. pn=" + info.getName()); } + // 移除卸载插件的HashMap缓存 + if (mPlugins.containsKey(info.getName())) { + mPlugins.remove(info.getName()); + } + // 移除卸载插件表快照 PluginTable.removeInfo(info); diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java index 44d4acb7..a665873f 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfo.java @@ -108,6 +108,10 @@ public class PluginInfo implements Parcelable, Cloneable { // 若插件需要卸载,则会有此值 private PluginInfo mPendingDelete; + // 若插件需要同版本覆盖安装更新,则会有此值 + private PluginInfo mPendingCover; + private boolean mIsPendingCover; + private PluginInfo(JSONObject jo) { initPluginInfo(jo); } @@ -155,6 +159,10 @@ public PluginInfo(PluginInfo pi) { if (pi.mPendingDelete != null) { this.mPendingDelete = new PluginInfo(pi.mPendingDelete); } + this.mIsPendingCover = pi.mIsPendingCover; + if (pi.mPendingCover != null) { + this.mPendingCover = new PluginInfo(pi.mPendingCover); + } } private void initPluginInfo(JSONObject jo) { @@ -171,6 +179,15 @@ private void initPluginInfo(JSONObject jo) { if (djo != null) { mPendingDelete = new PluginInfo(djo); } + + // 缓存"待覆盖安装"的插件信息 + JSONObject cjo = jo.optJSONObject("coverinfo"); + if (cjo != null) { + mPendingCover = new PluginInfo(cjo); + } + + // 缓存"待覆盖安装"的插件覆盖字段 + mIsPendingCover = jo.optBoolean("cover"); } // 通过别名和包名来最终确认插件名 @@ -347,6 +364,7 @@ public boolean isDexExtracted() { /** * 获取APK存放的文件信息
* 若为"纯APK"插件,则会位于app_p_a中;若为"p-n"插件,则会位于"app_plugins_v3"中
+ * 注意:若支持同版本覆盖安装的话,则会位于app_p_c中;
* * @return Apk所在的File对象 */ @@ -356,6 +374,8 @@ public File getApkFile() { File dir; if (isPnPlugin()) { dir = context.getDir(Constant.LOCAL_PLUGIN_SUB_DIR, 0); + } else if (getIsPendingCover()) { + dir = context.getDir(Constant.LOCAL_PLUGIN_APK_COVER_DIR, 0); } else { dir = context.getDir(Constant.LOCAL_PLUGIN_APK_SUB_DIR, 0); } @@ -365,6 +385,7 @@ public File getApkFile() { /** * 获取Dex(优化后)生成时所在的目录
* 若为"纯APK"插件,则会位于app_p_od中;若为"p-n"插件,则会位于"app_plugins_v3_odex"中
+ * 若支持同版本覆盖安装的话,则会位于app_p_c中;
* 注意:仅供框架内部使用 * * @return 优化后Dex所在目录的File对象 @@ -374,6 +395,8 @@ public File getDexParentDir() { Context context = RePluginInternal.getAppContext(); if (isPnPlugin()) { return context.getDir(Constant.LOCAL_PLUGIN_ODEX_SUB_DIR, 0); + } else if (getIsPendingCover()) { + return context.getDir(Constant.LOCAL_PLUGIN_APK_COVER_DIR, 0); } else { return context.getDir(Constant.LOCAL_PLUGIN_APK_ODEX_SUB_DIR, 0); } @@ -394,6 +417,7 @@ public File getDexFile() { /** * 根据类型来获取SO释放的路径
* 若为"纯APK"插件,则会位于app_p_n中;若为"p-n"插件,则会位于"app_plugins_v3_libs"中
+ * 若支持同版本覆盖安装的话,则会位于app_p_c中;
* 注意:仅供框架内部使用 * * @return SO释放路径所在的File对象 @@ -404,6 +428,8 @@ public File getNativeLibsDir() { File dir; if (isPnPlugin()) { dir = context.getDir(Constant.LOCAL_PLUGIN_DATA_LIB_DIR, 0); + } else if (getIsPendingCover()) { + dir = context.getDir(Constant.LOCAL_PLUGIN_APK_COVER_DIR, 0); } else { dir = context.getDir(Constant.LOCAL_PLUGIN_APK_LIB_DIR, 0); } @@ -491,6 +517,62 @@ public void setPendingDelete(PluginInfo info) { } } + /** + * 是否已准备好了新待覆盖的版本? + * + * @return 是否已准备好 + */ + public boolean isNeedCover() { + return mPendingCover != null; + } + + /** + * 获取将来要覆盖更新的插件的信息,将会在下次启动时才能被使用 + * + * @return 插件覆盖安装信息 + */ + public PluginInfo getPendingCover() { + return mPendingCover; + } + + /** + * 设置插件的覆盖更新信息。此信息有可能等到下次才能被使用
+ * 注意:若为“纯APK”方案所用,则修改后需调用PluginInfoList.save来保存,否则会无效 + * + * @param info 插件覆盖安装信息 + */ + public void setPendingCover(PluginInfo info) { + mPendingCover = info; + if (info != null) { + JSONHelper.putNoThrows(mJson, "coverinfo", info.getJSON()); + } else { + mJson.remove("coverinfo"); + } + } + + /** + * 此PluginInfo是否包含同版本覆盖的字段?只在调用RePlugin.install方法才能看到
+ * 注意:仅框架内部使用 + * + * @return 是否包含同版本覆盖字段 + */ + public boolean getIsPendingCover() { + return mIsPendingCover; + } + + /** + * 设置PluginInfo的同版本覆盖的字段
+ * 注意:仅框架内部使用
+ */
+ public void setIsPendingCover(boolean coverInfo) {
+ mIsPendingCover = coverInfo;
+ if (mIsPendingCover) {
+ JSONHelper.putNoThrows(mJson, "cover", mIsPendingCover);
+ } else {
+ mJson.remove("cover");
+ }
+ }
+
/**
* 获取最小支持宿主API的版本
*/
diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java
index 6eb74d0a..e7400f11 100644
--- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java
+++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/replugin/model/PluginInfoList.java
@@ -74,6 +74,20 @@ public void remove(String pn) {
JSONHelper.remove(mJson, i);
}
}
+ if (mMap.containsKey(pn)) {
+ mMap.remove(pn);
+ }
+ removeListElement(mList, pn);
+ }
+
+ private void removeListElement(List