会涉及 PackageInstaller PackageManager PackageManagerService

PackageInstaller PackageManager PackageManagerService

  • 涉及文件
    • packages\apps\PackageInstaller
    • frameworks/base/core/java/android/content/pm/PackageManager.java
    • frameworks/base/core/java/android/content/pm/IPackageManager.aidl
    • frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

PackageInstaller

系统默认内置应用,主要提供安装、升级、卸载应用等功能。既支持完整安装包也支持拆分包。 任何应用都可以通过创建 PackageInstaller.Session 来安装应用;首先创建会话,然后安装程序把一个或多个安装包流式传输到位并决定是进行安装还是销毁会话。安装过程需要用户参与进行交互。 会话能够安装全新的应用、升级已安装的应用或把拆分包添加到现有的应用。 相关 API 具体可参考 Android 官方文档:PackageInstallerPackageInstaller.Session PackageInstaller 其实主要是处理用户交互的,向用户展示即将安装的应用的基本信息:图标、名称和需要的权限等,以及安装进度和安装结果。 调用安装程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
private void install(String filePath) {
    File apkFile = new File(filePath);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Uri contentUri = FileProvider.getUriForFile(
                                                    mContext
                                                    , "{USER.PACKAGE.NAME}.fileprovider"
                                                    , apkFile);
        intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
    } else {
        intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
    }
    startActivity(intent);
}

PackageManager

该类主要用于检索已经安装应用的信息,可以通过 Context.getPackageManager() 获取。相关 API 具体可以参考 Android 官方文档:PackageManager

获取 PackageManager

Context 类的抽象方法一般都由 ContextImpl 子类实现。

  1. Context.getPackageManager()

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }
    
        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            // 没有使用同步,可能会有多个实例
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }
    
        return null;
    }
  2. ActivityThread.getPackageManager()

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    public static IPackageManager getPackageManager() {
        if (sPackageManager != null) {
            return sPackageManager;
        }
        // 这个就不往下分析了,获取到其实是  BinderProxy
        IBinder b = ServiceManager.getService("package");
        // 这个获取到是  IPackageManager.Stub.Proxy;
        // 既是  PackageManagerService 服务端  Binder 的远程代理
        sPackageManager = IPackageManager.Stub.asInterface(b);
        return sPackageManager;
    }
  3. ApplicationPackageManager()

    1
    2
    3
    4
    5
    6
    
    protected ApplicationPackageManager(ContextImpl context,
                                        IPackageManager pm) {
        mContext = context;
        // 所有需要  Binder 通讯都交由  mPM 处理
        mPM = pm;
    }

PackageManager 其实相当于 PackageManagerService 的远程代理是一个抽象类,其实现类是: ApplicationPackageManager

PackageManagerService

这个才是今天的主角

类图

略。和 PowerManagerService 类似,与 PackageManager 的通讯是基于 AIDL 的,最终通过 Binder 实现。

