分析通过 APK 文件安装应用的过程

PackageManagerService 应用安装过程

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

PackageInstaller

调用安装程序:

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

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>

InstallStart.onCreate()

 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
protected void onCreate(@Nullable Bundle savedInstanceState) {
    // ......
    Intent nextActivity = new Intent(intent);
    nextActivity.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
    // ......

    if (PackageInstaller.ACTION_CONFIRM_PERMISSIONS.equals(intent.getAction())) {
        nextActivity.setClass(this, PackageInstallerActivity.class);
    } else {
        // 一般执行这个分支
        Uri packageUri = intent.getData();

        if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE)
                                   || packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
            // Copy file to prevent it from being changed underneath this process
            // 只是执行了拷贝操作,防止  apk 文件被改动
            nextActivity.setClass(this, InstallStaging.class);
        } else if (packageUri != null && packageUri.getScheme().equals(
                                                                       PackageInstallerActivity.SCHEME_PACKAGE)) {
            nextActivity.setClass(this, PackageInstallerActivity.class);
        } else {
            Intent result = new Intent();
            result.putExtra(Intent.EXTRA_INSTALL_RESULT,
                            PackageManager.INSTALL_FAILED_INVALID_URI);
            setResult(RESULT_FIRST_USER, result);

            nextActivity = null;
        }
    }

    if (nextActivity != null) {
        startActivity(nextActivity);
    }
    finish();
}

InstallStaging.onResume()

 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
protected void onResume() {
    super.onResume();

    // ......

    mStagingTask = new StagingAsyncTask();
    mStagingTask.execute(getIntent().getData());
}

private final class StagingAsyncTask extends AsyncTask<Uri, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Uri... params) {
        if (params == null || params.length <= 0) {
            return false;
        }
        Uri packageUri = params[0];
        try (InputStream in = getContentResolver().openInputStream(packageUri)) {
            // Despite the comments in ContentResolver#openInputStream the returned stream can
            // be null.
            if (in == null) {
                return false;
            }

            try (OutputStream out = new FileOutputStream(mStagedFile)) {
                byte[] buffer = new byte[1024 * 1024];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) >= 0) {
                    // Be nice and respond to a cancellation
                    if (isCancelled()) {
                        return false;
                    }
                    out.write(buffer, 0, bytesRead);
                }
            }
        } catch (IOException | SecurityException | IllegalStateException e) {
            return false;
        }
        return true;
    }

    @Override
    protected void onPostExecute(Boolean success) {
        if (success) {
            // Now start the installation again from a file
            Intent installIntent = new Intent(getIntent());
            installIntent.setClass(InstallStaging.this, DeleteStagedFileOnResult.class);
            installIntent.setData(Uri.fromFile(mStagedFile));

            if (installIntent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
                installIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
            }

            installIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            startActivity(installIntent);

            InstallStaging.this.finish();
        } else {
            showError();
        }
    }
}

public class DeleteStagedFileOnResult extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            Intent installIntent = new Intent(getIntent());
            installIntent.setClass(this, PackageInstallerActivity.class);

            installIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            startActivityForResult(installIntent, 0);
        }
    }
    // ......
}

PackageInstallerActivity.class

  • onCreate()

     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
    
    protected void onCreate(Bundle icicle) {
        super.onCreate(null);
    
        if (icicle != null) {
            mAllowUnknownSources = icicle.getBoolean(ALLOW_UNKNOWN_SOURCES_KEY);
        }
        // 获取  PackageManager,PackageManagerService 的代理类,它持有下面的  mIpm,
        // 其实就是  new ApplicationPackageManager(this, mIpm);通过  mIpm 和  PackageManagerService 通讯
        mPm = getPackageManager();
        // 获取  IPackageManager,这是  PackageManagerService 的  Binder 代理类
        mIpm = AppGlobals.getPackageManager();
        // 获取  AppOpsManager,这是  AppOpsServiec 的代理类;应用操作相关
        mAppOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
        // 获取  PackageInstallerService,应用安装服务
        mInstaller = mPm.getPackageInstaller();
        // 获取  UserManager,这是  UserManagerService 的代理类,用于用户管理
        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
    
        final Intent intent = getIntent();
    
        final Uri packageUri;
    
        if (PackageInstaller.ACTION_CONFIRM_PERMISSIONS.equals(intent.getAction())) {
            // ......
        } else {
            mSessionId = -1;
            packageUri = intent.getData();
            mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
            mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
        }
        // 穿戴设备
        if (DeviceUtils.isWear(this)) {
            showDialogInner(DLG_NOT_SUPPORTED_ON_WEAR);
            return;
        }
        // 解析  Uri 并设置此程序包的安装程序
        boolean wasSetUp = processPackageUri(packageUri);
        if (!wasSetUp) {
            return;
        }
    
        // load dummy layout with OK button disabled until we override this layout in
        // startInstallConfirm
        bindUi(R.layout.install_confirm, false);
        // 检查是否允许安装软件包并在允许的情况下启动安装。 如果不允许显示相应的对话框。
        // 允许安装则调用  initiateInstall();
        checkIfAllowedAndInitiateInstall();
    }
  • 获取安装包信息

    • processPackageUri()

       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
      
      private boolean processPackageUri(final Uri packageUri) {
          mPackageURI = packageUri;
      
          final String scheme = packageUri.getScheme();
      
          switch (scheme) {
          case SCHEME_PACKAGE: {
              // ......
          } break;
      
          case ContentResolver.SCHEME_FILE: {
              File sourceFile = new File(packageUri.getPath());
              PackageParser.Package parsed = PackageUtil.getPackageInfo(this, sourceFile);
              // ......
              mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
                                                           PackageManager.GET_PERMISSIONS, 0, 0, null,
                                                           new PackageUserState());
              mAppSnippet = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
          } break;
          }
      
          return true;
      }
      public static PackageParser.Package getPackageInfo(Context context, File sourceFile) {
          final PackageParser parser = new PackageParser();
          parser.setCallback(new PackageParser.CallbackImpl(context.getPackageManager()));
          try {
              return parser.parsePackage(sourceFile, 0);
          } catch (PackageParserException e) {
              return null;
          }
      }
    • PackageParser.parsePackage()

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      
      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 {
          // ......
          long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
          if (packageFile.isDirectory()) {
              // parseClusterPackage() 我们在上一篇(二)中分析过
              parsed = parseClusterPackage(packageFile, flags);
          } else {
              parsed = parseMonolithicPackage(packageFile, flags);
          }
          // ......
          return parsed;
      }
  • initiateInstall()

     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
    
    private void initiateInstall() {
        String pkgName = mPkgInfo.packageName;
        // Check if there is already a package on the device with this name
        // but it has been renamed to something else.
        // 如果设备上已有该应用包,并且曾经有更改过包名,则使用旧包名
        String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
        if (oldName != null && oldName.length > 0 && oldName[0] != null) {
            pkgName = oldName[0];
            mPkgInfo.packageName = pkgName;
            mPkgInfo.applicationInfo.packageName = pkgName;
        }
        // Check if package is already installed. display confirmation dialog if replacing pkg
        // 如果该应用包已被安装,则显示该应用被替换
        try {
            // This is a little convoluted because we want to get all uninstalled
            // apps, but this may include apps with just data, and if it is just
            // data we still want to count it as "installed".
            mAppInfo = mPm.getApplicationInfo(pkgName,
                                              PackageManager.MATCH_UNINSTALLED_PACKAGES);
            if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
                mAppInfo = null;
            }
        } catch (NameNotFoundException e) {
            mAppInfo = null;
        }
        // 主要显示应用需要的权限,最终调用  startInstall() 方法通过  InstallInstalling.class 类进行安装
        startInstallConfirm();
    }

