private void loadAllPlugin(Context context) { long b = System.currentTimeMillis(); ArrayList<File> apkfiles = new ArrayList<File>(); File baseDir = new File(PluginDirHelper.getBaseDir(context)); File[] dirs = baseDir.listFiles(); for (File dir : dirs) { if (dir.isDirectory()) { File file = new File(dir, "apk/base-1.apk"); if (file.exists()) { apkfiles.add(file); } } } Log.i(TAG, "Search apk cost %s ms", (System.currentTimeMillis() - b)); b = System.currentTimeMillis(); if (apkfiles != null && apkfiles.size() > 0) { for (File pluginFile : apkfiles) { long b1 = System.currentTimeMillis(); try { PluginPackageParser pluginPackageParser = new PluginPackageParser(mContext, pluginFile); Signature[] signatures = readSignatures(pluginPackageParser.getPackageName()); if (signatures == null || signatures.length <= 0) { pluginPackageParser.collectCertificates(0); PackageInfo info = pluginPackageParser.getPackageInfo(PackageManager.GET_SIGNATURES); saveSignatures(info); } else { mSignatureCache.put(pluginPackageParser.getPackageName(), signatures); pluginPackageParser.writeSignature(signatures); } if (!mPluginCache.containsKey(pluginPackageParser.getPackageName())) { mPluginCache.put(pluginPackageParser.getPackageName(), pluginPackageParser); } } catch (Throwable e) { Log.e(TAG, "parse a apk file error %s", e, pluginFile.getPath()); } finally { Log.i( TAG, "Parse %s apk cost %s ms", pluginFile.getPath(), (System.currentTimeMillis() - b1)); } } } Log.i(TAG, "Parse all apk cost %s ms", (System.currentTimeMillis() - b)); b = System.currentTimeMillis(); try { mActivityManagerService.onCreate(IPluginManagerImpl.this); } catch (Exception e) { Log.e(TAG, "mActivityManagerService.onCreate", e); } Log.i(TAG, "ActivityManagerService.onCreate %s ms", (System.currentTimeMillis() - b)); }
@Override public List<PackageInfo> getInstalledPackages(int flags) throws RemoteException { waitForReadyInner(); try { enforcePluginFileExists(); List<PackageInfo> infos = new ArrayList<PackageInfo>(mPluginCache.size()); if (shouldNotBlockOtherInfo()) { for (PluginPackageParser pluginPackageParser : mPluginCache.values()) { infos.add(pluginPackageParser.getPackageInfo(flags)); } } else { List<String> pkgs = mActivityManagerService.getPackageNamesByPid(Binder.getCallingPid()); for (PluginPackageParser pluginPackageParser : mPluginCache.values()) { if (pkgs.contains(pluginPackageParser.getPackageName())) { infos.add(pluginPackageParser.getPackageInfo(flags)); } } } return infos; } catch (Exception e) { handleException(e); } return null; }
@Override public PackageInfo getPackageInfo(String packageName, int flags) throws RemoteException { waitForReadyInner(); try { String pkg = getAndCheckCallingPkg(packageName); if (pkg != null) { enforcePluginFileExists(); PluginPackageParser parser = mPluginCache.get(pkg); if (parser != null) { PackageInfo packageInfo = parser.getPackageInfo(flags); if (packageInfo != null && (flags & PackageManager.GET_SIGNATURES) != 0 && packageInfo.signatures == null) { packageInfo.signatures = mSignatureCache.get(packageName); } return packageInfo; } } } catch (Exception e) { handleException(e); } return null; }
@Override public int installPackage(String filepath, int flags) throws RemoteException { // install plugin String apkfile = null; try { PackageManager pm = mContext.getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(filepath, 0); if (info == null) { return PackageManagerCompat.INSTALL_FAILED_INVALID_APK; } apkfile = PluginDirHelper.getPluginApkFile(mContext, info.packageName); if ((flags & PackageManagerCompat.INSTALL_REPLACE_EXISTING) != 0) { forceStopPackage(info.packageName); if (mPluginCache.containsKey(info.packageName)) { deleteApplicationCacheFiles(info.packageName, null); } new File(apkfile).delete(); Utils.copyFile(filepath, apkfile); PluginPackageParser parser = new PluginPackageParser(mContext, new File(apkfile)); parser.collectCertificates(0); PackageInfo pkgInfo = parser.getPackageInfo(PackageManager.GET_PERMISSIONS | PackageManager.GET_SIGNATURES); if (pkgInfo != null && pkgInfo.requestedPermissions != null && pkgInfo.requestedPermissions.length > 0) { for (String requestedPermission : pkgInfo.requestedPermissions) { boolean b = false; try { b = pm.getPermissionInfo(requestedPermission, 0) != null; } catch (NameNotFoundException e) { } if (!mHostRequestedPermission.contains(requestedPermission) && b) { Log.e(TAG, "No Permission %s", requestedPermission); new File(apkfile).delete(); return PluginManager.INSTALL_FAILED_NO_REQUESTEDPERMISSION; } } } saveSignatures(pkgInfo); // if (pkgInfo.reqFeatures != null && pkgInfo.reqFeatures.length > 0) { // for (FeatureInfo reqFeature : pkgInfo.reqFeatures) { // Log.e(TAG, "reqFeature name=%s,flags=%s,glesVersion=%s", // reqFeature.name, reqFeature.flags, reqFeature.getGlEsVersion()); // } // } copyNativeLibs(mContext, apkfile, parser.getApplicationInfo(0)); dexOpt(mContext, apkfile, parser); mPluginCache.put(parser.getPackageName(), parser); mActivityManagerService.onPkgInstalled(mPluginCache, parser, parser.getPackageName()); sendInstalledBroadcast(info.packageName); return PackageManagerCompat.INSTALL_SUCCEEDED; } else { if (mPluginCache.containsKey(info.packageName)) { return PackageManagerCompat.INSTALL_FAILED_ALREADY_EXISTS; } else { forceStopPackage(info.packageName); new File(apkfile).delete(); Utils.copyFile(filepath, apkfile); PluginPackageParser parser = new PluginPackageParser(mContext, new File(apkfile)); parser.collectCertificates(0); PackageInfo pkgInfo = parser.getPackageInfo(PackageManager.GET_PERMISSIONS | PackageManager.GET_SIGNATURES); if (pkgInfo != null && pkgInfo.requestedPermissions != null && pkgInfo.requestedPermissions.length > 0) { for (String requestedPermission : pkgInfo.requestedPermissions) { boolean b = false; try { b = pm.getPermissionInfo(requestedPermission, 0) != null; } catch (NameNotFoundException e) { } if (!mHostRequestedPermission.contains(requestedPermission) && b) { Log.e(TAG, "No Permission %s", requestedPermission); new File(apkfile).delete(); return PluginManager.INSTALL_FAILED_NO_REQUESTEDPERMISSION; } } } saveSignatures(pkgInfo); // if (pkgInfo.reqFeatures != null && pkgInfo.reqFeatures.length > 0) { // for (FeatureInfo reqFeature : pkgInfo.reqFeatures) { // Log.e(TAG, "reqFeature name=%s,flags=%s,glesVersion=%s", // reqFeature.name, reqFeature.flags, reqFeature.getGlEsVersion()); // } // } copyNativeLibs(mContext, apkfile, parser.getApplicationInfo(0)); dexOpt(mContext, apkfile, parser); mPluginCache.put(parser.getPackageName(), parser); mActivityManagerService.onPkgInstalled(mPluginCache, parser, parser.getPackageName()); sendInstalledBroadcast(info.packageName); return PackageManagerCompat.INSTALL_SUCCEEDED; } } } catch (Exception e) { if (apkfile != null) { new File(apkfile).delete(); } handleException(e); return PackageManagerCompat.INSTALL_FAILED_INTERNAL_ERROR; } }