这里接着上一篇开始写,上一篇只是讲了在startBootstrapServices中启动PackageManagerService部分的代码,剩余的在startOtherServices中PackageManagerService相关设置操作没有分析到,这一篇接着分析下面遗留的问题:
- mPackageManagerService.updatePackagesIfNeeded
- mPackageManagerService.performFstrimIfNeeded
- mPackageManagerService.systemReady
- mPackageManagerService.waitForAppDataPrepared
一. mPackageManagerService.updatePackagesIfNeeded
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public void updatePackagesIfNeeded() { enforceSystemOrRoot("Only the system can request package update"); // 判断是否是FOTA升级 boolean causeUpgrade = isUpgrade(); // 判断是否是第一次开机或者恢复出厂设置或者FOTA到pre-N版本 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; // 判断是否有清除过Dalvik虚拟机的Cache boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); // 如果不存在上面三种情况,则直接返回,不需要执行更新Package if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { return; } List<PackageParser.Package> pkgs; synchronized (mPackages) { // 这里会按照Package的重要程度来给他们分配优先级 // core app优先级最高,系统app次之,接着是被其他app以来的app,最后则是最近未被使用和剩余的app pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); } final long startTime = System.nanoTime(); // 这里最后会调用到mInstaller.dexopt()方法,mInstaller会和Installd进行通信完成Dex优化升级 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT), false /* bootComplete */); final int elapsedTimeSeconds = (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); } |
上面的代码首先判断是否需要对Package进行更新,如果需要更新的话会首先按照Package的重要程度给其赋予一个优先级,然后调用performDexOptUpgrade完成dex优化升级。
二.mPackageManagerService.performFstrimIfNeeded
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public void performFstrimIfNeeded() { enforceSystemOrRoot("Only the system can request fstrim"); try { // 获取MountService IStorageManager sm = PackageHelper.getStorageManager(); if (sm != null) { boolean doTrim = false; // 获取执行FTRIM间隔,默认是3天,可以通过setting provider更改这个时间 final long interval = android.provider.Settings.Global.getLong( mContext.getContentResolver(), android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, DEFAULT_MANDATORY_FSTRIM_INTERVAL); if (interval > 0) { final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance(); // 上一次执行strim到现在超过三天,这需要执行FTRIM if (timeSinceLast > interval) { doTrim = true; Slog.w(TAG, "No disk maintenance in " + timeSinceLast + "; running immediately"); } } if (doTrim) { final boolean dexOptDialogShown; synchronized (mPackages) { dexOptDialogShown = mDexOptDialogShown; } if (!isFirstBoot() && dexOptDialogShown) { try { // 显示一个带提示信息的窗口 ActivityManager.getService().showBootMessage( mContext.getResources().getString( R.string.android_upgrading_fstrim), true); } catch (RemoteException e) { } } // 发送消息H_FSTRIM给handler,然后再向vold发送fstrim命令 sm.runMaintenance(); } } else { Slog.e(TAG, "storageManager service unavailable!"); } } catch (RemoteException e) { // Can't happen; StorageManagerService is local } } |
上面主要是执行磁盘清理工作,释放磁盘空间。
三.mPackageManagerService.systemReady
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
public void systemReady() { enforceSystemOrRoot("Only the system can claim the system is ready"); mSystemReady = true; // 获取PackageManagerService的ContentResolver final ContentResolver resolver = mContext.getContentResolver(); ContentObserver co = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { mEphemeralAppsDisabled = (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) || (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0); } }; mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE), false, co, UserHandle.USER_SYSTEM); mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM); co.onChange(true); // 禁用运营商的app CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, mContext.getContentResolver(), UserHandle.USER_SYSTEM); // 系统处于ready时,读取系统的兼容性设置 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( mContext.getContentResolver(), android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; // 设置PackageParser是否启用兼容性设置 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); if (DEBUG_SETTINGS) { Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); } int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; synchronized (mPackages) { // 检查Preferred Activity是否有更新 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); for (int i=0; i < mSettings.mPreferredActivities.size(); i++) { PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); removed.clear(); for (PreferredActivity pa : pir.filterSet()) { if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { removed.add(pa); } } if (removed.size() > 0) { for (int r=0; r < removed.size(); r++) { PreferredActivity pa = removed.get(r); Slog.w(TAG, "Removing dangling preferred activity: " + pa.mPref.mComponent); pir.removeFilter(pa); } mSettings.writePackageRestrictionsLPr( mSettings.mPreferredActivities.keyAt(i)); } } for (int userId : UserManagerService.getInstance().getUserIds()) { if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { grantPermissionsUserIds = ArrayUtils.appendInt( grantPermissionsUserIds, userId); } } } // 多用户服务 sUserManager.systemReady(); // 升级所有以获取到的默认权限 for (int userId : grantPermissionsUserIds) { mDefaultPermissionPolicy.grantDefaultPermissions(userId); } // 此处调取前面获取默认权限失败时抛出的异常 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); } // 处理所有等待系统就绪的消息 if (mPostSystemReadyMessages != null) { for (Message msg : mPostSystemReadyMessages) { msg.sendToTarget(); } mPostSystemReadyMessages = null; } // 观察外部存储设备 final StorageManager storage = mContext.getSystemService(StorageManager.class); storage.registerListener(mStorageListener); mInstallerService.systemReady(); mPackageDexOptimizer.systemReady(); // Storage相关处理,暂不分析 StorageManagerInternal StorageManagerInternal = LocalServices.getService( StorageManagerInternal.class); StorageManagerInternal.addExternalStoragePolicy( new StorageManagerInternal.ExternalStorageMountPolicy() { @Override public int getMountMode(int uid, String packageName) { if (Process.isIsolated(uid)) { return Zygote.MOUNT_EXTERNAL_NONE; } if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { return Zygote.MOUNT_EXTERNAL_DEFAULT; } if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { return Zygote.MOUNT_EXTERNAL_DEFAULT; } if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { return Zygote.MOUNT_EXTERNAL_READ; } return Zygote.MOUNT_EXTERNAL_WRITE; } @Override public boolean hasExternalStorage(int uid, String packageName) { return true; } }); // 清除过期的userid和app sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); if (mPrivappPermissionsViolations != null) { Slog.wtf(TAG,"Signature|privileged permissions not in " + "privapp-permissions whitelist: " + mPrivappPermissionsViolations); mPrivappPermissionsViolations = null; } } |
这一部分主要是当PKMS准备就绪是,更新一些Package的信息、默认权限的获取以及通知在等待PKMS就绪的主件。下面接着分析最后一个方法调用。
四.mPackageManagerService.waitForAppDataPrepared
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void waitForAppDataPrepared() { if (mPrepareAppDataFuture == null) { return; } ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData"); mPrepareAppDataFuture = null; } public static <T> T waitForFutureNoInterrupt(Future<T> future, String description) { try { return future.get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException(description + " interrupted"); } catch (ExecutionException e) { throw new RuntimeException(description + " failed", e); } } |
&emps; 上面一段代码看是获取特定的feature的。
这一篇就到这里啦,简简单单看了下PKMS初始化之后所作的事情。感觉处理第一个函数对package的信息进行更新和第二个函数对存储空间进行回收外并没有做特别多的事情。