会介绍 PackageInstaller PackageManager PackageManagerService 之间的联系及 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. 调用安装程序:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    private void installApp(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);
    }
  2. Intent 匹配

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    <activity android:name=".InstallStart"
              android:exported="true"
              android:excludeFromRecents="true">
      <intent-filter android:priority="1">
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.INSTALL_PACKAGE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="file" />
        <data android:scheme="content" />
        <data android:mimeType="application/vnd.android.package-archive" />
      </intent-filter>
      <intent-filter android:priority="1">
        <action android:name="android.intent.action.INSTALL_PACKAGE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="file" />
        <data android:scheme="package" />
        <data android:scheme="content" />
      </intent-filter>
      <intent-filter android:priority="1">
        <action android:name="android.content.pm.action.CONFIRM_PERMISSIONS" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </activity>

应用卸载

  1. 调用卸载程序:

    1
    2
    3
    4
    5
    6
    7
    
    public static void unstallApp(Context context, String packageName){
        Intent uninstall_intent = new Intent();
        uninstall_intent.setAction(Intent.ACTION_DELETE);
        uninstall_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        uninstall_intent.setData(Uri.parse("package:"+packageName));
        context.startActivity(uninstall_intent);
    }
  2. Intent 匹配

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    <activity android:name=".UninstallerActivity"
              android:configChanges="orientation|keyboardHidden|screenSize"
              android:excludeFromRecents="true"
              android:theme="@style/AlertDialogActivity">
      <intent-filter android:priority="1">
        <action android:name="android.intent.action.DELETE" />
        <action android:name="android.intent.action.UNINSTALL_PACKAGE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="package" />
      </intent-filter>
    </activity>

PackageManager

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

获取 PackageManager

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

  • 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;
    }
  • 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;
    }
  • ApplicationPackageManager()

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

    PackageManager 其实现类是: ApplicationPackageManager 。持有 IPackageManager 对象是 PackageManagerService 的代理。

PackageManagerService

类图

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

启动

  • 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);
    }
  • 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;
    }
  • 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);
    }
  • 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));
        }
    }

构造 PackageManagerService()

  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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