InstallInstalling.class

  • onCreate()

     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
    
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.install_installing);
        ApplicationInfo appInfo = getIntent()
            .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
        mPackageURI = getIntent().getData();
        if ("package".equals(mPackageURI.getScheme())) {
            // ......
        } else {
            final File sourceFile = new File(mPackageURI.getPath());
            // 获取安装包基本信息:应用名称和应用图标
            PackageUtil.initSnippetForNewApp(this, PackageUtil.getAppSnippet(this, appInfo,
                                                                             sourceFile), R.id.app_snippet);
            if (savedInstanceState != null) {
                // ......
            } else {
                // 安装应用会话参数
                PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                                                                                           PackageInstaller.SessionParams.MODE_FULL_INSTALL);
                params.installFlags = PackageManager.INSTALL_FULL_APP;
                params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER);
                params.originatingUri = getIntent()
                    .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
                params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
                                                                UID_UNKNOWN);
                params.installerPackageName =
                    getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
    
                File file = new File(mPackageURI.getPath());
                try {
                    // 应用包基本信息
                    PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);
                    // 应用包名
                    params.setAppPackageName(pkg.packageName);
                    // 安装位置
                    params.setInstallLocation(pkg.installLocation);
                    // 安装后占用空间
                    params.setSize(
                                   PackageHelper.calculateInstalledSize(pkg, false, params.abiOverride));
                } catch (PackageParser.PackageParserException e) {
                    params.setSize(file.length());
                } catch (IOException e) {
                    params.setSize(file.length());
                }
    
                try {
                    // 接收安装事件并保存到  EventResultPersister;返回等待安装事件的  ID
                    // 这里将结果传入到  launchFinishBasedOnResult() 方法进行处理
                    mInstallId = InstallEventReceiver
                        .addObserver(this, EventResultPersister.GENERATE_NEW_ID,
                                     this::launchFinishBasedOnResult);
                } catch (EventResultPersister.OutOfIdsException e) {
                    launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
                }
    
                try {
                    // 创建安装会话并返回会话  Id
                    mSessionId = getPackageManager().getPackageInstaller().createSession(params);
                } catch (IOException e) {
                    launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
                }
            }
            // 显示安装进度
            mSessionCallback = new InstallSessionCallback();
        }
    }
    
    protected void onStart() {
        super.onStart();
        // 安装会话回调,这里只显示安装进度
        getPackageManager().getPackageInstaller().registerSessionCallback(mSessionCallback);
    }
    
    protected void onResume() {
        super.onResume();
        // This is the first onResume in a single life of the activity
        if (mInstallingTask == null) {
            // 获取安装会话信息
            PackageInstaller installer = getPackageManager().getPackageInstaller();
            PackageInstaller.SessionInfo sessionInfo = installer.getSessionInfo(mSessionId);
            if (sessionInfo != null && !sessionInfo.isActive()) {
                // 通过  AsyncTask 异步执行
                mInstallingTask = new InstallingAsyncTask();
                mInstallingTask.execute();
            } else {
                // we will receive a broadcast when the install is finished
                mCancelButton.setEnabled(false);
                setFinishOnTouchOutside(false);
            }
        }
    }
  • InstallingAsyncTask.class

     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
    
    private final class InstallingAsyncTask extends AsyncTask<Void, Void,
                                                                  PackageInstaller.Session> {
        volatile boolean isDone;
    
        @Override
        protected PackageInstaller.Session doInBackground(Void... params) {
            PackageInstaller.Session session;
            try {
                // 开启安装会话
                session = getPackageManager().getPackageInstaller().openSession(mSessionId);
            } catch (IOException e) {
                return null;
            }
            // 初始化安装进度
            session.setStagingProgress(0);
            try {
                File file = new File(mPackageURI.getPath());
    
                try (InputStream in = new FileInputStream(file)) {
                    long sizeBytes = file.length();
                    try (OutputStream out = session
                         .openWrite("PackageInstaller", 0, sizeBytes)) {
                        byte[] buffer = new byte[1024 * 1024];
                        while (true) {
                            int numRead = in.read(buffer);
    
                            if (numRead == -1) {
                                // 确保写入硬盘
                                session.fsync(out);
                                break;
                            }
    
                            if (isCancelled()) {
                                session.close();
                                break;
                            }
    
                            out.write(buffer, 0, numRead);
                            if (sizeBytes > 0) {
                                float fraction = ((float) numRead / (float) sizeBytes);
                                session.addProgress(fraction);
                            }
                        }
                    }
                }
    
                return session;
            } catch (IOException | SecurityException e) {
                Log.e(LOG_TAG, "Could not write package", e);
    
                session.close();
    
                return null;
            } finally {
                synchronized (this) {
                    isDone = true;
                    notifyAll();
                }
            }
        }
    
        @Override
        protected void onPostExecute(PackageInstaller.Session session) {
            if (session != null) {
                Intent broadcastIntent = new Intent(BROADCAST_ACTION);
                broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                broadcastIntent.setPackage(
                                           getPackageManager().getPermissionControllerPackageName());
                broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId);
    
                PendingIntent pendingIntent = PendingIntent.getBroadcast(
                                                                         InstallInstalling.this,
                                                                         mInstallId,
                                                                         broadcastIntent,
                                                                         PendingIntent.FLAG_UPDATE_CURRENT);
                // 传入  IntentSender;把它看作可以传递给其它应用的  Intent 就好
                session.commit(pendingIntent.getIntentSender());
                mCancelButton.setEnabled(false);
                setFinishOnTouchOutside(false);
            } else {
                getPackageManager().getPackageInstaller().abandonSession(mSessionId);
    
                if (!isCancelled()) {
                    launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null);
                }
            }
        }
    }

PackageInstaller.class

createSession()

 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