启动

  1. SystemServer 部分

     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
    
    private void run() {
        // Start services.
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    }
    
    private void startBootstrapServices() {
        // Start the package manager.
        // 启动  PackageManagerService 服务  <2.>
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                                                            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
    
        // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
        // A/B artifacts after boot, before anything else might touch/need them.
        // Note: this isn't needed during decryption (we don't have /data anyways).
        if (!mOnlyCore) {
            boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false);
            if (!disableOtaDexopt) {
                OtaDexoptService.main(mSystemContext, mPackageManagerService);
            }
        }
    }
    
    private void startOtherServices() {
        if (!mOnlyCore) {
            // 是否要更新应用,像  OTA 升级后应用可能会有变动  <3.>
            mPackageManagerService.updatePackagesIfNeeded();
        }
        // 执行  fstrim
        mPackageManagerService.performFstrimIfNeeded();
        // 系统已经准备好了,做相应的收尾工作 <4.>
        mPackageManagerService.systemReady();
    
        mActivityManagerService.systemReady(() -> {
                // Wait for all packages to be prepared
                mPackageManagerService.waitForAppDataPrepared();
            }, BOOT_TIMINGS_TRACE_LOG);
    }
  2. main()

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    public static PackageManagerService main(Context context, Installer installer,
                                             boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        // 检查系统设置,存储在 *.prop 文件中的值
        PackageManagerServiceCompilerMapping.checkProperties();
        // 构建  PackageManagerService,factoryTest 标记是否是测试模式,onlyCore 标记是否只加载核心应用
        PackageManagerService m = new PackageManagerService(context, installer,
                                                            factoryTest, onlyCore);
        // 支持多用户时不加载黑名单中的应用
        m.enableSystemUserPackages();
        // 注册到  ServiceManager
        ServiceManager.addService("package", m);
        // Native 层的  PackagerManagerNative,这里是服务端不是代理
        final PackageManagerNative pmn = m.new PackageManagerNative();
        ServiceManager.addService("package_native", pmn);
        return m;
    }
  3. 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
    
    public void updatePackagesIfNeeded() {
        enforceSystemOrRoot("Only the system can request package update");
    
        // We need to re-extract after an OTA.
        // 判断系统是否是  OTA 升级后开机
        boolean causeUpgrade = isUpgrade();
    
        // First boot or factory reset.
        // Note: we also handle devices that are upgrading to N right now as if it is their
        //       first boot, as they do not have profile data.
        // 系统是首次启动或恢复出厂设置之后启动;或者升级到  N 的首次启动,有生成配置文件
        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
    
        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
        // 如果虚拟机缓存文件有剪裁,比如  ota 之后
        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
    
        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
            return;
        }
    
        List<PackageParser.Package> pkgs;
        synchronized (mPackages) {
            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
        }
    
        final long startTime = System.nanoTime();
        // 有时会显示:系统正在升级的弹窗
        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
                                                 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
                                                 false /* bootComplete */);
    
        final int elapsedTimeSeconds =
            (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
    }
  4. 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
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    
    public void systemReady() {
        enforceSystemOrRoot("Only the system can claim the system is ready");
    
        mSystemReady = true;
        // 监听是否允许网络及时应用
        final ContentResolver resolver = mContext.getContentResolver();
        ContentObserver co = new ContentObserver(mHandler) {
                @Override
                public void onChange(boolean selfChange) {
                    mWebInstantAppsDisabled =
                        (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.Secure
                                                              .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
        co.onChange(true);
    
        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
        // disabled after already being started.
        // 禁止运营商应用,直到相匹配的  SIM 插入
        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
                                                          mContext.getContentResolver(), UserHandle.USER_SYSTEM);
    
        // Read the compatibilty setting when the system is ready.
        // 阅读兼容性设置
        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
                                                                                   mContext.getContentResolver(),
                                                                                   android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
        if (DEBUG_SETTINGS) {
            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
        }
    
        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
    
        synchronized (mPackages) {
            // Verify that all of the preferred activity components actually
            // exist.  It is possible for applications to be updated and at
            // that point remove a previously declared activity component that
            // had been set as a preferred activity.  We try to clean this up
            // the next time we encounter that preferred activity, but it is
            // possible for the user flow to never be able to return to that
            // situation so here we do a sanity check to make sure we haven't
            // left any junk around.
            // 清理首选应用,比如:设置中默认  Chrome 为首选浏览器但  Chrome 已被移除,需要清理该默认浏览器选项
            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();
        // If we upgraded grant all default permissions before kicking off.
        // 升级默认权限
        for (int userId : grantPermissionsUserIds) {
            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
        }
    
        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
            // If we did not grant default permissions, we preload from this the
            // default permission exceptions lazily to ensure we don't hit the
            // disk on a new user creation.
            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
        }
    
        // Now that we've scanned all packages, and granted any default
        // permissions, ensure permissions are updated. Beware of dragons if you
        // try optimizing this.
        // 扫描所有包并更新默认权限
        synchronized (mPackages) {
            mPermissionManager.updateAllPermissions(
                                                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
                                                    mPermissionCallback);
        }
    
        // Kick off any messages waiting for system ready
        // 发送所有消息等待系统准备完毕
        if (mPostSystemReadyMessages != null) {
            for (Message msg : mPostSystemReadyMessages) {
                msg.sendToTarget();
            }
            mPostSystemReadyMessages = null;
        }
    
        // Watch for external volumes that come and go over time
        // 监听外部卷的改变
        final StorageManager storage = mContext.getSystemService(StorageManager.class);
        storage.registerListener(mStorageListener);
    
        mInstallerService.systemReady();
        mDexManager.systemReady();
        mPackageDexOptimizer.systemReady();
        // 外部卷挂载方式
        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(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;
                                                            }
                                                        });
    
        // Now that we're mostly running, clean up stale users and apps
        // 清理工作
        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
    
        mPermissionManager.systemReady();
    
        if (mInstantAppResolverConnection != null) {
            mContext.registerReceiver(new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        mInstantAppResolverConnection.optimisticBind();
                        mContext.unregisterReceiver(this);
                    }
                }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
        }
    }

构造