public PackageManagerService(Context context, Installer installer,
                             boolean factoryTest, boolean onlyCore) {
    //LockGuard 验证所有锁定是否以一致的顺序完成,并且如果检测到任何反转则将记录。
    //例如,如果调用线程在保持  PackageManager 锁时试图获取  ActivityManager 锁,它将会提示。
    LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                        SystemClock.uptimeMillis());
    //ro.build.version.sdk 没有设置,这个一般是不可能的
    if (mSdkVersion <= 0) {
        Slog.w(TAG, "**** ro.build.version.sdk not set!");
    }

    mContext = context;
    // 正常情况下,mFactoryTest=false mOnlyCore=false
    mFactoryTest = factoryTest;
    mOnlyCore = onlyCore;
    //分辨率相关
    mMetrics = new DisplayMetrics();
    //用于远程调用  installd
    mInstaller = installer;

    // Create sub-components that provide services / data. Order here is important.
    synchronized (mInstallLock) {
        synchronized (mPackages) {
            // Expose private service for system components to use.
            // PackageManager 加入到  LocalServices 供  SystemServer 内部调用  PackageManagerService
            LocalServices.addService(
                                     PackageManagerInternal.class, new PackageManagerInternalImpl());
            // 用户管理
            sUserManager = new UserManagerService(context, this,
                                                  new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
            // 权限管理
            mPermissionManager = PermissionManagerService.create(context,
                                                                 new DefaultPermissionGrantedCallback() {
                                                                     @Override
                                                                     public void onDefaultRuntimePermissionsGranted(int userId) {
                                                                         synchronized(mPackages) {
                                                                             mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
                                                                         }
                                                                     }
                                                                 }, mPackages /*externalLock*/);
            // 默认权限策略,比如默认情况下  Phone 应该具有电话相关的权限
            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
            // 保存有关动态设置的信息 <1.>
            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
        }
    }
    // Android UID 与  Linux UID 的一一对应关系
    mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                               ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    // 调试相关,默认未设置是空
    String separateProcesses = SystemProperties.get("debug.separate_processes");
    if (separateProcesses != null && separateProcesses.length() > 0) {
        if ("*".equals(separateProcesses)) {
            mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
            mSeparateProcesses = null;
            Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
        } else {
            mDefParseFlags = 0;
            mSeparateProcesses = separateProcesses.split(",");
            Slog.w(TAG, "Running with debug.separate_processes: "
                   + separateProcesses);
        }
    } else {
        mDefParseFlags = 0;
        mSeparateProcesses = null;
    }
    // 用于在包上运行  dexopt 命令的  Helper 类
    mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                                                   "*dexopt*");
    DexManager.Listener dexManagerListener = DexLogger.getListener(this,
                                                                   installer, mInstallLock);
    // 用于处理  dex 文件
    mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock,
                                 dexManagerListener);
    // ArtManagerService Art 虚拟机管理服务
    mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
    // 两个回调
    mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());

    mOnPermissionChangeListeners = new OnPermissionChangeListeners(
                                                                   FgThread.get().getLooper());
    // 存储分辨率、显示等相关信息
    getDefaultDisplayMetrics(context, mMetrics);
    // 系统设置 <2.>
    SystemConfig systemConfig = SystemConfig.getInstance();
    // 支持的功能
    mAvailableFeatures = systemConfig.getAvailableFeatures();
    // 需要特殊保护的包
    mProtectedPackages = new ProtectedPackages(mContext);

    synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            // 该  Handler 将处理  PackageManagerService 的相关消息,APK 的安装就由其负责
            mHandlerThread = new ServiceThread(TAG,
                                               Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
            mHandler = new PackageHandler(mHandlerThread.getLooper());
            // 日志相关
            mProcessLoggingHandler = new ProcessLoggingHandler();
            // 监控堵塞
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
            // 用于管理即时应用
            mInstantAppRegistry = new InstantAppRegistry(this);
            // 保存共享库到当前服务
            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
            final int builtInLibCount = libConfig.size();
            for (int i = 0; i < builtInLibCount; i++) {
                String name = libConfig.keyAt(i);
                String path = libConfig.valueAt(i);
                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
                                    SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
            }
            // 从  mac_permissions.xml 等相关文件加载  SELinux MAC 策略
            SELinuxMMAC.readInstallPolicy();

            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
            // ApplicationInfo#category 的回调
            FallbackCategoryProvider.loadFallbacks();
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
            // 是否首次启动设备
            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            // Clean up orphaned packages for which the code path doesn't exist
            // and they are an update to a system app - caused by bug/32321269
            // 清除孤立包
            final int packageSettingCount = mSettings.mPackages.size();
            for (int i = packageSettingCount - 1; i >= 0; i--) {
                PackageSetting ps = mSettings.mPackages.valueAt(i);
                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
                    && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
                    mSettings.mPackages.removeAt(i);
                    mSettings.enableSystemPackageLPw(ps.name);
                }
            }

            if (mFirstBoot) {
                // 请求把备份系统的数据复制到  data 分区,如果有的话
                requestCopyPreoptedFiles();
            }
            // 获取自定义  ResolverActivity,一般为空,
            //ResolverActivity 用于显示系统启动一个  Intent 的多个匹配项
            String customResolverActivity = Resources.getSystem().getString(
                                                                            R.string.config_customResolverActivity);
            if (TextUtils.isEmpty(customResolverActivity)) {
                customResolverActivity = null;
            } else {
                mCustomResolverComponentName = ComponentName.unflattenFromString(
                                                                                 customResolverActivity);
            }

            long startTime = SystemClock.uptimeMillis();

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                                startTime);
            // 系统启动相关类的环境变量,默认包括 /sysem/frameworks/*.jar
            final String bootClassPath = System.getenv("BOOTCLASSPATH");
            // SystemServer 相关类的环境变量, 包括 /system/framework/services.jar /system/framework/*-service.jar
            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");

            if (bootClassPath == null) {
                Slog.w(TAG, "No BOOTCLASSPATH found!");
            }

            if (systemServerClassPath == null) {
                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
            }
            //  /system/framework 目录
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            // 系统  ota 升级相关
            final VersionInfo ver = mSettings.getInternalVersion();
            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
            if (mIsUpgrade) {
                logCriticalInfo(Log.INFO,
                                "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
            }

            // when upgrading from pre-M, promote system app permissions from install to runtime
            mPromoteSystemApps =
                mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;

            // When upgrading from pre-N, we need to handle package extraction like first boot,
            // as there is no profiling data available.
            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;

            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;

            // save off the names of pre-existing system packages prior to scanning; we don't
            // want to automatically grant runtime permissions for new system apps
            // 在扫描之前保存预先存在的系统包的名称; 我们不希望自动为新系统应用授予运行时权限
            if (mPromoteSystemApps) {
                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
                while (pkgSettingIter.hasNext()) {
                    PackageSetting ps = pkgSettingIter.next();
                    if (isSystemApp(ps)) {
                        mExistingSystemPackages.add(ps.name);
                    }
                }
            }
            // 获取缓存目录,如果是升级的话则删除缓存目录并重新生成缓存
            mCacheDir = preparePackageParserCache(mIsUpgrade);

            // Set flag to monitor and not change apk file paths when
            // scanning install directories.
            // 扫描安装包的默认参数
            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
            // 第一次或  ota 升级后开机
            if (mIsUpgrade || mFirstBoot) {
                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
            }
            // 从指定目录扫描安装包,不同点目录扫描参数不一样 <3.>
            // /system/priv-app,/system/app,/system/frameworks,/vender,/odm 等目录
            // Collect vendor/product overlay packages. (Do this before scanning any apps.)
            // For security and version matching reason, only consider
            // overlay packages if they reside in the right directory.
            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
                            mDefParseFlags
                            | PackageParser.PARSE_IS_SYSTEM_DIR,
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_VENDOR,
                            0);

            // ......

            // Collect ordinary product packages.
            File productAppDir = new File(Environment.getProductDirectory(), "app");
            try {
                productAppDir = productAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(productAppDir,
                            mDefParseFlags
                            | PackageParser.PARSE_IS_SYSTEM_DIR,
                            scanFlags
                            | SCAN_AS_SYSTEM
                            | SCAN_AS_PRODUCT,
                            0);
            // 处理不存在的系统安装包
            // Prune any system packages that no longer exist.
            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
            // 子包必须替换为  data 分区上的完整包或被禁用
            // Stub packages must either be replaced with full versions in the /data
            // partition or be disabled.
            final List<String> stubSystemApps = new ArrayList<>();
            if (!mOnlyCore) {
                // do this first before mucking with mPackages for the "expecting better" case
                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
                while (pkgIterator.hasNext()) {
                    final PackageParser.Package pkg = pkgIterator.next();
                    if (pkg.isStub) {
                        stubSystemApps.add(pkg.packageName);
                    }
                }

                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
                while (psit.hasNext()) {
                    PackageSetting ps = psit.next();

                    /*
                     * If this is not a system app, it can't be a
                     * disable system app.
                     */
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        continue;
                    }

                    /*
                     * If the package is scanned, it's not erased.
                     */
                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
                    if (scannedPkg != null) {
                        /*
                         * If the system app is both scanned and in the
                         * disabled packages list, then it must have been
                         * added via OTA. Remove it from the currently
                         * scanned package so the previously user-installed
                         * application can be scanned.
                         */
                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
                            logCriticalInfo(Log.WARN,
                                            "Expecting better updated system app for " + ps.name
                                            + "; removing system app.  Last known"
                                            + " codePath=" + ps.codePathString
                                            + ", versionCode=" + ps.versionCode
                                            + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
                            removePackageLI(scannedPkg, true);
                            mExpectingBetter.put(ps.name, ps.codePath);
                        }

                        continue;
                    }

                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                        psit.remove();
                        logCriticalInfo(Log.WARN, "System package " + ps.name
                                        + " no longer exists; it's data will be wiped");
                        // Actual deletion of code and data will be handled by later
                        // reconciliation step
                    } else {
                        // we still have a disabled system package, but, it still might have
                        // been removed. check the code path still exists and check there's
                        // still a package. the latter can happen if an OTA keeps the same
                        // code path, but, changes the package name.
                        final PackageSetting disabledPs =
                            mSettings.getDisabledSystemPkgLPr(ps.name);
                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
                            || disabledPs.pkg == null) {
                            possiblyDeletedUpdatedSystemApps.add(ps.name);
                        }
                    }
                }
            }

            //delete tmp files
            deleteTempPackageFiles();

            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();

            // Remove any shared userIDs that have no associated packages
            // 删除没有关联包的任何共享用户标识
            mSettings.pruneSharedUsersLPw();
            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
            final int systemPackagesCount = mPackages.size();
            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
                   + " ms, packageCount: " + systemPackagesCount
                   + " , timePerPackage: "
                   + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
                   + " , cached: " + cachedSystemApps);
            if (mIsUpgrade && systemPackagesCount > 0) {
                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
                                        ((int) systemScanTime) / systemPackagesCount);
            }
            if (!mOnlyCore) {
                // 处理第三方安装包
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                                    SystemClock.uptimeMillis());
                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);

                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
                                | PackageParser.PARSE_FORWARD_LOCK,
                                scanFlags | SCAN_REQUIRE_KNOWN, 0);

                // Remove disable package settings for updated system apps that were
                // removed via an OTA. If the update is no longer present, remove the
                // app completely. Otherwise, revoke their system privileges.
                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
                    final String msg;
                    if (deletedPkg == null) {
                        // should have found an update, but, we didn't; remove everything
                        msg = "Updated system package " + deletedAppName
                            + " no longer exists; removing its data";
                        // Actual deletion of code and data will be handled by later
                        // reconciliation step
                    } else {
                        // found an update; revoke system privileges
                        msg = "Updated system package + " + deletedAppName
                            + " no longer exists; revoking system privileges";

                        // Don't do anything if a stub is removed from the system image. If
                        // we were to remove the uncompressed version from the /data partition,
                        // this is where it'd be done.

                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
                    }
                    logCriticalInfo(Log.WARN, msg);
                }

                /*
                 * Make sure all system apps that we expected to appear on
                 * the userdata partition actually showed up. If they never
                 * appeared, crawl back and revive the system version.
                 */
                for (int i = 0; i < mExpectingBetter.size(); i++) {
                    final String packageName = mExpectingBetter.keyAt(i);
                    if (!mPackages.containsKey(packageName)) {
                        final File scanFile = mExpectingBetter.valueAt(i);

                        logCriticalInfo(Log.WARN, "Expected better " + packageName
                                        + " but never showed up; reverting to system");

                        final @ParseFlags int reparseFlags;
                        final @ScanFlags int rescanFlags;
                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
                            reparseFlags =
                                mDefParseFlags |
                                PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                scanFlags
                                | SCAN_AS_SYSTEM
                                | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(systemAppDir, scanFile)) {

                            // ......

                        } else {
                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                            continue;
                        }

                        mSettings.enableSystemPackageLPw(packageName);

                        try {
                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, "Failed to parse original system package: "
                                   + e.getMessage());
                        }
                    }
                }

                // Uncompress and install any stubbed system applications.
                // This must be done last to ensure all stubs are replaced or disabled.
                // 最后处理子安装包,确保子安装包被整包替换或被禁用
                decompressSystemApplications(stubSystemApps, scanFlags);

                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
                    - cachedSystemApps;

                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
                       + " ms, packageCount: " + dataPackagesCount
                       + " , timePerPackage: "
                       + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
                       + " , cached: " + cachedNonSystemApps);
                if (mIsUpgrade && dataPackagesCount > 0) {
                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
                                            ((int) dataScanTime) / dataPackagesCount);
                }
            }
            mExpectingBetter.clear();

            // Resolve the storage manager.
            // 获取存储管理器
            mStorageManagerPackage = getStorageManagerPackageName();

            // Resolve protected action filters. Only the setup wizard is allowed to
            // have a high priority filter for these actions.
            // 只允许开机向导设为高优先级
            mSetupWizardPackage = getSetupWizardPackageName();
            if (mProtectedFilters.size() > 0) {
                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
                    Slog.i(TAG, "No setup wizard;"
                           + " All protected intents capped to priority 0");
                }
                for (ActivityIntentInfo filter : mProtectedFilters) {
                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
                        // skip setup wizard; allow it to keep the high priority filter
                        continue;
                    }
                    filter.setPriority(0);
                }
            }

            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();

            mDeferProtectedFilters = false;
            mProtectedFilters.clear();

            // Now that we know all of the shared libraries, update all clients to have
            // the correct library paths.
            // 现在我们知道所有共享库,更新所有客户端以获得正确的库路径。
            updateAllSharedLibrariesLPw(null);

            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
                // NOTE: We ignore potential failures here during a system scan (like
                // the rest of the commands above) because there's precious little we
                // can do about it. A settings error is reported, though.
                final List<String> changedAbiCodePath =
                    adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                        final String codePathString = changedAbiCodePath.get(i);
                        try {
                            mInstaller.rmdex(codePathString,
                                             getDexCodeInstructionSet(getPreferredInstructionSet()));
                        } catch (InstallerException ignored) {
                        }
                    }
                }
                // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
                // SELinux domain.
                setting.fixSeInfoLocked();
            }

            // Now that we know all the packages we are keeping,
            // read and update their last usage times.
            mPackageUsage.read(mPackages);
            mCompilerStats.read();

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                                SystemClock.uptimeMillis());
            Slog.i(TAG, "Time to scan packages: "
                   + ((SystemClock.uptimeMillis()-startTime)/1000f)
                   + " seconds");

            // If the platform SDK has changed since the last time we booted,
            // we need to re-grant app permission to catch any new ones that
            // appear.  This is really a hack, and means that apps can in some
            // cases get permissions that the user didn't initially explicitly
            // allow...  it would be nice to have some better way to handle
            // this situation.
            // SDK 有改变时,需处理新出现的权限
            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
            if (sdkUpdated) {
                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                       + mSdkVersion + "; regranting permissions for internal storage");
            }
            mPermissionManager.updateAllPermissions(
                                                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
                                                    mPermissionCallback);
            ver.sdkVersion = mSdkVersion;

            // If this is the first boot or an update from pre-M, and it is a normal
            // boot, then we need to initialize the default preferred apps across
            // all defined users.
            // 如果这是第一次启动或来自  pre-M 的更新,并且它是正常启动,
            //那么我们需要在所有已定义的用户中初始化默认的首选应用程序。
            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : sUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
                    applyFactoryDefaultBrowserLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }

            // Prepare storage for system user really early during boot,
            // since core system apps like SettingsProvider and SystemUI
            // can't wait for user to start
            // 为先于用户启动的系统应用准备存储
            final int storageFlags;
            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
                storageFlags = StorageManager.FLAG_STORAGE_DE;
            } else {
                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            }
            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
                                                             UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
                                                             true /* onlyCoreApps */);
            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
                    TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
                                                                   Trace.TRACE_TAG_PACKAGE_MANAGER);
                    traceLog.traceBegin("AppDataFixup");
                    try {
                        mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
                                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                    } catch (InstallerException e) {
                        Slog.w(TAG, "Trouble fixing GIDs", e);
                    }
                    traceLog.traceEnd();

                    traceLog.traceBegin("AppDataPrepare");
                    if (deferPackages == null || deferPackages.isEmpty()) {
                        return;
                    }
                    int count = 0;
                    for (String pkgName : deferPackages) {
                        PackageParser.Package pkg = null;
                        synchronized (mPackages) {
                            PackageSetting ps = mSettings.getPackageLPr(pkgName);
                            if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
                                pkg = ps.pkg;
                            }
                        }
                        if (pkg != null) {
                            synchronized (mInstallLock) {
                                prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
                                                            true /* maybeMigrateAppData */);
                            }
                            count++;
                        }
                    }
                    traceLog.traceEnd();
                    Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
                }, "prepareAppData");

            // If this is first boot after an OTA, and a normal boot, then
            // we need to clear code cache directories.
            // Note that we do *not* clear the application profiles. These remain valid
            // across OTAs and are used to drive profile verification (post OTA) and
            // profile compilation (without waiting to collect a fresh set of profiles).
            // OTA 清除缓存不是应用数据,所以  OTA 后开机会很慢,因为要重新生成缓存
            if (mIsUpgrade && !onlyCore) {
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                for (int i = 0; i < mSettings.mPackages.size(); i++) {
                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                        // No apps are running this early, so no need to freeze
                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }
            // 检查默认浏览器,没有则设置
            checkDefaultBrowser();

            // clear only after permissions and other defaults have been updated
            mExistingSystemPackages.clear();
            mPromoteSystemApps = false;

            // All the changes are done during package scanning.
            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

            // can downgrade to reader
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
            // 保存配置,将信息写到  package.xml、package.lsit 及  pacakge-stopped.xml 文件中
            mSettings.writeLPr();
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                                SystemClock.uptimeMillis());
            // 获取一下变量
            if (!mOnlyCore) {
                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
                mRequiredInstallerPackage = getRequiredInstallerLPr();
                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
                if (mIntentFilterVerifierComponent != null) {
                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                                                                    mIntentFilterVerifierComponent);
                } else {
                    mIntentFilterVerifier = null;
                }
                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                                                                                      PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
                                                                                      SharedLibraryInfo.VERSION_UNDEFINED);
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                                                                                    PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                                                                                    SharedLibraryInfo.VERSION_UNDEFINED);
            } else {
                mRequiredVerifierPackage = null;
                mRequiredInstallerPackage = null;
                mRequiredUninstallerPackage = null;
                mIntentFilterVerifierComponent = null;
                mIntentFilterVerifier = null;
                mServicesSystemSharedLibraryPackageName = null;
                mSharedSystemSharedLibraryPackageName = null;
            }

            mInstallerService = new PackageInstallerService(context, this);
            final Pair<ComponentName, String> instantAppResolverComponent =
                getInstantAppResolverLPr();
            if (instantAppResolverComponent != null) {
                if (DEBUG_INSTANT) {
                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
                }
                mInstantAppResolverConnection = new InstantAppResolverConnection(
                                                                                 mContext, instantAppResolverComponent.first,
                                                                                 instantAppResolverComponent.second);
                mInstantAppResolverSettingsComponent =
                    getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
            } else {
                mInstantAppResolverConnection = null;
                mInstantAppResolverSettingsComponent = null;
            }
            updateInstantAppInstallerLocked(null);

            // Read and update the usage of dex files.
            // Do this at the end of PM init so that all the packages have their
            // data directory reconciled.
            // At this point we know the code paths of the packages, so we can validate
            // the disk file and build the internal cache.
            // The usage file is expected to be small so loading and verifying it
            // should take a fairly small time compare to the other activities (e.g. package
            // scanning).
            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
            for (int userId : currentUserIds) {
                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
            }
            // 执行  dexopt 操作生成 .odex 后缀文件
            mDexManager.load(userPackages);
            if (mIsUpgrade) {
                MetricsLogger.histogram(null, "ota_package_manager_init_time",
                                        (int) (SystemClock.uptimeMillis() - startTime));
            }
        } // synchronized (mPackages)
    } // synchronized (mInstallLock)

    // Now after opening every single application zip, make sure they
    // are all flushed.  Not really needed, but keeps things nice and
    // tidy.
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
    // 清理及资源回收
    Runtime.getRuntime().gc();
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

    // The initial scanning above does many calls into installd while
    // holding the mPackages lock, but we're mostly interested in yelling
    // once we have a booted system.
    mInstaller.setWarnIfHeld(mPackages);

    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
  • Settings.class 建立 Android 体系与 Linux 内核的用户权限对应关系

    • Settings()

       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
      
      Settings(PermissionSettings permissions, Object lock) {
          this(Environment.getDataDirectory(), permissions, lock);
      }
      
      Settings(File dataDir, PermissionSettings permission, Object lock) {
          mLock = lock;
          mPermissions = permission;
          mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
          // /data/system 目录
          mSystemDir = new File(dataDir, "system");
          mSystemDir.mkdirs();
          FileUtils.setPermissions(mSystemDir.toString(),
                                   FileUtils.S_IRWXU|FileUtils.S_IRWXG
                                   |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                                   -1, -1);
          // 记录应用相关信息:permission、package、shared-user、keyset-settings
          mSettingsFilename = new File(mSystemDir, "packages.xml");
          // package-backup.xml 是  package.xml 的备份文件,
          // package.xml 写入成功后再写入到备份文件,写入失败时可恢复到上次状态
          mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
          // 记录安装包相关信息:包名、userid、debugable、应用数据存放路径、seinfo、gid
          mPackageListFilename = new File(mSystemDir, "packages.list");
          FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
          // sdcardfs 的作用与  fuse 相同,也是用于控制文件访问的权限。
          final File kernelDir = new File("/config/sdcardfs");
          mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
      
          // Deprecated: Needed for migration
          // 强制停止运行的应用信息
          mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
          mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
      }
    • addSharedUserLPw()

       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
      
      SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
          SharedUserSetting s = mSharedUsers.get(name);
          if (s != null) {
              if (s.userId == uid) {
                  // 相应的  SharedUserSetting 存在并且  userId 相同直接返回该对象
                  return s;
              }
              // userId 不同则抱一个错误
              PackageManagerService.reportSettingsProblem(Log.ERROR,
                                                          "Adding duplicate shared user, keeping first: " + name);
              return null;
          }
          // 不存在新建存入到  mShsredUsers 并返回新建的对象
          s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
          s.userId = uid;
          if (addUserIdLPw(uid, s, name)) {
              mSharedUsers.put(name, s);
              return s;
          }
          return null;
      }
      
      private boolean addUserIdLPw(int uid, Object obj, Object name) {
          if (uid > Process.LAST_APPLICATION_UID) {
              // userId 没有对应的应用,不合法
              return false;
          }
      
          if (uid >= Process.FIRST_APPLICATION_UID) {
              // 非系统应用
              // 存入到  mUserIds 中  userId 对应的下标位置;中间空白部分用  null 填充
              int N = mUserIds.size();
              final int index = uid - Process.FIRST_APPLICATION_UID;
              while (index >= N) {
                  mUserIds.add(null);
                  N++;
              }
              if (mUserIds.get(index) != null) {
                  PackageManagerService.reportSettingsProblem(Log.ERROR,
                                                              "Adding duplicate user id: " + uid
                                                              + " name=" + name);
                  return false;
              }
              mUserIds.set(index, obj);
          } else {
              // 系统内置的  userId
              if (mOtherUserIds.get(uid) != null) {
                  PackageManagerService.reportSettingsProblem(Log.ERROR,
                                                              "Adding duplicate shared id: " + uid
                                                              + " name=" + name);
                  return false;
              }
              // 存入到  mOtherUserIds 中
              mOtherUserIds.put(uid, obj);
          }
          return true;
      }

      SettingsmSharedUsers 是一个 map 对象,利用名称作为索引管理 SharedUserSettings 对象。 Settings 中的 mOtherUserIdsmUserIds ,均是利用 userId 作为索引管理 SharedUserSettings 对象。不同的是 mOtherUserIdsSparseArray ,以系统 uid 作为键值;=mUserIds= 是 ArrayList ,普通 APK 的 uidArrayList 的下标。 SharedUserSettings 将持有一组 PackageSettingAndroidManifest.xmlandroid:sharedUserId 的属性就是应用的 UserId 其与 Linux 的 UID 相关联,而 Linux 的权限是建立再用户的基础上的,从而建立应用的权限体系。

  • SystemConfig.class 从文件读取系统配置

    • SystemConfig()

       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
      
      // 单例模式
      public static SystemConfig getInstance() {
          synchronized (SystemConfig.class) {
              if (sInstance == null) {
                  sInstance = new SystemConfig();
              }
              return sInstance;
          }
      }
      
      SystemConfig() {
          // Read configuration from system
          // 从 /system 目录读取权限配置信息
          readPermissions(Environment.buildPath(
                                                Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
      
          // Read configuration from the old permissions dir
          // 旧配置文件
          readPermissions(Environment.buildPath(
                                                Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
      
          // Vendors are only allowed to customze libs, features and privapp permissions
          // 从 /vendor 目录读取权限配置信息,该目录下只能自定义:libs、features、privapp 权限
          int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS;
          if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
              // For backward compatibility
              vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
          }
          readPermissions(Environment.buildPath(
                                                Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
          readPermissions(Environment.buildPath(
                                                Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);
      
          // Allow ODM to customize system configs as much as Vendor, because /odm is another
          // vendor partition other than /vendor.
          // 从 /odm 目录读取权限配置信息,限制和 /vendor 一样
          int odmPermissionFlag = vendorPermissionFlag;
          readPermissions(Environment.buildPath(
                                                Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
          readPermissions(Environment.buildPath(
                                                Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
      
          // Allow OEM to customize features and OEM permissions
          // 从  /oem 目录读取权限配置信息,只能自定义:features 和  OEM 权限
          int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS;
          readPermissions(Environment.buildPath(
                                                Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
          readPermissions(Environment.buildPath(
                                                Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);
      
          // Allow Product to customize system configs around libs, features, permissions and apps
          // 从产品目录读取配置信息,可以自定义:system configs、libs、features、permissions、apps
          int productPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
              ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
          readPermissions(Environment.buildPath(
                                                Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
          readPermissions(Environment.buildPath(
                                                Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);
      }
    • readPermissions()

       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
      
      void readPermissions(File libraryDir, int permissionFlag) {
          // Read permissions from given directory.
          if (!libraryDir.exists() || !libraryDir.isDirectory()) {
              if (permissionFlag == ALLOW_ALL) {
                  Slog.w(TAG, "No directory " + libraryDir + ", skipping");
              }
              return;
          }
          if (!libraryDir.canRead()) {
              Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
              return;
          }
      
          // Iterate over the files in the directory and scan .xml files
          File platformFile = null;
          for (File f : libraryDir.listFiles()) {
              // We'll read platform.xml last
              if (f.getPath().endsWith("etc/permissions/platform.xml")) {
                  platformFile = f;
                  continue;
              }
      
              if (!f.getPath().endsWith(".xml")) {
                  Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
                  continue;
              }
              if (!f.canRead()) {
                  Slog.w(TAG, "Permissions library file " + f + " cannot be read");
                  continue;
              }
      
              readPermissionsFromXml(f, permissionFlag);
          }
      
          // Read platform permissions last so it will take precedence
          if (platformFile != null) {
              // 解析  XML 文件并保存解析后的结果
              readPermissionsFromXml(platformFile, permissionFlag);
          }
      }
  • scanDirTracedLI() 扫描已安装应用信息并保存

     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
    
    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
        try {
            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }
    
    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
        final File[] files = scanDir.listFiles();
        if (ArrayUtils.isEmpty(files)) {
            Log.d(TAG, "No files in app dir " + scanDir);
            return;
        }
    
        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
                                                                                     mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
                                                                                     mParallelPackageParserCallback)) {
            // Submit files for parsing in parallel
            int fileCount = 0;
            for (File file : files) {
                // 过滤  apk、文件夹并排除临时文件
                final boolean isPackage = (isApkFile(file) || file.isDirectory())
                    && !PackageInstallerService.isStageName(file.getName());
                if (!isPackage) {
                    // Ignore entries which are not packages
                    continue;
                }
                // 提交符合条件的文件,用于并行解析
                parallelPackageParser.submit(file, parseFlags);
                // 计数用于后面处理解析结果
                fileCount++;
            }
    
            // Process results one by one
            // 逐个处理解析结果
            for (; fileCount > 0; fileCount--) {
                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
                Throwable throwable = parseResult.throwable;
                int errorCode = PackageManager.INSTALL_SUCCEEDED;
    
                if (throwable == null) {
                    // TODO(toddke): move lower in the scan chain
                    // Static shared libraries have synthetic package names
                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
                        // 重命名静态共享库包:pkg.packageName + "_"  + pkg.staticSharedLibVersion
                        renameStaticSharedLibraryPackage(parseResult.pkg);
                    }
                    try {
                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
                            // 继续解析其它信息
                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
                                               currentTime, null);
                        }
                    } catch (PackageManagerException e) {
                        errorCode = e.error;
                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
                    }
                } else if (throwable instanceof PackageParser.PackageParserException) {
                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
                        throwable;
                    errorCode = e.error;
                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
                } else {
                    throw new IllegalStateException("Unexpected exception occurred while parsing "
                                                    + parseResult.scanFile, throwable);
                }
    
                // Delete invalid userdata apps
                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
                    errorCode != PackageManager.INSTALL_SUCCEEDED) {
                    logCriticalInfo(Log.WARN,
                                    "Deleting invalid package at " + parseResult.scanFile);
                    // 移除无用的用户安装包
                    removeCodePathLI(parseResult.scanFile);
                }
            }
        }
    }
    • ParallelPackageParser.class 这是一个辅助类用于并行解析安装包

      ```java static class ParseResult {

      1
      2
      3
      
      PackageParser.Package pkg; // Parsed package
      File scanFile; // File that was parsed
      Throwable throwable; // Set if an error occurs during parsing

      }

      /**

      • Take the parsed package from the parsing queue, waiting if necessary until the element
      • appears in the queue.
      • @return parsed package */ // 取出解析结果 public ParseResult take() { try { if (mInterruptedInThread != null) { throw new InterruptedException(“Interrupted in ” + mInterruptedInThread); } return mQueue.take(); } catch (InterruptedException e) { // We cannot recover from interrupt here Thread.currentThread().interrupt(); throw new IllegalStateException(e); } }

      /** * Submits the file for parsing * @param scanFile file to scan * @param parseFlags parse falgs */ 提交到线程池 public void submit(File scanFile, int parseFlags) { mService.submit(() -> { ParseResult pr = new ParseResult(); Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, “parallel parsePackage [” + scanFile + “]”); try { PackageParser pp = new PackageParser(); // debug.separate_processes 值 pp.setSeparateProcesses(mSeparateProcesses); pp.setOnlyCoreApps(mOnlyCore); pp.setDisplayMetrics(mMetrics); pp.setCacheDir(mCacheDir); pp.setCallback(mPackageParserCallback); pr.scanFile = scanFile; // 保存解析信息 pr.pkg = parsePackage(pp, scanFile, parseFlags); } catch (Throwable e) { pr.throwable = e; } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } try { // 保存解析结果 mQueue.put(pr); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // Propagate result to callers of take(). // This is helpful to prevent main thread from getting stuck waiting on // ParallelPackageParser to finish in case of interruption mInterruptedInThread = Thread.currentThread().getName(); } }); }

      @VisibleForTesting protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile, int parseFlags) throws PackageParser.PackageParserException { // 交由 PackageParser 类进行解析 return packageParser.parsePackage(scanFile, parseFlags, true /* useCaches */); } ```

    • PackageParser.class 安装包解析类

      • parsePackage()

         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
        
        public Package parsePackage(File packageFile, int flags) throws PackageParserException {
            return parsePackage(packageFile, flags, false /* useCaches */);
        }
        
        public Package parsePackage(File packageFile, int flags, boolean useCaches)
            throws PackageParserException {
            // 这次是  true,如果从缓存中找到直接返回该对象
            Package parsed = useCaches ? getCachedResult(packageFile, flags) : null;
            if (parsed != null) {
                return parsed;
            }
        
            long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
            // 目录和单个文件调用的方法不同,但大同小异;
            // Android 目前默认都是文件夹;那我这里也就只分析解析文件夹的方法
            if (packageFile.isDirectory()) {
                parsed = parseClusterPackage(packageFile, flags);
            } else {
                parsed = parseMonolithicPackage(packageFile, flags);
            }
        
            long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
            // 缓存解析结果
            cacheResult(packageFile, flags, parsed);
            if (LOG_PARSE_TIMINGS) {
                parseTime = cacheTime - parseTime;
                cacheTime = SystemClock.uptimeMillis() - cacheTime;
                if (parseTime + cacheTime > LOG_PARSE_TIMINGS_THRESHOLD_MS) {
                    Slog.i(TAG, "Parse times for '" + packageFile + "': parse=" + parseTime
                           + "ms, update_cache=" + cacheTime + " ms");
                }
            }
            return parsed;
        }
      • parseClusterPackage() 解析文件夹

        ```java /**

        • Parse all APKs contained in the given directory, treating them as a
        • single package. This also performs sanity checking, such as requiring
        • identical package name and version codes, a single base APK, and unique
        • split names.
        • Note that this does not perform signature verification; that
        • must be done separately in {@link #collectCertificates(Package, int)}. */ private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException { // 解析出所有 apk 信息 <3> final PackageLite lite = parseClusterPackageLite(packageDir, 0); if (mOnlyCoreApps && !lite.coreApp) { throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, “Not a coreApp: “ + packageDir); }

          // Build the split dependency tree. // 构建子包依赖树 SparseArray splitDependencies = null; final SplitAssetLoader assetLoader; if (lite.isolatedSplits && !ArrayUtils.isEmpty(lite.splitNames)) { try { splitDependencies = SplitAssetDependencyLoader.createDependenciesFromPackage(lite); assetLoader = new SplitAssetDependencyLoader(lite, splitDependencies, flags); } catch (SplitAssetDependencyLoader.IllegalDependencyException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST, e.getMessage()); } } else { assetLoader = new DefaultSplitAssetLoader(lite, flags); }

          try { // 解析母 apk <5> final AssetManager assets = assetLoader.getBaseAssetManager(); final File baseApk = new File(lite.baseCodePath); final Package pkg = parseBaseApk(baseApk, assets, flags); if (pkg == null) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, “Failed to parse base APK: “ + baseApk); }

           1
           2
           3
           4
           5
           6
           7
           8
           9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          
          if (!ArrayUtils.isEmpty(lite.splitNames)) {
              final int num = lite.splitNames.length;
              pkg.splitNames = lite.splitNames;
              pkg.splitCodePaths = lite.splitCodePaths;
              pkg.splitRevisionCodes = lite.splitRevisionCodes;
              pkg.splitFlags = new int[num];
              pkg.splitPrivateFlags = new int[num];
              pkg.applicationInfo.splitNames = pkg.splitNames;
              pkg.applicationInfo.splitDependencies = splitDependencies;
              pkg.applicationInfo.splitClassLoaderNames = new String[num];
          
              for (int i = 0; i < num; i++) {
                  // 解析子  apk,过程类似母  apk
                  final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
                  parseSplitApk(pkg, i, splitAssets, flags);
              }
          }
          
          pkg.setCodePath(packageDir.getCanonicalPath());
          pkg.setUse32bitAbi(lite.use32bitAbi);
          return pkg;

          } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, “Failed to get path: “ + lite.baseCodePath, e); } finally { IoUtils.closeQuietly(assetLoader); } } ```

      • parseClusterPackageLite()

          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
        
        // PackageLite 的构造方法,主要是保存应用的信息
        public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
                           boolean[] isFeatureSplits, String[] usesSplitNames, String[] configForSplit,
                           String[] splitCodePaths, int[] splitRevisionCodes) {
            this.packageName = baseApk.packageName;
            this.versionCode = baseApk.versionCode;
            this.versionCodeMajor = baseApk.versionCodeMajor;
            this.installLocation = baseApk.installLocation;
            this.verifiers = baseApk.verifiers;
            this.splitNames = splitNames;
            this.isFeatureSplits = isFeatureSplits;
            this.usesSplitNames = usesSplitNames;
            this.configForSplit = configForSplit;
            this.codePath = codePath;
            this.baseCodePath = baseApk.codePath;
            this.splitCodePaths = splitCodePaths;
            this.baseRevisionCode = baseApk.revisionCode;
            this.splitRevisionCodes = splitRevisionCodes;
            this.coreApp = baseApk.coreApp;
            this.debuggable = baseApk.debuggable;
            this.multiArch = baseApk.multiArch;
            this.use32bitAbi = baseApk.use32bitAbi;
            this.extractNativeLibs = baseApk.extractNativeLibs;
            this.isolatedSplits = baseApk.isolatedSplits;
        }
        
        static PackageLite parseClusterPackageLite(File packageDir, int flags)
            throws PackageParserException {
            final File[] files = packageDir.listFiles();
            if (ArrayUtils.isEmpty(files)) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
                                                 "No packages found in split");
            }
        
            String packageName = null;
            int versionCode = 0;
        
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
            final ArrayMap<String, ApkLite> apks = new ArrayMap<>();
            for (File file : files) {
                if (isApkFile(file)) {
                    // 解析单个  APK 文件
                    final ApkLite lite = parseApkLite(file, flags);
        
                    // Assert that all package names and version codes are
                    // consistent with the first one we encounter.
                    if (packageName == null) {
                        packageName = lite.packageName;
                        versionCode = lite.versionCode;
                    } else {
                        // 检查包名是否一致
                        if (!packageName.equals(lite.packageName)) {
                            throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                                             "Inconsistent package " + lite.packageName + " in " + file
                                                             + "; expected " + packageName);
                        }
                        // 检查版本号是否一致
                        if (versionCode != lite.versionCode) {
                            throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                                             "Inconsistent version " + lite.versionCode + " in " + file
                                                             + "; expected " + versionCode);
                        }
                    }
                    // 检查子包的唯一性
                    // Assert that each split is defined only once
                    if (apks.put(lite.splitName, lite) != null) {
                        throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                                         "Split name " + lite.splitName
                                                         + " defined more than once; most recent was " + file);
                    }
                }
            }
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            // 因为  baseApk.splitName=null,所以移除  null 返回  baseApk
            final ApkLite baseApk = apks.remove(null);
            if (baseApk == null) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                                 "Missing base APK in " + packageDir);
            }
        
            // Always apply deterministic ordering based on splitName
            final int size = apks.size();
        
            String[] splitNames = null;
            boolean[] isFeatureSplits = null;
            String[] usesSplitNames = null;
            String[] configForSplits = null;
            String[] splitCodePaths = null;
            int[] splitRevisionCodes = null;
            String[] splitClassLoaderNames = null;
            if (size > 0) {
                splitNames = new String[size];
                isFeatureSplits = new boolean[size];
                usesSplitNames = new String[size];
                configForSplits = new String[size];
                splitCodePaths = new String[size];
                splitRevisionCodes = new int[size];
                // 子包排序储存
                splitNames = apks.keySet().toArray(splitNames);
                Arrays.sort(splitNames, sSplitNameComparator);
        
                for (int i = 0; i < size; i++) {
                    final ApkLite apk = apks.get(splitNames[i]);
                    usesSplitNames[i] = apk.usesSplitName;
                    isFeatureSplits[i] = apk.isFeatureSplit;
                    configForSplits[i] = apk.configForSplit;
                    splitCodePaths[i] = apk.codePath;
                    splitRevisionCodes[i] = apk.revisionCode;
                }
            }
        
            final String codePath = packageDir.getAbsolutePath();
            // 构建  PackageLite 对象并返回
            return new PackageLite(codePath, baseApk, splitNames, isFeatureSplits, usesSplitNames,
                                   configForSplits, splitCodePaths, splitRevisionCodes);
        }
      • parseApkLite()

        ```java /**

        • Utility method that retrieves lightweight details about a single APK
        • file, including package name, split name, and install location. *
        • @param apkFile path to a single APK
        • @param flags optional parse flags, such as
        • {@link #PARSE_COLLECT_CERTIFICATES} */ public static ApkLite parseApkLite(File apkFile, int flags) throws PackageParserException { return parseApkLiteInner(apkFile, null, null, flags); }

        private static ApkLite parseApkLiteInner(File apkFile, FileDescriptor fd, String debugPathName, int flags) throws PackageParserException { // 这里 fd、debugPathName 都是 null // 这个获得 apk 绝对路径 final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath();

         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
        
        XmlResourceParser parser = null;
        try {
            final ApkAssets apkAssets;
            try {
                // 从  apk 中加载  AndroidManifest.xml 文件
                apkAssets = fd != null
                    ? ApkAssets.loadFromFd(fd, debugPathName, false, false)
                    : ApkAssets.loadFromPath(apkPath);
            } catch (IOException e) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
                                                 "Failed to parse " + apkPath);
            }
            // 准备解析  AndroidManifest.xml 文件
            parser = apkAssets.openXml(ANDROID_MANIFEST_FILENAME);
        
            final SigningDetails signingDetails;
            if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
                // TODO: factor signature related items out of Package object
                final Package tempPkg = new Package((String) null);
                // 系统签名  apk 跳过签名相关
                final boolean skipVerify = (flags & PARSE_IS_SYSTEM_DIR) != 0;
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
                try {
                    // 获取签名信息
                    collectCertificates(tempPkg, apkFile, skipVerify);
                } finally {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
                signingDetails = tempPkg.mSigningDetails;
            } else {
                signingDetails = SigningDetails.UNKNOWN;
            }
        
            //XmlResourceParser 是  AttributeSet 的子类
            final AttributeSet attrs = parser;
            return parseApkLite(apkPath, parser, attrs, signingDetails);
        
        } catch (XmlPullParserException | IOException | RuntimeException e) {
            Slog.w(TAG, "Failed to parse " + apkPath, e);
            throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                                             "Failed to parse " + apkPath, e);
        } finally {
            IoUtils.closeQuietly(parser);
            // TODO(b/72056911): Implement and call close() on ApkAssets.
        }

        } // 主要解析 AndroidManifest.xml 文件,并将结果保存到 ApkLite 对象中 private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs, SigningDetails signingDetails) throws IOException, XmlPullParserException, PackageParserException { final Pair packageSplit = parsePackageSplitNames(parser, attrs);

         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        
        int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
        int versionCode = 0;
        int versionCodeMajor = 0;
        int revisionCode = 0;
        boolean coreApp = false;
        boolean debuggable = false;
        boolean multiArch = false;
        boolean use32bitAbi = false;
        boolean extractNativeLibs = true;
        boolean isolatedSplits = false;
        boolean isFeatureSplit = false;
        String configForSplit = null;
        String usesSplitName = null;
        
        // 从  AndroidManifest.xml 中解析上述变量的值
        // ......
        // 构建  ApkLite 对象并返回
        return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
                           configForSplit, usesSplitName, versionCode, versionCodeMajor, revisionCode,
                           installLocation, verifiers, signingDetails, coreApp, debuggable,
                           multiArch, use32bitAbi, extractNativeLibs, isolatedSplits);

        } ```

      • parseBaseApk()

          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
        
        private Package parseBaseApk(File apkFile, AssetManager assets, int flags)
            throws PackageParserException {
            final String apkPath = apkFile.getAbsolutePath();
        
            String volumeUuid = null;
            if (apkPath.startsWith(MNT_EXPAND)) {
                final int end = apkPath.indexOf('/', MNT_EXPAND.length());
                volumeUuid = apkPath.substring(MNT_EXPAND.length(), end);
            }
        
            mParseError = PackageManager.INSTALL_SUCCEEDED;
            mArchiveSourcePath = apkFile.getAbsolutePath();
        
            if (DEBUG_JAR) Slog.d(TAG, "Scanning base APK: " + apkPath);
        
            XmlResourceParser parser = null;
            try {
                // 根据  apk 路径获取资源管理器中的  AndroidManifest.xml
                final int cookie = assets.findCookieForPath(apkPath);
                if (cookie == 0) {
                    throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                                     "Failed adding asset path: " + apkPath);
                }
                parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
                final Resources res = new Resources(assets, mMetrics, null);
        
                final String[] outError = new String[1];
                final Package pkg = parseBaseApk(apkPath, res, parser, flags, outError);
                if (pkg == null) {
                    throw new PackageParserException(mParseError,
                                                     apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
                }
        
                pkg.setVolumeUuid(volumeUuid);
                pkg.setApplicationVolumeUuid(volumeUuid);
                pkg.setBaseCodePath(apkPath);
                pkg.setSigningDetails(SigningDetails.UNKNOWN);
        
                return pkg;
        
            } catch (PackageParserException e) {
                throw e;
            } catch (Exception e) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                                                 "Failed to read manifest from " + apkPath, e);
            } finally {
                IoUtils.closeQuietly(parser);
            }
        }
        
        private boolean parseBaseApkChild(Package parentPkg, Resources res, XmlResourceParser parser,
                                          int flags, String[] outError) throws XmlPullParserException, IOException {
            // Make sure we have a valid child package name
            // 包名
            String childPackageName = parser.getAttributeValue(null, "package");
            if (validateName(childPackageName, true, false) != null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
                return false;
            }
        
            // Child packages must be unique
            // 包名唯一
            if (childPackageName.equals(parentPkg.packageName)) {
                String message = "Child package name cannot be equal to parent package name: "
                    + parentPkg.packageName;
                Slog.w(TAG, message);
                outError[0] = message;
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }
        
            // Child packages must be unique
            if (parentPkg.hasChildPackage(childPackageName)) {
                String message = "Duplicate child package:" + childPackageName;
                Slog.w(TAG, message);
                outError[0] = message;
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }
        
            // Go ahead and parse the child
            Package childPkg = new Package(childPackageName);
        
            // Child package inherits parent version code/name/target SDK
            // 解析出:版本号、名称、SDK 版本等信息
            childPkg.mVersionCode = parentPkg.mVersionCode;
            childPkg.baseRevisionCode = parentPkg.baseRevisionCode;
            childPkg.mVersionName = parentPkg.mVersionName;
            childPkg.applicationInfo.targetSdkVersion = parentPkg.applicationInfo.targetSdkVersion;
            childPkg.applicationInfo.minSdkVersion = parentPkg.applicationInfo.minSdkVersion;
        
            childPkg = parseBaseApkCommon(childPkg, CHILD_PACKAGE_TAGS, res, parser, flags, outError);
            if (childPkg == null) {
                // If we got null then error was set during child parsing
                return false;
            }
        
            // Set the parent-child relation
            if (parentPkg.childPackages == null) {
                parentPkg.childPackages = new ArrayList<>();
            }
            parentPkg.childPackages.add(childPkg);
            childPkg.parentPackage = parentPkg;
        
            return true;
        }
    • scanPackageChildLI()

       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
      
      private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
                                                       final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
                                                       @Nullable UserHandle user)
          throws PackageManagerException {
          // If the package has children and this is the first dive in the function
          // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
          // packages (parent and children) would be successfully scanned before the
          // actual scan since scanning mutates internal state and we want to atomically
          // install the package and its children.
          // 如果有子包,第一次只确保扫描到所有子包但不解析,因为解析会改变包的状态
          if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
              if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
                  scanFlags |= SCAN_CHECK_ONLY;
              }
          } else {
              scanFlags &= ~SCAN_CHECK_ONLY;
          }
      
          // Scan the parent
          PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
                                                          scanFlags, currentTime, user);
      
          // Scan the children
          final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
          for (int i = 0; i < childCount; i++) {
              PackageParser.Package childPackage = pkg.childPackages.get(i);
              addForInitLI(childPackage, parseFlags, scanFlags,
                           currentTime, user);
          }
      
      
          if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
              // 第二次进入改方法,解析所有包
              return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
          }
      
          return scannedPkg;
      }
      • addForInitLI()

        这个方法比较长,主要作用是把扫描到的应用包信息存储到 PackageManagerService ,由于以后查询, Intent 行为主要依赖次信息库;在此过程中也会附加检查,如果包与先前已知的包相同,则发生基本验证[例如确保匹配签名,检查版本代码等]。 如果程序包未通过签名检查,则将删除 /data 上安装的版本。 如果新软件包的版本小于或等于 /data 上的版本,则将忽略它。

          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
        162
        163
        164
        165
        166
        167
        168
        169
        170
        171
        172
        173
        174
        175
        176
        177
        178
        179
        180
        181
        182
        183
        184
        185
        186
        187
        188
        189
        190
        191
        192
        193
        194
        195
        196
        197
        198
        199
        200
        201
        202
        203
        
        private PackageParser.Package addForInitLI(PackageParser.Package pkg,
                                                   @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
                                                   @Nullable UserHandle user)
            throws PackageManagerException {
            // 系统内置的即非  data 分区
            final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
            final String renamedPkgName;
            final PackageSetting disabledPkgSetting;
            final boolean isSystemPkgUpdated;
            final boolean pkgAlreadyExists;
            PackageSetting pkgSetting;
        
            // NOTE: installPackageLI() has the same code to setup the package's
            // application info. This probably should be done lower in the call
            // stack [such as scanPackageOnly()]. However, we verify the application
            // info prior to that [in scanPackageNew()] and thus have to setup
            // the application info early.
            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
            pkg.setApplicationInfoCodePath(pkg.codePath);
            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
            pkg.setApplicationInfoResourcePath(pkg.codePath);
            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
        
            synchronized (mPackages) {
                // 获取自首次安装以来已重命名的软件包的原始包名。 键是包的新名称,值是原始名称。
                renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
                final String realPkgName = getRealPackageName(pkg, renamedPkgName);
                if (realPkgName != null) {
                    // 更改为原始包名
                    ensurePackageRenamed(pkg, renamedPkgName);
                }
                //获取原始包配置,原始包必须以相同的方式签名,且必须具有相同的名称和共享用户[如果有]。
                final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
                // 获取当前包配置
                final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
                pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
                // 判断当前应用包是否已经存在
                pkgAlreadyExists = pkgSetting != null;
                final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
                // 获取被当前应用包替换的系统应用包配置
                disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
                // 是否是系统应用的升级包
                isSystemPkgUpdated = disabledPkgSetting != null;
        
                final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
                                                 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
                    : null;
        
                if (scanSystemPartition) {
                    // Potentially prune child packages. If the application on the /system
                    // partition has been updated via OTA, but, is still disabled by a
                    // version on /data, cycle through all of its children packages and
                    // remove children that are no longer defined.
                    // 如果 /system 分区上的应用程序已通过  OTA 更新,但仍然被 /data 上的版本禁用,则循环遍历其所有子程序包并删除不再定义的子项。
                    if (isSystemPkgUpdated) {
                        final int scannedChildCount = (pkg.childPackages != null)
                            ? pkg.childPackages.size() : 0;
                        final int disabledChildCount = disabledPkgSetting.childPackageNames != null
                            ? disabledPkgSetting.childPackageNames.size() : 0;
                        for (int i = 0; i < disabledChildCount; i++) {
                            String disabledChildPackageName =
                                disabledPkgSetting.childPackageNames.get(i);
                            boolean disabledPackageAvailable = false;
                            for (int j = 0; j < scannedChildCount; j++) {
                                PackageParser.Package childPkg = pkg.childPackages.get(j);
                                if (childPkg.packageName.equals(disabledChildPackageName)) {
                                    disabledPackageAvailable = true;
                                    break;
                                }
                            }
                            if (!disabledPackageAvailable) {
                                mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
                            }
                        }
                        // we're updating the disabled package, so, scan it as the package setting
                        final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
                                                                    disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
                                                                    null /* originalPkgSetting */, null, parseFlags, scanFlags,
                                                                    (pkg == mPlatformPackage), user);
                        applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
                        scanPackageOnlyLI(request, mFactoryTest, -1L);
                    }
                }
            }
            // 新包安装路径是否改变
            final boolean newPkgChangedPaths =
                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
            // 新包版本是否升级
            final boolean newPkgVersionGreater =
                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
            // 系统包是否有升级
            final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
                && newPkgChangedPaths && newPkgVersionGreater;
            if (isSystemPkgBetter) {
                // The version of the application on /system is greater than the version on
                // /data. Switch back to the application on /system.
                // It's safe to assume the application on /system will correctly scan. If not,
                // there won't be a working copy of the application.
                // /system 上的应用程序版本大于 /data 上的版本。 切换回 /system 上的应用程序。
                synchronized (mPackages) {
                    // just remove the loaded entries from package lists
                    mPackages.remove(pkgSetting.name);
                }
        
                final InstallArgs args = createInstallArgsForExisting(
                                                                      packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
                                                                      pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
                // 清理资源文件
                args.cleanUpResourcesLI();
                synchronized (mPackages) {
                    // 重新启用系统分区上的应用包
                    mSettings.enableSystemPackageLPw(pkgSetting.name);
                }
            }
        
            if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
                // The version of the application on the /system partition is less than or
                // equal to the version on the /data partition. Even though the disabled system package
                // is likely to be replaced by a version on the /data partition, we make assumptions
                // that it's part of the mPackages collection during package manager initialization. So,
                // add it to mPackages if there isn't already a package in the collection and then throw
                // an exception to use the application already installed on the /data partition.
                // /system 分区上的应用程序版本小于或等于 /data 分区上的版本。仍然使用 /data 分区上的版本,但仍将改包加入到应用管理器
                synchronized (mPackages) {
                    if (!mPackages.containsKey(pkg.packageName)) {
                        mPackages.put(pkg.packageName, pkg);
                    }
                }
            }
        
            // Verify certificates against what was last scanned. If it is an updated priv app, we will
            // force re-collecting certificate.
            // 根据上次扫描的内容验证证书。 如果它是更新  priv-app 下的应用程序,我们将强制重新收集证书。
            final boolean forceCollect = PackageManagerServiceUtils.isApkVerificationForced(
                                                                                            disabledPkgSetting);
            // Full APK verification can be skipped during certificate collection, only if the file is
            // in verified partition, or can be verified on access (when apk verity is enabled). In both
            // cases, only data in Signing Block is verified instead of the whole file.
            // 只有当文件位于已验证的分区中,或者可以在访问时验证(apk 启用访问验证时),
            //才能在证书收集期间跳过完整的  APK 验证。 在这两种情况下,仅验证签名块中的数据而不是整个文件。
            final boolean skipVerify = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) ||
                (forceCollect && canSkipFullPackageVerification(pkg));
            collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
        
            // Reset profile if the application version is changed
            maybeClearProfilesForUpgradesLI(pkgSetting, pkg);
        
            /*
             * A new system app appeared, but we already had a non-system one of the
             * same name installed earlier.
             */
            // 出现了一个新的系统应用程序,但我们之前已经安装了一个同名的非系统应用程序。
            boolean shouldHideSystemApp = false;
            // A new application appeared on /system, but, we already have a copy of
            // the application installed on /data.
            if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
                && !pkgSetting.isSystem()) {
        
                if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
                                                         PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
                    && !pkgSetting.signatures.mSigningDetails.checkCapability(
                                                                              pkg.mSigningDetails,
                                                                              PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
                    // 签名不匹配,删除改包
                    try (PackageFreezer freezer = freezePackage(pkg.packageName,
                                                                "scanPackageInternalLI")) {
                        deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
                    }
                    pkgSetting = null;
                } else if (newPkgVersionGreater) {
                    // The application on /system is newer than the application on /data.
                    // Simply remove the application on /data [keeping application data]
                    // and replace it with the version on /system.
                    // 系统新包版本更高,移除 /data 上的应用包但保留应用数据
                    InstallArgs args = createInstallArgsForExisting(
                                                                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
                                                                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
                    synchronized (mInstallLock) {
                        args.cleanUpResourcesLI();
                    }
                } else {
                    // The application on /system is older than the application on /data. Hide
                    // the application on /system and the version on /data will be scanned later
                    // and re-added like an update.
                    // /system 上的应用程序比 /data 上的应用程序旧。 隐藏 /system 上的应用程序,稍后将扫描 /data 上的版本,并像更新一样重新添加。
                    shouldHideSystemApp = true;
                }
            }
            // 下一步 <2>
            final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
                                                                      | SCAN_UPDATE_SIGNATURE, currentTime, user);
        
            if (shouldHideSystemApp) {
                synchronized (mPackages) {
                    // 停用需要隐藏的系统包
                    mSettings.disableSystemPackageLPw(pkg.packageName, true);
                }
            }
            return scannedPkg;
        }
      • scanPackageNewLI()

        这个方法主要是有新应用包时(比如 ota 引入)确认是否要替换原应用包

         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
        
        @GuardedBy("mInstallLock")
        private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
                                                       final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
                                                       @Nullable UserHandle user) throws PackageManagerException {
        
            final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
            if (realPkgName != null) {
                ensurePackageRenamed(pkg, renamedPkgName);
            }
            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
            final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
            final PackageSetting disabledPkgSetting =
                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
            // 调整扫描参数
            scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
            synchronized (mPackages) {
                // 根据给定的策略标志将策略应用于已解析的包。
                applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
                // 断言解析的包根据给定的策略有效。 如果包无效,无论出于何种原因,抛出  PackageManagerException。
                assertPackageIsValid(pkg, parseFlags, scanFlags);
        
                SharedUserSetting sharedUserSetting = null;
                if (pkg.mSharedUserId != null) {
                    // SIDE EFFECTS; may potentially allocate a new shared user
                    // 如果不存在则新建
                    sharedUserSetting = mSettings.getSharedUserLPw(
                                                                   pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
                }
        
                boolean scanSucceeded = false;
                try {
                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
                                                                pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
                                                                originalPkgSetting, realPkgName, parseFlags, scanFlags,
                                                                (pkg == mPlatformPackage), user);
                    // 前面主要是解析  AndroidManifest.xm 获取应用的基本信息;同时确定应用使用的版本
                    // 这个方法将解析四大组件相关信息,并储存以供以后查询,比如  Intent 相关 <3>
                    final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
                    if (result.success) {
                        // 提交结果 <4>
                        commitScanResultsLocked(request, result);
                    }
                    scanSucceeded = true;
                } finally {
                    if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
                        // DELETE_DATA_ON_FAILURES is only used by frozen paths
                        // 失败则清理无效数据
                        destroyAppDataLIF(pkg, UserHandle.USER_ALL,
                                          StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                        destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
                    }
                }
            }
            return pkg;
        }
      • scanPackageOnlyLI()

          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
        162
        163
        164
        165
        166
        167
        168
        169
        170
        171
        172
        173
        174
        175
        176
        177
        178
        179
        180
        181
        182
        183
        184
        185
        186
        187
        188
        189
        190
        191
        192
        193
        194
        195
        196
        197
        198
        199
        200
        201
        202
        203
        204
        205
        206
        207
        208
        209
        210
        211
        212
        213
        214
        215
        216
        217
        218
        219
        220
        221
        222
        223
        224
        225
        226
        227
        228
        229
        230
        231
        232
        233
        234
        235
        236
        237
        238
        239
        240
        241
        242
        243
        244
        245
        246
        247
        248
        249
        250
        251
        252
        253
        254
        255
        256
        257
        258
        259
        260
        261
        262
        263
        264
        265
        266
        267
        268
        269
        270
        271
        272
        273
        274
        275
        276
        277
        278
        279
        280
        281
        282
        283
        284
        285
        286
        287
        288
        289
        290
        
        @GuardedBy("mInstallLock")
        private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
                                                             boolean isUnderFactoryTest, long currentTime)
            throws PackageManagerException {
            final PackageParser.Package pkg = request.pkg;
            PackageSetting pkgSetting = request.pkgSetting;
            final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
            final PackageSetting originalPkgSetting = request.originalPkgSetting;
            final @ParseFlags int parseFlags = request.parseFlags;
            final @ScanFlags int scanFlags = request.scanFlags;
            final String realPkgName = request.realPkgName;
            final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
            final UserHandle user = request.user;
            final boolean isPlatformPackage = request.isPlatformPackage;
        
            List<String> changedAbiCodePath = null;
        
            DexManager.maybeLogUnexpectedPackageDetails(pkg);
        
            // Initialize package source and resource directories
            // 初始化资源、源码目录
            final File scanFile = new File(pkg.codePath);
            final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
            final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
        
            // We keep references to the derived CPU Abis from settings in oder to reuse
            // them in the case where we're not upgrading or booting for the first time.
            // 如果不是系统升级或首次开机可以使用以前保存的  CPU Abis 的引用
            String primaryCpuAbiFromSettings = null;
            String secondaryCpuAbiFromSettings = null;
            // 需要生成  abi 引用
            boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
        
            if (!needToDeriveAbi) {
                // 不需要生成  abi 引用时,确保是否有旧的存在,没有则要生成
                if (pkgSetting != null) {
                    primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
                    secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
                } else {
                    // Re-scanning a system package after uninstalling updates; need to derive ABI
                    needToDeriveAbi = true;
                }
            }
            // sharedUser 不一致,需要重新生成  PackageSetting
            if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
                PackageManagerService.reportSettingsProblem(Log.WARN,
                                                            "Package " + pkg.packageName + " shared user changed from "
                                                            + (pkgSetting.sharedUser != null
                                                               ? pkgSetting.sharedUser.name : "<nothing>")
                                                            + " to "
                                                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
                                                            + "; replacing with new");
                pkgSetting = null;
            }
        
            String[] usesStaticLibraries = null;
            if (pkg.usesStaticLibraries != null) {
                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
            }
            // 更新  PackageSetting 没有则要生成
            final boolean createNewPackage = (pkgSetting == null);
            if (createNewPackage) {
                final String parentPackageName = (pkg.parentPackage != null)
                    ? pkg.parentPackage.packageName : null;
                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
                final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
                // REMOVE SharedUserSetting from method; update in a separate call
                pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
                                                       disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
                                                       destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
                                                       pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
                                                       pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
                                                       user, true /*allowInstall*/, instantApp, virtualPreload,
                                                       parentPackageName, pkg.getChildPackageNames(),
                                                       UserManagerService.getInstance(), usesStaticLibraries,
                                                       pkg.usesStaticLibrariesVersions);
            } else {
                // REMOVE SharedUserSetting from method; update in a separate call.
                //
                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
                // secondaryCpuAbi are not known at this point so we always update them
                // to null here, only to reset them at a later point.
                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
                                              destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
                                              pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
                                              pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
                                              pkg.getChildPackageNames(), UserManagerService.getInstance(),
                                              usesStaticLibraries, pkg.usesStaticLibrariesVersions);
            }
            if (createNewPackage && originalPkgSetting != null) {
                // This is the initial transition from the original package, so,
                // fix up the new package's name now. We must do this after looking
                // up the package under its new name, so getPackageLP takes care of
                // fiddling things correctly.
                pkg.setPackageName(originalPkgSetting.name);
        
                // File a report about this.
                String msg = "New package " + pkgSetting.realName
                    + " renamed to replace old package " + pkgSetting.name;
                reportSettingsProblem(Log.WARN, msg);
            }
        
            final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
            // for existing packages, change the install state; but, only if it's explicitly specified
            // 更改已存在应用包的安装状态
            if (!createNewPackage) {
                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
            }
            if (disabledPkgSetting != null) {
                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
            }
        
            // Apps which share a sharedUserId must be placed in the same selinux domain. If this
            // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
            // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
            // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
            // least restrictive selinux domain.
            // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
            // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
            // ensures that all packages continue to run in the same selinux domain.
            // 共享  sharedUserId 的应用必须放在同一个  selinux 域中。 如果此程序包是作为此共享用户安装的第一个应用程序,
            // 请将  seInfoTargetSdkVersion 设置为其  targetSdkVersion。 这些稍后在  PackageManagerService 的构造函
            // 数中调整为共享用户中所有应用程序的最低  targetSdkVersion,这对应于限制性最小的  selinux 域。
            // 注意:在安装/更新新软件包时,即使使用较低的  targetSdkVersion,共享用户的  seinfoTargetSdkVersion
            // 也不会被修改,直到下次引导。 这可确保所有包继续在同一  selinux 域中运行。
            final int targetSdkVersion =
                ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
                sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
            // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
            // They currently can be if the sharedUser apps are signed with the platform key.
            final boolean isPrivileged = (sharedUserSetting != null) ?
                sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
        
            pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
                                                               pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
            pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
                                                                                                   userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId));
        
            pkg.mExtras = pkgSetting;
            pkg.applicationInfo.processName = fixProcessName(
                                                             pkg.applicationInfo.packageName,
                                                             pkg.applicationInfo.processName);
        
            if (!isPlatformPackage) {
                // Get all of our default paths setup
                pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
            }
            // 更新  abi 引用
            final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
        
            if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
                if (needToDeriveAbi) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
                    final boolean extractNativeLibs = !pkg.isLibrary();
                    derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        
                    // Some system apps still use directory structure for native libraries
                    // in which case we might end up not detecting abi solely based on apk
                    // structure. Try to detect abi based on directory structure.
                    if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
                        pkg.applicationInfo.primaryCpuAbi == null) {
                        setBundledAppAbisAndRoots(pkg, pkgSetting);
                        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
                    }
                } else {
                    // This is not a first boot or an upgrade, don't bother deriving the
                    // ABI during the scan. Instead, trust the value that was stored in the
                    // package setting.
                    pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
                    pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
        
                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
        
                    if (DEBUG_ABI_SELECTION) {
                        Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
                               pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
                               pkg.applicationInfo.secondaryCpuAbi);
                    }
                }
            } else {
                if ((scanFlags & SCAN_MOVE) != 0) {
                    // We haven't run dex-opt for this move (since we've moved the compiled output too)
                    // but we already have this packages package info in the PackageSetting. We just
                    // use that and derive the native library path based on the new codepath.
                    pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
                    pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
                }
        
                // Set native library paths again. For moves, the path will be updated based on the
                // ABIs we've determined above. For non-moves, the path will be updated based on the
                // ABIs we determined during compilation, but the path will depend on the final
                // package path (after the rename away from the stage path).
                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
            }
        
            // This is a special case for the "system" package, where the ABI is
            // dictated by the zygote configuration (and init.rc). We should keep track
            // of this ABI so that we can deal with "normal" applications that run under
            // the same UID correctly.
            if (isPlatformPackage) {
                pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
            }
        
            // If there's a mismatch between the abi-override in the package setting
            // and the abiOverride specified for the install. Warn about this because we
            // would've already compiled the app without taking the package setting into
            // account.
            if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
                if (cpuAbiOverride == null && pkg.packageName != null) {
                    Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
                           " for package " + pkg.packageName);
                }
            }
        
            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
            pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
        
            // Copy the derived override back to the parsed package, so that we can
            // update the package settings accordingly.
            pkg.cpuAbiOverride = cpuAbiOverride;
        
            // Push the derived path down into PackageSettings so we know what to
            // clean up at uninstall time.
            pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
        
            if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
                // We don't do this here during boot because we can do it all
                // at once after scanning all existing packages.
                //
                // We also do this *before* we perform dexopt on this package, so that
                // we can avoid redundant dexopts, and also to make sure we've got the
                // code and package path correct.
                changedAbiCodePath =
                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
            }
        
            if (isUnderFactoryTest && pkg.requestedPermissions.contains(
                                                                        android.Manifest.permission.FACTORY_TEST)) {
                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
            }
        
            if (isSystemApp(pkg)) {
                pkgSetting.isOrphaned = true;
            }
        
            // Take care of first install / last update times.
            // 记录首次安装时间和最后更新时间
            final long scanFileTime = getLastModifiedTime(pkg);
            if (currentTime != 0) {
                if (pkgSetting.firstInstallTime == 0) {
                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
                } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
                    pkgSetting.lastUpdateTime = currentTime;
                }
            } else if (pkgSetting.firstInstallTime == 0) {
                // We need *something*.  Take time time stamp of the file.
                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
            } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
                if (scanFileTime != pkgSetting.timeStamp) {
                    // A package on the system image has changed; consider this
                    // to be an update.
                    pkgSetting.lastUpdateTime = scanFileTime;
                }
            }
            pkgSetting.setTimeStamp(scanFileTime);
        
            pkgSetting.pkg = pkg;
            pkgSetting.pkgFlags = pkg.applicationInfo.flags;
            if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
                pkgSetting.versionCode = pkg.getLongVersionCode();
            }
            // Update volume if needed
            final String volumeUuid = pkg.applicationInfo.volumeUuid;
            if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
                Slog.i(PackageManagerService.TAG,
                       "Update" + (pkgSetting.isSystem() ? " system" : "")
                       + " package " + pkg.packageName
                       + " volume from " + pkgSetting.volumeUuid
                       + " to " + volumeUuid);
                pkgSetting.volumeUuid = volumeUuid;
            }
        
            return new ScanResult(true, pkgSetting, changedAbiCodePath);
        }
      • commitScanResultsLocked()

        提交包扫描并修改系统状态。

          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
        162
        163
        164
        165
        166
        167
        168
        169
        170
        171
        172
        173
        174
        175
        176
        177
        178
        179
        180
        181
        182
        183
        184
        185
        186
        187
        188
        189
        
        @GuardedBy("mPackages")
        private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
            throws PackageManagerException {
            final PackageParser.Package pkg = request.pkg;
            final PackageParser.Package oldPkg = request.oldPkg;
            final @ParseFlags int parseFlags = request.parseFlags;
            final @ScanFlags int scanFlags = request.scanFlags;
            final PackageSetting oldPkgSetting = request.oldPkgSetting;
            final PackageSetting originalPkgSetting = request.originalPkgSetting;
            final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
            final UserHandle user = request.user;
            final String realPkgName = request.realPkgName;
            final PackageSetting pkgSetting = result.pkgSetting;
            final List<String> changedAbiCodePath = result.changedAbiCodePath;
            final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
            // 新旧包  sharedUser 不一致
            if (newPkgSettingCreated) {
                if (originalPkgSetting != null) {
                    mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
                }
                // 新建用户
                mSettings.addUserToSettingLPw(pkgSetting);
                // 原应用包数据传给新包,原包数据将不会保留
                if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
                    mTransferedPackages.add(originalPkgSetting.name);
                }
            }
            pkg.applicationInfo.uid = pkgSetting.appId;
            // 更新用户状态
            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
        
            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
                mTransferedPackages.add(pkg.packageName);
            }
        
            if ((scanFlags & SCAN_BOOTING) == 0
                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                // Check all shared libraries and map to their actual file path.
                // We only do this here for apps not on a system dir, because those
                // are the only ones that can fail an install due to this.  We
                // will take care of the system apps by updating all of their
                // library paths after the scan is done. Also during the initial
                // scan don't update any libs as we do this wholesale after all
                // apps are scanned to avoid dependency based scanning.
                // 检查所有非系统目录上的共享库并映射到它们的实际文件路径。
                updateSharedLibrariesLPr(pkg, null);
            }
        
            // All versions of a static shared library are referenced with the same
            // package name. Internally, we use a synthetic package name to allow
            // multiple versions of the same shared library to be installed. So,
            // we need to generate the synthetic package name of the latest shared
            // library in order to compare signatures.
            // 使用相同的包名称引用静态共享库的所有版本。 在内部,我们使用合成包名称来允许安装同一共享库的多个版本。
            // 因此,我们需要生成最新共享库的合成包名称,以便比较签名。
            // 以下处理应用包的签名信息
            PackageSetting signatureCheckPs = pkgSetting;
            if (pkg.applicationInfo.isStaticSharedLibrary()) {
                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
                if (libraryEntry != null) {
                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
                }
            }
        
            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
            if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
                if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
                    // We just determined the app is signed correctly, so bring
                    // over the latest parsed certs.
                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
                } else {
                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                                                          "Package " + pkg.packageName + " upgrade keys do not match the "
                                                          + "previously installed version");
                    } else {
                        pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
                        String msg = "System package " + pkg.packageName
                            + " signature changed; retaining data.";
                        reportSettingsProblem(Log.WARN, msg);
                    }
                }
            } else {
                try {
                    final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
                    final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
                    final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
                                                                 pkg.mSigningDetails, compareCompat, compareRecover);
                    // The new KeySets will be re-added later in the scanning process.
                    if (compatMatch) {
                        synchronized (mPackages) {
                            ksms.removeAppKeySetDataLPw(pkg.packageName);
                        }
                    }
                    // We just determined the app is signed correctly, so bring
                    // over the latest parsed certs.
                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
        
        
                    // if this is is a sharedUser, check to see if the new package is signed by a newer
                    // signing certificate than the existing one, and if so, copy over the new details
                    if (signatureCheckPs.sharedUser != null) {
                        if (pkg.mSigningDetails.hasAncestor(
                                                            signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
                            signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
                        }
                        if (signatureCheckPs.sharedUser.signaturesChanged == null) {
                            signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
                        }
                    }
                } catch (PackageManagerException e) {
                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                        throw e;
                    }
                    // The signature has changed, but this package is in the system
                    // image...  let's recover!
                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
        
                    // If the system app is part of a shared user we allow that shared user to change
                    // signatures as well as part of an OTA. We still need to verify that the signatures
                    // are consistent within the shared user for a given boot, so only allow updating
                    // the signatures on the first package scanned for the shared user (i.e. if the
                    // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
                    // OTA 更改了签名信息,更新签名信息
                    if (signatureCheckPs.sharedUser != null) {
                        if (signatureCheckPs.sharedUser.signaturesChanged != null &&
                            compareSignatures(
                                              signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
                                              pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
                            throw new PackageManagerException(
                                                              INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
                                                              "Signature mismatch for shared user: " + pkgSetting.sharedUser);
                        }
        
                        signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
                        signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
                    }
                    // File a report about this.
                    String msg = "System package " + pkg.packageName
                        + " signature changed; retaining data.";
                    reportSettingsProblem(Log.WARN, msg);
                } catch (IllegalArgumentException e) {
                }
            }
            // 权限相关
            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
                // This package wants to adopt ownership of permissions from
                // another package.
                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
                    final String origName = pkg.mAdoptPermissions.get(i);
                    final PackageSetting orig = mSettings.getPackageLPr(origName);
                    if (orig != null) {
                        if (verifyPackageUpdateLPr(orig, pkg)) {
                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
                                   + pkg.packageName);
                            mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
                        }
                    }
                }
            }
            // 处理  cpu abi
            if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
                for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                    final String codePathString = changedAbiCodePath.get(i);
                    try {
                        mInstaller.rmdex(codePathString,
                                         getDexCodeInstructionSet(getPreferredInstructionSet()));
                    } catch (InstallerException ignored) {
                    }
                }
            }
        
            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
                if (oldPkgSetting != null) {
                    synchronized (mPackages) {
                        mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
                    }
                }
            } else {
                final int userId = user == null ? 0 : user.getIdentifier();
                // Modify state for the given package setting
                // 提交扫描结果到  PackageManagerService
                commitPackageSettings(pkg, oldPkg, pkgSetting, user, scanFlags,
                                      (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
                if (pkgSetting.getInstantApp(userId)) {
                    mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
                }
            }
        }
      • commitPackageSettings()

          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
        162
        163
        164
        165
        166
        167
        168
        169
        170
        171
        172
        173
        174
        175
        176
        177
        178
        179
        180
        181
        182
        183
        184
        185
        186
        187
        188
        189
        190
        191
        192
        193
        194
        195
        196
        197
        198
        199
        200
        201
        202
        203
        204
        205
        206
        207
        208
        209
        210
        211
        212
        213
        214
        215
        216
        217
        218
        219
        220
        221
        222
        223
        224
        225
        226
        227
        228
        229
        230
        231
        232
        233
        234
        235
        236
        237
        238
        239
        240
        241
        242
        243
        244
        245
        246
        247
        248
        249
        250
        251
        252
        253
        254
        255
        256
        257
        258
        259
        260
        261
        262
        263
        264
        265
        266
        267
        268
        269
        270
        271
        272
        
        private void commitPackageSettings(PackageParser.Package pkg,
                                           @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting, UserHandle user,
                                           final @ScanFlags int scanFlags, boolean chatty) {
            final String pkgName = pkg.packageName;
            // mCustomResolverComponentName 定义于:R.string.config_customResolverActivity
            if (mCustomResolverComponentName != null &&
                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
                // 用自定义的替换默认的  ResolverActivity;前面说过  ResolverActivity 的用处
                // Intent 有多个匹配项时,展示这些匹配项供用户选择一个
                setUpCustomResolverActivity(pkg);
            }
            // 处理特殊包名:android
            if (pkg.packageName.equals("android")) {
                synchronized (mPackages) {
                    if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
                        // Set up information for our fall-back user intent resolution activity.
                        // 系统应用包
                        mPlatformPackage = pkg;
                        pkg.mVersionCode = mSdkVersion;
                        pkg.mVersionCodeMajor = 0;
                        mAndroidApplication = pkg.applicationInfo;
                        // 没有自定义  ResolverActivity;初始化默认  ResolverActivity
                        if (!mResolverReplaced) {
                            mResolveActivity.applicationInfo = mAndroidApplication;
                            mResolveActivity.name = ResolverActivity.class.getName();
                            mResolveActivity.packageName = mAndroidApplication.packageName;
                            mResolveActivity.processName = "system:ui";
                            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
                            mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
                            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
                            mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
                            mResolveActivity.exported = true;
                            mResolveActivity.enabled = true;
                            mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
                            mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
                                | ActivityInfo.CONFIG_ORIENTATION
                                | ActivityInfo.CONFIG_KEYBOARD
                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
                            mResolveInfo.activityInfo = mResolveActivity;
                            mResolveInfo.priority = 0;
                            mResolveInfo.preferredOrder = 0;
                            mResolveInfo.match = 0;
                            mResolveComponentName = new ComponentName(
                                                                      mAndroidApplication.packageName, mResolveActivity.name);
                        }
                    }
                }
            }
        
            ArrayList<PackageParser.Package> clientLibPkgs = null;
            // writer
            synchronized (mPackages) {
                boolean hasStaticSharedLibs = false;
        
                // Any app can add new static shared libraries
                // 更新链接库信息
                if (pkg.staticSharedLibName != null) {
                    // Static shared libs don't allow renaming as they have synthetic package
                    // names to allow install of multiple versions, so use name from manifest.
                    if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
                                            pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
                                            pkg.manifestPackageName, pkg.getLongVersionCode())) {
                        hasStaticSharedLibs = true;
                    } else {
                        Slog.w(TAG, "Package " + pkg.packageName + " library "
                               + pkg.staticSharedLibName + " already exists; skipping");
                    }
                    // Static shared libs cannot be updated once installed since they
                    // use synthetic package name which includes the version code, so
                    // not need to update other packages's shared lib dependencies.
                }
                // 系统应用包更新时,链接库相关更新
                if (!hasStaticSharedLibs
                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                    // Only system apps can add new dynamic shared libraries.
                    if (pkg.libraryNames != null) {
                        for (int i = 0; i < pkg.libraryNames.size(); i++) {
                            String name = pkg.libraryNames.get(i);
                            boolean allowed = false;
                            if (pkg.isUpdatedSystemApp()) {
                                // New library entries can only be added through the
                                // system image.  This is important to get rid of a lot
                                // of nasty edge cases: for example if we allowed a non-
                                // system update of the app to add a library, then uninstalling
                                // the update would make the library go away, and assumptions
                                // we made such as through app install filtering would now
                                // have allowed apps on the device which aren't compatible
                                // with it.  Better to just have the restriction here, be
                                // conservative, and create many fewer cases that can negatively
                                // impact the user experience.
                                final PackageSetting sysPs = mSettings
                                    .getDisabledSystemPkgLPr(pkg.packageName);
                                if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
                                    for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
                                        if (name.equals(sysPs.pkg.libraryNames.get(j))) {
                                            allowed = true;
                                            break;
                                        }
                                    }
                                }
                            } else {
                                allowed = true;
                            }
                            if ((scanFlags & SCAN_BOOTING) == 0) {
                                // If we are not booting, we need to update any applications
                                // that are clients of our shared library.  If we are booting,
                                // this will all be done once the scan is complete.
                                clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
                            }
                        }
                    }
                }
        
                if ((scanFlags & SCAN_BOOTING) != 0) {
                    // No apps can run during boot scan, so they don't need to be frozen
                } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
                    // Caller asked to not kill app, so it's probably not frozen
                } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
                    // Caller asked us to ignore frozen check for some reason; they
                    // probably didn't know the package name
                } else {
                    // We're doing major surgery on this package, so it better be frozen
                    // right now to keep it from launching
                    checkPackageFrozen(pkgName);
                }
        
                // Also need to kill any apps that are dependent on the library.
                if (clientLibPkgs != null) {
                    for (int i=0; i<clientLibPkgs.size(); i++) {
                        PackageParser.Package clientPkg = clientLibPkgs.get(i);
                        killApplication(clientPkg.applicationInfo.packageName,
                                        clientPkg.applicationInfo.uid, "update lib");
                    }
                }
        
                // writer
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
                // PackageManagerService 存储四大组件信息
                synchronized (mPackages) {
                    // We don't expect installation to fail beyond this point
        
                    // Add the new setting to mSettings
                    mSettings.insertPackageSettingLPw(pkgSetting, pkg);
                    // Add the new setting to mPackages
                    mPackages.put(pkg.applicationInfo.packageName, pkg);
                    // Make sure we don't accidentally delete its data.
                    final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
                    while (iter.hasNext()) {
                        PackageCleanItem item = iter.next();
                        if (pkgName.equals(item.packageName)) {
                            iter.remove();
                        }
                    }
        
                    // Add the package's KeySets to the global KeySetManagerService
                    KeySetManagerService ksms = mSettings.mKeySetManagerService;
                    ksms.addScannedPackageLPw(pkg);
                    // Provider
                    int N = pkg.providers.size();
                    StringBuilder r = null;
                    int i;
                    for (i=0; i<N; i++) {
                        PackageParser.Provider p = pkg.providers.get(i);
        
                        // ......
        
                    }
                    // Service
                    N = pkg.services.size();
                    r = null;
                    for (i=0; i<N; i++) {
                        PackageParser.Service s = pkg.services.get(i);
                        s.info.processName = fixProcessName(pkg.applicationInfo.processName,
                                                            s.info.processName);
                        mServices.addService(s);
                        if (chatty) {
                            if (r == null) {
                                r = new StringBuilder(256);
                            } else {
                                r.append(' ');
                            }
                            r.append(s.info.name);
                        }
                    }
                    // Receiver
                    N = pkg.receivers.size();
                    r = null;
                    for (i=0; i<N; i++) {
                        PackageParser.Activity a = pkg.receivers.get(i);
                        a.info.processName = fixProcessName(pkg.applicationInfo.processName,
                                                            a.info.processName);
                        mReceivers.addActivity(a, "receiver");
                        if (chatty) {
                            if (r == null) {
                                r = new StringBuilder(256);
                            } else {
                                r.append(' ');
                            }
                            r.append(a.info.name);
                        }
                    }
                    // Activity
                    N = pkg.activities.size();
                    r = null;
                    for (i=0; i<N; i++) {
                        PackageParser.Activity a = pkg.activities.get(i);
                        a.info.processName = fixProcessName(pkg.applicationInfo.processName,
                                                            a.info.processName);
                        mActivities.addActivity(a, "activity");
                        if (chatty) {
                            if (r == null) {
                                r = new StringBuilder(256);
                            } else {
                                r.append(' ');
                            }
                            r.append(a.info.name);
                        }
                    }
                    // Permission 不允许临时应用程序定义新权限和权限组。
                    // Don't allow ephemeral applications to define new permissions groups.
                    if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
                    } else {
                        mPermissionManager.addAllPermissionGroups(pkg, chatty);
                    }
        
                    // Don't allow ephemeral applications to define new permissions.
                    if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
                    } else {
                        mPermissionManager.addAllPermissions(pkg, chatty);
                    }
                    // Instrumentation
                    N = pkg.instrumentation.size();
                    r = null;
                    for (i=0; i<N; i++) {
                        PackageParser.Instrumentation a = pkg.instrumentation.get(i);
                        a.info.packageName = pkg.applicationInfo.packageName;
                        a.info.sourceDir = pkg.applicationInfo.sourceDir;
                        a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
                        a.info.splitNames = pkg.splitNames;
                        a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
                        a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
                        a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
                        a.info.dataDir = pkg.applicationInfo.dataDir;
                        a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
                        a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
                        a.info.primaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
                        a.info.secondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi;
                        a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
                        a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
                        mInstrumentation.put(a.getComponentName(), a);
                        if (chatty) {
                            if (r == null) {
                                r = new StringBuilder(256);
                            } else {
                                r.append(' ');
                            }
                            r.append(a.info.name);
                        }
                    }
                    // Protected Broadcast
                    if (pkg.protectedBroadcasts != null) {
                        N = pkg.protectedBroadcasts.size();
                        synchronized (mProtectedBroadcasts) {
                            for (i = 0; i < N; i++) {
                                mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
                            }
                        }
                    }
        
                }