// 前面提到过 =getPackageManager()= 返回的是 =ApplicationPackageManager= 对象。
// ApplicationPackageManager.getPackageInstaller()
public PackageInstaller getPackageInstaller() {
    synchronized (mLock) {
        if (mInstaller == null) {
            try {
                // mPM 是  IPackageManager 的对象,会通过  Binder 调用  PackageManagerService 同名方法完成
                mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
                                                  mContext.getPackageName(), mContext.getUserId());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return mInstaller;
    }
}
// PackageManagerService.getPackageInstaller()
public IPackageInstaller getPackageInstaller() {
    if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
        return null;
    }
    return mInstallerService;
}

public int createSession(@NonNull SessionParams params) throws IOException {
    try {
        final String installerPackage;
        if (params.installerPackageName == null) {
            installerPackage = mInstallerPackageName;
        } else {
            installerPackage = params.installerPackageName;
        }
        // mInstaller 是  IPackageInstaller 对象通过  Binder 调用  PackageInstallerService
        return mInstaller.createSession(params, installerPackage, mUserId);
    } catch (RuntimeException e) {
        // ......
    }
}
  • PackageInstallerService.createSession()

      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
    
    public int createSession(SessionParams params, String installerPackageName, int userId) {
        try {
            return createSessionInternal(params, installerPackageName, userId);
        } catch (IOException e) {
            throw ExceptionUtils.wrap(e);
        }
    }
    
    private int createSessionInternal(SessionParams params, String installerPackageName, int userId)
        throws IOException {
        // 权限检查
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(
                                                      callingUid, userId, true, true, "createSession");
    
        if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
            throw new SecurityException("User restriction prevents installing");
        }
        // 根据调用者的  UID 修正  SessionParams.installFlags
        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
            params.installFlags |= PackageManager.INSTALL_FROM_ADB;
    
        } else {
            // Only apps with INSTALL_PACKAGES are allowed to set an installer that is not the
            // caller.
            if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES) !=
                PackageManager.PERMISSION_GRANTED) {
                mAppOps.checkPackage(callingUid, installerPackageName);
            }
    
            params.installFlags &= ~PackageManager.INSTALL_FROM_ADB;
            params.installFlags &= ~PackageManager.INSTALL_ALL_USERS;
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
            if ((params.installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0
                && !mPm.isCallerVerifier(callingUid)) {
                params.installFlags &= ~PackageManager.INSTALL_VIRTUAL_PRELOAD;
            }
        }
    
        // Only system components can circumvent runtime permissions when installing.
        if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
            && mContext.checkCallingOrSelfPermission(Manifest.permission
                                                     .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
            throw new SecurityException("You need the "
                                        + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
                                        + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
        }
        // 不支持的  flags;已经不允许安装在外置存储
        if ((params.installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
            || (params.installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
            throw new IllegalArgumentException(
                                               "New installs into ASEC containers no longer supported");
        }
    
        // Defensively resize giant app icons
        // 调整图标大小
        if (params.appIcon != null) {
            final ActivityManager am = (ActivityManager) mContext.getSystemService(
                                                                                   Context.ACTIVITY_SERVICE);
            final int iconSize = am.getLauncherLargeIconSize();
            if ((params.appIcon.getWidth() > iconSize * 2)
                || (params.appIcon.getHeight() > iconSize * 2)) {
                params.appIcon = Bitmap.createScaledBitmap(params.appIcon, iconSize, iconSize,
                                                           true);
            }
        }
    
        switch (params.mode) {
        case SessionParams.MODE_FULL_INSTALL:
        case SessionParams.MODE_INHERIT_EXISTING:
            break;
        default:
            throw new IllegalArgumentException("Invalid install mode: " + params.mode);
        }
    
        // If caller requested explicit location, sanity check it, otherwise
        // resolve the best internal or adopted location.
        // 根据  installFlags 确定安装位置
        if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
            if (!PackageHelper.fitsOnInternal(mContext, params)) {
                throw new IOException("No suitable internal storage available");
            }
    
        } else if ((params.installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
            if (!PackageHelper.fitsOnExternal(mContext, params)) {
                throw new IOException("No suitable external storage available");
            }
    
        } else if ((params.installFlags & PackageManager.INSTALL_FORCE_VOLUME_UUID) != 0) {
            // For now, installs to adopted media are treated as internal from
            // an install flag point-of-view.
            params.setInstallFlagsInternal();
    
        } else {
            // 默认不指定安装位置
            // For now, installs to adopted media are treated as internal from
            // an install flag point-of-view.
            params.setInstallFlagsInternal();
    
            // Resolve best location for install, based on combination of
            // requested install flags, delta size, and manifest settings.
            final long ident = Binder.clearCallingIdentity();
            try {
                params.volumeUuid = PackageHelper.resolveInstallVolume(mContext, params);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
    
        final int sessionId;
        final PackageInstallerSession session;
        synchronized (mSessions) {
            // Sanity check that installer isn't going crazy
            // 确保调用者没有提交过多的会话
            final int activeCount = getSessionCount(mSessions, callingUid);
            if (activeCount >= MAX_ACTIVE_SESSIONS) {
                throw new IllegalStateException(
                                                "Too many active sessions for UID " + callingUid);
            }
            final int historicalCount = mHistoricalSessionsByInstaller.get(callingUid);
            if (historicalCount >= MAX_HISTORICAL_SESSIONS) {
                throw new IllegalStateException(
                                                "Too many historical sessions for UID " + callingUid);
            }
            // 生成当前新建会话的  Id
            sessionId = allocateSessionIdLocked();
        }
    
        final long createdMillis = System.currentTimeMillis();
        // We're staging to exactly one location
        File stageDir = null;
        String stageCid = null;
        if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
            // 默认安装到内置存储
            final boolean isInstant =
                (params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
            // /data 下面的临时目录,用于存放  apk 文件
            stageDir = buildStageDir(params.volumeUuid, sessionId, isInstant);
        } else {
            stageCid = buildExternalStageCid(sessionId);
        }
        // 新建会话对象
        session = new PackageInstallerSession(mInternalCallback, mContext, mPm,
                                              mInstallThread.getLooper(), sessionId, userId, installerPackageName, callingUid,
                                              params, createdMillis, stageDir, stageCid, false, false);
    
        synchronized (mSessions) {
            mSessions.put(sessionId, session);
        }
        // 回调,通知会话创建
        mCallbacks.notifySessionCreated(session.sessionId, session.userId);
        // 异步写入到  SessionFile 进行记录
        writeSessionsAsync();
        return sessionId;
    }

openSession()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public @NonNull Session openSession(int sessionId) throws IOException {
    try {
        // Session.class 是  PackageInstaller 的内部类,用于管理  IPackageInstallerSession 对象
        return new Session(mInstaller.openSession(sessionId));
    } catch (RuntimeException e) {
        ExceptionUtils.maybeUnwrapIOException(e);
        throw e;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
  • PackageInstallerService.openSession()

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    public IPackageInstallerSession openSession(int sessionId) {
        try {
            return openSessionInternal(sessionId);
        } catch (IOException e) {
            throw ExceptionUtils.wrap(e);
        }
    }
    private IPackageInstallerSession openSessionInternal(int sessionId) throws IOException {
        synchronized (mSessions) {
            final PackageInstallerSession session = mSessions.get(sessionId);
            if (session == null || !isCallingUidOwner(session)) {
                throw new SecurityException("Caller has no access to session " + sessionId);
            }
            session.open();
            // 返回的是  IPackageInstallerSession;其实就是该会话的代理
            return session;
        }
    }
  • PackageInstallerSession.open()

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    public void open() throws IOException {
        // 激活当前会话
        if (mActiveCount.getAndIncrement() == 0) {
            mCallback.onSessionActiveChanged(this, true);
        }
        boolean wasPrepared;
        synchronized (mLock) {
            wasPrepared = mPrepared;
            if (!mPrepared) {
                if (stageDir != null) {
                    // 准备临时目录
                    prepareStageDir(stageDir);
                } else {
                    throw new IllegalArgumentException("stageDir must be set");
                }
                mPrepared = true;
            }
        }
        if (!wasPrepared) {
            // 回调,通知会话准备完毕
            mCallback.onSessionPrepared(this);
        }
    }

Session.commit()

1
2
3
4
5
6
7
public void commit(@NonNull IntentSender statusReceiver) {
    try {
        mSession.commit(statusReceiver, false);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
  • PackageInstallerSession.commit()

     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
    
    public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
        Preconditions.checkNotNull(statusReceiver);
    
        final boolean wasSealed;
        synchronized (mLock) {
            // 检查调用者是否是该会话的所有者
            assertCallerIsOwnerOrRootLocked();
            // 检查会话是否准备好或被销毁
            assertPreparedAndNotDestroyedLocked("commit");
    
            final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(
                                                                                            mContext, statusReceiver, sessionId,
                                                                                            isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId);
            mRemoteObserver = adapter.getBinder();
            // forTransfer=false
            if (forTransfer) {
                mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
    
                if (mInstallerUid == mOriginalInstallerUid) {
                    throw new IllegalArgumentException("Session has not been transferred");
                }
            } else {
                // 检查安装用户是否改变
                if (mInstallerUid != mOriginalInstallerUid) {
                    throw new IllegalArgumentException("Session has been transferred");
                }
            }
            // mSealed=false
            wasSealed = mSealed;
            if (!mSealed) {
                try {
                    // 锁定会话以防止修改并验证其内容。
                    sealAndValidateLocked();
                } catch (IOException e) {
                    throw new IllegalArgumentException(e);
                } catch (PackageManagerException e) {
                    // Do now throw an exception here to stay compatible with O and older
                    destroyInternal();
                    dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
                    return;
                }
            }
    
            // Client staging is fully done at this point
            // 客户端部分已全部完成
            mClientProgress = 1f;
            computeProgressLocked(true);
    
            // This ongoing commit should keep session active, even though client
            // will probably close their end.
            // 活动会话计数器增加
            mActiveCount.incrementAndGet();
    
            mCommitted = true;
            // 调用  commitLocked() 方法
            mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
        }
    
        if (!wasSealed) {
            // Persist the fact that we've sealed ourselves to prevent
            // mutations of any hard links we create. We do this without holding
            // the session lock, since otherwise it's a lock inversion.
            mCallback.onSessionSealedBlocking(this);
        }
    }
  • PackageInstallerSession.commitLocked()

     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
    
    private void commitLocked()
        throws PackageManagerException {
        // ...... 一些检查工作
    
        // Inherit any packages and native libraries from existing install that
        // haven't been overridden.
        if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
            // ...... 安装包继承已经安装的应用,进行一些库文件拷贝
        }
    
        // TODO: surface more granular state from dexopt
        mInternalProgress = 0.5f;
        computeProgressLocked(true);
    
        // Unpack native libraries
        // 解压本地库文件
        extractNativeLibraries(mResolvedStageDir, params.abiOverride, mayInheritNativeLibs());
    
        // We've reached point of no return; call into PMS to install the stage.
        // Regardless of success or failure we always destroy session.
        // 观察者,监听安装结果
        final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
                @Override
                public void onUserActionRequired(Intent intent) {
                    throw new IllegalStateException();
                }
    
                @Override
                public void onPackageInstalled(String basePackageName, int returnCode, String msg,
                                               Bundle extras) {
                    destroyInternal();
                    dispatchSessionFinished(returnCode, msg, extras);
                }
            };
    
        final UserHandle user;
        if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
            user = UserHandle.ALL;
        } else {
            user = new UserHandle(userId);
        }
    
        mRelinquished = true;
        // 提交给  PackageManagerService 进行下一步安装工作
        mPm.installStage(mPackageName, stageDir, localObserver, params,
                         mInstallerPackageName, mInstallerUid, user, mSigningDetails);
    }

PackageManagerService.class

installStage()

 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
void installStage(String packageName, File stagedDir,
                  IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
                  String installerPackageName, int installerUid, UserHandle user,
                  PackageParser.SigningDetails signingDetails) {
    // 从名字就知道用于储存验证信息,其实主要就是这四个构造注入的对象
    final VerificationInfo verificationInfo = new VerificationInfo(
                                                                   sessionParams.originatingUri, sessionParams.referrerUri,
                                                                   sessionParams.originatingUid, installerUid);
    // 主要储存应用包来源信息,即开始安装时存储的位置
    final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
    // 新建消息
    final Message msg = mHandler.obtainMessage(INIT_COPY);
    // 修正  SessionParams.installReason 参数
    final int installReason = fixUpInstallReason(installerPackageName, installerUid,
                                                 sessionParams.installReason);
    // 准备安装参数
    final InstallParams params = new InstallParams(origin, null, observer,
                                                   sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
                                                   verificationInfo, user, sessionParams.abiOverride,
                                                   sessionParams.grantedRuntimePermissions, signingDetails, installReason);
    params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
    msg.obj = params;

    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
                          System.identityHashCode(msg.obj));
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                          System.identityHashCode(msg.obj));
    // 发送消息
    mHandler.sendMessage(msg);
}

PackageHandler.handleMessage()

  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
class PackageHandler extends Handler {
    // 标识是否绑定服务
    private boolean mBound = false;
    final ArrayList<HandlerParams> mPendingInstalls =
        new ArrayList<HandlerParams>();
    // 连接服务
    private boolean connectToService() {
        Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
        Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
        if (mContext.bindServiceAsUser(service, mDefContainerConn,
                                       Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            mBound = true;
            return true;
        }
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        return false;
    }
    // 断开与服务的连接
    private void disconnectService() {
        mContainerService = null;
        mBound = false;
        Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
        mContext.unbindService(mDefContainerConn);
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    }

    PackageHandler(Looper looper) {
        super(looper);
    }

    public void handleMessage(Message msg) {
        try {
            doHandleMessage(msg);
        } finally {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        }
    }
    void doHandleMessage(Message msg) {
        switch (msg.what) {
            // ......
        case INIT_COPY: {
            HandlerParams params = (HandlerParams) msg.obj;
            // 挂起等待安装的计数
            int idx = mPendingInstalls.size();
            // If a bind was already initiated we dont really
            // need to do anything. The pending install
            // will be processed later on.
            if (!mBound) {
                // 服务处于断开状态,则绑定服务
                // If this is the only one pending we might
                // have to bind to the service again.
                if (!connectToService()) {
                    // 绑定失败
                    return;
                } else {
                    // Once we bind to the service, the first
                    // pending request will be processed.
                    // 绑定服务成功,将当前请求加入队列等待处理
                    // 服务绑定成功后会发送  MCS_BOUND 消息
                    mPendingInstalls.add(idx, params);
                }
            } else {
                // 如果处于绑定状态,则把当前请求加入等待队列
                mPendingInstalls.add(idx, params);
                // Already bound to the service. Just make
                // sure we trigger off processing the first request.
                if (idx == 0) {
                    // 如果之前队列为空,则当前为第一个,那么处理当前请求
                    mHandler.sendEmptyMessage(MCS_BOUND);
                }
            }
            break;
        }
        case MCS_BOUND: {
            if (msg.obj != null) {
                mContainerService = (IMediaContainerService) msg.obj;
            }
            if (mContainerService == null) {
                if (!mBound) {
                    // Something seriously wrong since we are not bound and we are not
                    // waiting for connection. Bail out.
                    // 这里服务应该是绑定状态的,但现在发生严重错误导致服务处于断开状态
                    // 输出报错信息并清理
                    for (HandlerParams params : mPendingInstalls) {
                        // Indicate service bind error
                        params.serviceError();
                    }
                    mPendingInstalls.clear();
                } else {
                }
            } else if (mPendingInstalls.size() > 0) {
                // 获取下一个待处理请求
                HandlerParams params = mPendingInstalls.get(0);
                if (params != null) {
                    // 调用了  startCopy() 方法,下面分析
                    if (params.startCopy()) {
                        // We are done...  look for more work or to
                        // go idle.
                        // Delete pending install
                        if (mPendingInstalls.size() > 0) {
                            // 移除当前处理的请求
                            mPendingInstalls.remove(0);
                        }
                        if (mPendingInstalls.size() == 0) {
                            // 处理完所有请求,断开服务
                            if (mBound) {
                                removeMessages(MCS_UNBIND);
                                Message ubmsg = obtainMessage(MCS_UNBIND);
                                // Unbind after a little delay, to avoid
                                // continual thrashing.
                                sendMessageDelayed(ubmsg, 10000);
                            }
                        } else {
                            // There are more pending requests in queue.
                            // Just post MCS_BOUND message to trigger processing
                            // of next pending install.
                            // 继续处理下一个请求
                            mHandler.sendEmptyMessage(MCS_BOUND);
                        }
                    }
                }
            } else {
                // Should never happen ideally.
            }
            break;
        }
            // .....
        }

HandlerParams.startCopy()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
final boolean startCopy() {
    boolean res;
    try {
        if (++mRetries > MAX_RETRIES) {
            // 重试超过  4 次
            mHandler.sendEmptyMessage(MCS_GIVE_UP);
            handleServiceError();
            return false;
        } else {
            // 执行拷贝
            handleStartCopy();
            res = true;
        }
    } catch (RemoteException e) {
        mHandler.sendEmptyMessage(MCS_RECONNECT);
        res = false;
    }
    // 处理结果
    handleReturnCode();
    return res;
}

handleStartCopy()

获取安装包信息和安装位置,根据默认策略改变安装位置并生成安装参数

  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
public void handleStartCopy() throws RemoteException {
    int ret = PackageManager.INSTALL_SUCCEEDED;

    // If we're already staged, we've firmly committed to an install location
    if (origin.staged) {
        if (origin.file != null) {
            // 安装到内置存储
            installFlags |= PackageManager.INSTALL_INTERNAL;
            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
        } else {
            throw new IllegalStateException("Invalid stage location");
        }
    }
    // 是否安装到内置存储
    final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
    // 是否安装到外置存储
    final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
    // 是否是及时应用
    final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
    PackageInfoLite pkgLite = null;

    if (onInt && onSd) {
        // Check if both bits are set.
        // 无法确定安装位置
        ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
    } else if (onSd && ephemeral) {
        // 及时应用不能安装到外置存储
        ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
    } else {
        // 其实还是调用  PackageParser.parsePackageLite(packageFile, 0);
        // * 获取应用包的基本信息,并生成建议安装位置
        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
                                                          packageAbiOverride);
        /*
         * If we have too little free space, try to free cache
         * before giving up.
         */
        // 如果空间不足,先清理缓存,再重新尝试
        // recommendedInstallLocation 记录了建议安装的位置
        if (!origin.staged && pkgLite.recommendedInstallLocation
            == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
            // TODO: focus freeing disk space on the target device
            final StorageManager storage = StorageManager.from(mContext);
            // 获取内部存储最小保留空间
            final long lowThreshold = storage.getStorageLowBytes(
                                                                 Environment.getDataDirectory());
            // 获取应用包安装占用空间
            final long sizeBytes = mContainerService.calculateInstalledSize(
                                                                            origin.resolvedPath, packageAbiOverride);

            try {
                // 是否缓存
                mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
                // 重新判断是否有建议安装的位置
                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
                                                                  installFlags, packageAbiOverride);

                /*
                 * The cache free must have deleted the file we
                 * downloaded to install.
                 *
                 * TODO: fix the "freeCache" call to not delete
                 *       the file we care about.
                 */
                if (pkgLite.recommendedInstallLocation
                    == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
                    // 清理缓存后还是无法安装
                    pkgLite.recommendedInstallLocation
                        = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
                }
            }
        }

        if (ret == PackageManager.INSTALL_SUCCEEDED) {
            int loc = pkgLite.recommendedInstallLocation;
            if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
            } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
                ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
            } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
                ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
            } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
                ret = PackageManager.INSTALL_FAILED_INVALID_APK;
            } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
                ret = PackageManager.INSTALL_FAILED_INVALID_URI;
            } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
                ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
            } else {
                // Override with defaults if needed.
                // * 根据是否已经安装该应用来调整安装位置
                loc = installLocationPolicy(pkgLite);
                if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
                    ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
                } else if (!onSd && !onInt) {
                    // Override install location with flags
                    if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
                        // Set the flag to install on external media.
                        // 设为安装在外置存储
                        installFlags |= PackageManager.INSTALL_EXTERNAL;
                        installFlags &= ~PackageManager.INSTALL_INTERNAL;
                    } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
                        // 及时应用安装在内置存储
                        installFlags |= PackageManager.INSTALL_INSTANT_APP;
                        installFlags &= ~(PackageManager.INSTALL_EXTERNAL
                                          |PackageManager.INSTALL_INTERNAL);
                    } else {
                        // Make sure the flag for installing on external
                        // media is unset
                        // 默认安装在内置存储
                        installFlags |= PackageManager.INSTALL_INTERNAL;
                        installFlags &= ~PackageManager.INSTALL_EXTERNAL;
                    }
                }
            }
        }
        // 生成安装参数
        final InstallArgs args = createInstallArgs(this);
        mArgs = args;

        if (ret == PackageManager.INSTALL_SUCCEEDED) {
            // TODO: http://b/22976637
            // Apps installed for "all" users use the device owner to verify the app
            UserHandle verifierUser = getUser();
            if (verifierUser == UserHandle.ALL) {
                verifierUser = UserHandle.SYSTEM;
            }

            /*
             * Determine if we have any installed package verifiers. If we
             * do, then we'll defer to them to verify the packages.
             */
            final int requiredUid = mRequiredVerifierPackage == null ? -1
                : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
                                verifierUser.getIdentifier());
            final int installerUid =
                verificationInfo == null ? -1 : verificationInfo.installerUid;
            if (!origin.existing && requiredUid != -1
                // ...... 将包信息发给包验证应用进行验证
                } else {
                    /*
                     * No package verification is enabled, so immediately start
                     * the remote call to initiate copy using temporary file.
                     */
                    // * 没有包验证应用,进行安装下一步操作
                    ret = args.copyApk(mContainerService, true);
                }
        }

        mRet = ret;
    }
  • IMediaContainerService.getMinimalPackageInfo()

    远程调用 DefaultContainerService.mBinder.getMinimalPackageInfo()

     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
    
    public PackageInfoLite getMinimalPackageInfo(String packagePath, int flags,
                                                 String abiOverride) {
        final Context context = DefaultContainerService.this;
    
        PackageInfoLite ret = new PackageInfoLite();
        if (packagePath == null) {
            ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
            return ret;
        }
    
        final File packageFile = new File(packagePath);
        final PackageParser.PackageLite pkg;
        final long sizeBytes;
        try {
            // 解析得到  PackageInfoLite
            pkg = PackageParser.parsePackageLite(packageFile, 0);
            // 计算安装所需空间
            sizeBytes = PackageHelper.calculateInstalledSize(pkg, abiOverride);
        } catch (PackageParserException | IOException e) {
            if (!packageFile.exists()) {
                ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
            } else {
                ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
            }
            return ret;
        }
    
        final int recommendedInstallLocation;
        final long token = Binder.clearCallingIdentity();
        try {
            // 确定建议安装位置
            recommendedInstallLocation = PackageHelper.resolveInstallLocation(context,
                                                                              pkg.packageName, pkg.installLocation, sizeBytes, flags);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    
        ret.packageName = pkg.packageName;
        ret.splitNames = pkg.splitNames;
        ret.versionCode = pkg.versionCode;
        ret.versionCodeMajor = pkg.versionCodeMajor;
        ret.baseRevisionCode = pkg.baseRevisionCode;
        ret.splitRevisionCodes = pkg.splitRevisionCodes;
        ret.installLocation = pkg.installLocation;
        ret.verifiers = pkg.verifiers;
        ret.recommendedInstallLocation = recommendedInstallLocation;
        ret.multiArch = pkg.multiArch;
    
        return ret;
    }
  • PackageHelper.resolveInstallLocation()

      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
    
    public static int resolveInstallLocation(Context context, String packageName,
                                             int installLocation, long sizeBytes, int installFlags) {
        final SessionParams params = new SessionParams(SessionParams.MODE_INVALID);
        params.appPackageName = packageName;
        params.installLocation = installLocation;
        params.sizeBytes = sizeBytes;
        params.installFlags = installFlags;
        try {
            return resolveInstallLocation(context, params);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }
    public static int resolveInstallLocation(Context context, SessionParams params)
        throws IOException {
        ApplicationInfo existingInfo = null;
        try {
            // 根据包名获取应用信息;如果以前有安装过该应用否则为空
            existingInfo = context.getPackageManager().getApplicationInfo(params.appPackageName,
                                                                          PackageManager.MATCH_ANY_USER);
        } catch (NameNotFoundException ignored) {
        }
    
        final int prefer;
        final boolean checkBoth;
        boolean ephemeral = false;
        if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
            // 及时应用
            prefer = RECOMMEND_INSTALL_INTERNAL;
            ephemeral = true;
            checkBoth = false;
        } else if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
            // 要求安装在内置存储
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = false;
        } else if ((params.installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
            // 要求安装在内置存储
            prefer = RECOMMEND_INSTALL_EXTERNAL;
            checkBoth = false;
        } else if (params.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
            // 要求只能安装在内置存储
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = false;
        } else if (params.installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
            // 要求优先安装在外置存储
            prefer = RECOMMEND_INSTALL_EXTERNAL;
            checkBoth = true;
        } else if (params.installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
            // 没有指定具体位置,由系统自己决定
            // When app is already installed, prefer same medium
            // 如果安装过该应用,用上次安装的位置
            if (existingInfo != null) {
                // TODO: distinguish if this is external ASEC
                if ((existingInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
                    prefer = RECOMMEND_INSTALL_EXTERNAL;
                } else {
                    prefer = RECOMMEND_INSTALL_INTERNAL;
                }
            } else {
                // 默认安装到内置存储
                prefer = RECOMMEND_INSTALL_INTERNAL;
            }
            checkBoth = true;
        } else {
            // 默认安装到内置存储
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = false;
        }
        // 判断是否优先安装到内置存储,没有唯一指定安装位置则:checkBoth=true
        boolean fitsOnInternal = false;
        if (checkBoth || prefer == RECOMMEND_INSTALL_INTERNAL) {
            fitsOnInternal = fitsOnInternal(context, params);
        }
        // 判断是否优先安装到位置存储
        boolean fitsOnExternal = false;
        if (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL) {
            fitsOnExternal = fitsOnExternal(context, params);
        }
        if (prefer == RECOMMEND_INSTALL_INTERNAL) {
            // The ephemeral case will either fit and return EPHEMERAL, or will not fit
            // and will fall through to return INSUFFICIENT_STORAGE
            if (fitsOnInternal) {
                // 决定安装到内置存储
                return (ephemeral)
                    ? PackageHelper.RECOMMEND_INSTALL_EPHEMERAL
                    : PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            }
        } else if (prefer == RECOMMEND_INSTALL_EXTERNAL) {
            if (fitsOnExternal) {
                // 决定安装到外置存储
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
        }
        if (checkBoth) {
            if (fitsOnInternal) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            } else if (fitsOnExternal) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
        }
        // 找不到适合安装的位置
        return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
    }
  • installLocationPolicy()

      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
    
    private int installLocationPolicy(PackageInfoLite pkgLite) {
        String packageName = pkgLite.packageName;
        int installLocation = pkgLite.installLocation;
        boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
        // reader
        synchronized (mPackages) {
            // Currently installed package which the new package is attempting to replace or
            // null if no such package is installed.
            // 根据包名获取应用信息,如果之前没有安装过为空
            PackageParser.Package installedPkg = mPackages.get(packageName);
            // Package which currently owns the data which the new package will own if installed.
            // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
            // will be null whereas dataOwnerPkg will contain information about the package
            // which was uninstalled while keeping its data.
            PackageParser.Package dataOwnerPkg = installedPkg;
            if (dataOwnerPkg  == null) {
                PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null) {
                    // 之前有安装过但是已经卸载却保留了数据
                    dataOwnerPkg = ps.pkg;
                }
            }
    
            if (dataOwnerPkg != null) {
                // If installed, the package will get access to data left on the device by its
                // predecessor. As a security measure, this is permited only if this is not a
                // version downgrade or if the predecessor package is marked as debuggable and
                // a downgrade is explicitly requested.
                //
                // On debuggable platform builds, downgrades are permitted even for
                // non-debuggable packages to make testing easier. Debuggable platform builds do
                // not offer security guarantees and thus it's OK to disable some security
                // mechanisms to make debugging/testing easier on those builds. However, even on
                // debuggable builds downgrades of packages are permitted only if requested via
                // installFlags. This is because we aim to keep the behavior of debuggable
                // platform builds as close as possible to the behavior of non-debuggable
                // platform builds.
                // 是否是降级安装,安装比已有版本低的版本
                final boolean downgradeRequested =
                    (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
                // 当前是否是调试模式
                final boolean packageDebuggable =
                    (dataOwnerPkg.applicationInfo.flags
                     & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                // 判断是否允许降级安装
                final boolean downgradePermitted =
                    (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
                if (!downgradePermitted) {
                    try {
                        // 检查是否是降级安装
                        checkDowngrade(dataOwnerPkg, pkgLite);
                    } catch (PackageManagerException e) {
                        Slog.w(TAG, "Downgrade detected: " + e.getMessage());
                        return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
                    }
                }
            }
    
            if (installedPkg != null) {
                // 应用已经安装过
                if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
                    // Check for updated system application.
                    if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                        // 升级系统应用
                        if (onSd) {
                            // 允许安装在外置存储
                            return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
                        }
                        return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
                    } else {
                        if (onSd) {
                            // Install flag overrides everything.
                            // 要求安装到外置存储
                            return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
                        }
                        // If current upgrade specifies particular preference
                        if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
                            // 要求只能安装在内置存储
                            // Application explicitly specified internal.
                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
                        } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
                            // 优先安装到外置存储
                            // App explictly prefers external. Let policy decide
                        } else {
                            // 未指定安装位置
                            // Prefer previous location
                            if (isExternal(installedPkg)) {
                                // 使用上次应用安装的位置
                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
                            }
                            // 默认安装到内置存储
                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
                        }
                    }
                } else {
                    // Invalid install. Return error code
                    return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
                }
            }
        }
        // All the special cases have been taken care of.
        // Return result based on recommended install location.
        if (onSd) {
            return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
        }
        return pkgLite.recommendedInstallLocation;
    }
  • createInstallArgs()

     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
    
    private InstallArgs createInstallArgs(InstallParams params) {
        if (params.move != null) {
            // 移动应用
            return new MoveInstallArgs(params);
        } else {
            // 正常安装
            return new FileInstallArgs(params);
        }
    }
    
    int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
        try {
            return doCopyApk(imcs, temp);
        } finally {
        }
    }
    
    private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
        // 在我们当前分析的安装流程中  staged=true 因为在  PackageInstallerSession 中已经进行了拷贝
        if (origin.staged) {
            codeFile = origin.file;
            resourceFile = origin.file;
            return PackageManager.INSTALL_SUCCEEDED;
        }
        // ...... 其它方式安装的拷贝动作
    }

handleReturnCode()

 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
void handleReturnCode() {
    // If mArgs is null, then MCS couldn't be reached. When it
    // reconnects, it will try again to install. At that point, this
    // will succeed.
    if (mArgs != null) {
        processPendingInstall(mArgs, mRet);
    }
}

private void processPendingInstall(final InstallArgs args, final int currentStatus) {
    // Queue up an async operation since the package installation may take a little while.
    mHandler.post(new Runnable() {
            public void run() {
                mHandler.removeCallbacks(this);
                // Result object to be returned
                PackageInstalledInfo res = new PackageInstalledInfo();
                res.setReturnCode(currentStatus);
                res.uid = -1;
                res.pkg = null;
                res.removedInfo = null;
                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                    // 主要是上一步安装失败进行清理工作
                    args.doPreInstall(res.returnCode);
                    synchronized (mInstallLock) {
                        installPackageTracedLI(args, res);
                    }
                    // 主要是上一步安装失败进行清理工作
                    args.doPostInstall(res.returnCode, res.uid);
                }

                // A restore should be performed at this point if (a) the install
                // succeeded, (b) the operation is not an update, and (c) the new
                // package has not opted out of backup participation.
                // 是否是升级
                final boolean update = res.removedInfo != null
                    && res.removedInfo.removedPackage != null;
                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
                // 是否需要恢复
                boolean doRestore = !update
                    && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);

                // Set up the post-install work request bookkeeping.  This will be used
                // and cleaned up by the post-install event handling regardless of whether
                // there's a restore pass performed.  Token values are >= 1.
                int token;
                if (mNextInstallToken < 0) mNextInstallToken = 1;
                token = mNextInstallToken++;

                PostInstallData data = new PostInstallData(args, res);
                mRunningInstalls.put(token, data);
                // 恢复相关工作
                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
                    // Pass responsibility to the Backup Manager.  It will perform a
                    // restore if appropriate, then pass responsibility back to the
                    // Package Manager to run the post-install observer callbacks
                    // and broadcasts.
                    IBackupManager bm = IBackupManager.Stub.asInterface(
                                                                        ServiceManager.getService(Context.BACKUP_SERVICE));
                    if (bm != null) {
                        try {
                            // TODO: http://b/22388012
                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
                            } else {
                                doRestore = false;
                            }
                        } catch (RemoteException e) {
                            // can't happen; the backup manager is local
                        } catch (Exception e) {
                            doRestore = false;
                        }
                    } else {
                        doRestore = false;
                    }
                }
                if (!doRestore) {
                    // No restore possible, or the Backup Manager was mysteriously not
                    // available -- just fire the post-install work request directly.
                    // 发送安装成功消息
                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
                    mHandler.sendMessage(msg);
                }
            }
        });
}
  • installPackageTracedLI()

      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
    
    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
        try {
            installPackageLI(args, res);
        } finally {
        }
    }
    
    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
        // ...... 变量初始化
        // Result object to be returned
        // 要返回的结果对象
        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
        res.installerPackageName = installerPackageName;
        // Sanity check
        // 完整性检查,及时应用只能安装在内置存储
        if (instantApp && (forwardLocked || onExternal)) {
            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
            return;
        }
        // Retrieve PackageSettings and parse package
        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
            | PackageParser.PARSE_ENFORCE_CODE
            | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
            | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
            | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
        PackageParser pp = new PackageParser();
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setDisplayMetrics(mMetrics);
        pp.setCallback(mPackageParserCallback);
        final PackageParser.Package pkg;
        try {
            // 解析  apk 文件得到  PackageParser.Package 对象
            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
            DexMetadataHelper.validatePackageDexMetadata(pkg);
        } catch (PackageParserException e) {
            res.setError("Failed parse during installPackageLI", e);
            return;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    
        // Instant apps have several additional install-time checks.
        // 检查是否支持及时应用
        if (instantApp) {
            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
                             "Instant app package must target at least O");
                return;
            }
            if (pkg.applicationInfo.targetSandboxVersion != 2) {
                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
                             "Instant app package must use targetSandboxVersion 2");
                return;
            }
            if (pkg.mSharedUserId != null) {
                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
                             "Instant app package may not declare a sharedUserId");
                return;
            }
        }
    
        if (pkg.applicationInfo.isStaticSharedLibrary()) {
            // Static shared libraries have synthetic package names
            renameStaticSharedLibraryPackage(pkg);
    
            // No static shared libs on external storage
            if (onExternal) {
                // 共享库不允许安装在外置存储
                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                             "Packages declaring static-shared libs cannot be updated");
                return;
            }
        }
    
        // If we are installing a clustered package add results for the children
        if (pkg.childPackages != null) {
            // 处理子包
            synchronized (mPackages) {
                final int childCount = pkg.childPackages.size();
                for (int i = 0; i < childCount; i++) {
                    PackageParser.Package childPkg = pkg.childPackages.get(i);
                    PackageInstalledInfo childRes = new PackageInstalledInfo();
                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                    childRes.pkg = childPkg;
                    childRes.name = childPkg.packageName;
                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
                    if (childPs != null) {
                        childRes.origUsers = childPs.queryInstalledUsers(
                                                                         sUserManager.getUserIds(), true);
                    }
                    if ((mPackages.containsKey(childPkg.packageName))) {
                        childRes.removedInfo = new PackageRemovedInfo(this);
                        childRes.removedInfo.removedPackage = childPkg.packageName;
                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
                    }
                    if (res.addedChildPackages == null) {
                        res.addedChildPackages = new ArrayMap<>();
                    }
                    res.addedChildPackages.put(childPkg.packageName, childRes);
                }
            }
        }
    
        // If package doesn't declare API override, mark that we have an install
        // time CPU ABI override.
        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
            pkg.cpuAbiOverride = args.abiOverride;
        }
        String pkgName = res.name = pkg.packageName;
        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
                return;
            }
        }
        // 获取签名信息
        try {
            // either use what we've been given or parse directly from the APK
            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
                pkg.setSigningDetails(args.signingDetails);
            } else {
                PackageParser.collectCertificates(pkg, false /* skipVerify */);
            }
        } catch (PackageParserException e) {
            res.setError("Failed collect during installPackageLI", e);
            return;
        }
        // 检查签名版本
        if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
            < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
                         "Instant app package must be signed with APK Signature Scheme v2 or greater");
            return;
        }
    
        // Get rid of all references to package scan path via parser.
        // ...... 检查是否要替换现有包
        pp = null;
        String oldCodePath = null;
        boolean systemApp = false;
        synchronized (mPackages) {
            // Check if installing already existing package
        }
    
        if (args.move != null) {
            // We did an in-place move, so dex is ready to roll
            // 移动应用
            scanFlags |= SCAN_NO_DEX;
            scanFlags |= SCAN_MOVE;
    
            synchronized (mPackages) {
                final PackageSetting ps = mSettings.mPackages.get(pkgName);
                if (ps == null) {
                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
                                 "Missing settings for moved package " + pkgName);
                }
    
                // We moved the entire application as-is, so bring over the
                // previously derived ABI information.
                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
            }
    
        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
            scanFlags |= SCAN_NO_DEX;
    
            try {
                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
                                      args.abiOverride : pkg.cpuAbiOverride);
                final boolean extractNativeLibs = !pkg.isLibrary();
                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
            } catch (PackageManagerException pme) {
                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
                return;
            }
    
            // Shared libraries for the package need to be updated.
            synchronized (mPackages) {
                try {
                    updateSharedLibrariesLPr(pkg, null);
                } catch (PackageManagerException e) {
                }
            }
        }
        // 重命名安装包路径名,使用拷贝后的
        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
            return;
        }
    
        if (PackageManagerServiceUtils.isApkVerityEnabled()) {
            // 安装验证相关
        }
    
        if (!instantApp) {
            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
        } else {
        }
    
        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
                                                              "installPackageLI")) {
            if (replace) {
                if (pkg.applicationInfo.isStaticSharedLibrary()) {
                    // Static libs have a synthetic package name containing the version
                    // and cannot be updated as an update would get a new package name,
                    // unless this is the exact same version code which is useful for
                    // development.
                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
                    if (existingPkg != null &&
                        existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
                                     + "static-shared libs cannot be updated");
                        return;
                    }
                }
                // 用新的应用信息替换旧的
                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
                                  installerPackageName, res, args.installReason);
            } else {
                // 将新应用信息加入到  PackageManagerService
                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
                                     args.user, installerPackageName, volumeUuid, res, args.installReason);
            }
        }
    
        // Prepare the application profiles for the new code paths.
        // This needs to be done before invoking dexopt so that any install-time profile
        // can be used for optimizations.
        // 为新代码路径准备应用程序配置文件。 这需要在调用  dexopt 之前完成,以便任何安装时配置文件都可以用于优化。
        mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
        // ......  dexopt 相关操作
        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
    
        synchronized (mPackages) {
            final PackageSetting ps = mSettings.mPackages.get(pkgName);
            if (ps != null) {
                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
                ps.setUpdateAvailable(false /*updateAvailable*/);
            }
    
            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
            for (int i = 0; i < childCount; i++) {
                PackageParser.Package childPkg = pkg.childPackages.get(i);
                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
                if (childPs != null) {
                    childRes.newUsers = childPs.queryInstalledUsers(
                                                                    sUserManager.getUserIds(), true);
                }
            }
    
            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                updateSequenceNumberLP(ps, res.newUsers);
                updateInstantAppInstallerLocked(pkgName);
            }
        }
    }