【Android源码】应用安装过程分析

源码研读

Posted by Corax on July 2, 2024

首先我打算把Android应用安装流程作为第一个专题,也没啥别的原因,因为我看书这部分之前看的最潦草。

本篇参考资料
《Android系统源代码情景分析》
《Android进阶解密》
https://david1840.github.io/2021/03/24/Android%E5%8C%85%E7%AE%A1%E7%90%86%E6%9C%BA%E5%88%B6-%E4%B8%89-PMS%E5%A4%84%E7%90%86APK%E5%AE%89%E8%A3%85/#4-%E5%AE%89%E8%A3%85APK

总览

因为涉及的函数还是比较多的,散落在不同的文件里,所以这个总览可以帮助形成结构性的知识网图,以此不断丰富来加强认识,也可以后续回顾以这个结构来复习。

-PMS服务的启动
--开始阶段,系统扫描阶段,DATA扫描阶段,扫描结束阶段,准备阶段
-APK的安装
--应用安装程序
---PackageInstallActivity
---InstallAppProcess
---PackageSession 发送给PMS请求
--PMS层面处理安装请求
---两次doHandlerMessage
---startcopy
----handlestartcopy
-----doCopyApk做先导工作
----handleReturnCode
-----三个阶段 其中的installPackageTracedLI
------installNewPackageLIF
-------三个函数

PMS服务的启动

删掉了一些 重点关注这个startBootstrapServices

D:\android-7.0.0_r1\frameworks\base\services\java\com\android\server\SystemServer.java   
   private void run() {


        // Start services.
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

来到PackageManagerService的main

D:\android-7.0.0_r1\frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java   
   public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        PackageManagerServiceCompilerMapping.checkProperties();

        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        m.enableSystemUserPackages();
        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
        // disabled after already being started.
        CarrierAppUtils.disableCarrierAppsUntilPrivileged(context.getOpPackageName(), m,
                UserHandle.USER_SYSTEM);
        ServiceManager.addService("package", m);
        return m;
    }

可以看到上面new了一个对象 来到构造函数,这个构造函数很长 600多行

我们把它划分为五个阶段

开始阶段

public PackageManagerService(Context context, Installer installer,
         boolean factoryTest, boolean onlyCore) {
     //打印开始日志
     EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
             SystemClock.uptimeMillis());

     if (mSdkVersion <= 0) {
         Slog.w(TAG, "**** ro.build.version.sdk not set!");
     }

     mContext = context;

     mPermissionReviewRequired = context.getResources().getBoolean(
             R.bool.config_permissionReviewRequired);

     mFactoryTest = factoryTest;
     mOnlyCore = onlyCore;
     //用于存储屏幕的相关信息
     mMetrics = new DisplayMetrics();
     //创建Settings对象 (1)
     mSettings = new Settings(mPackages);
     // 添加system, phone, log, nfc, bluetooth, shell这六种shareUserId到mSettings;
     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);
  
  
  		......

     mInstaller = installer;
     //创建Dex优化工具类
     mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
             "*dexopt*");
     mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());

     mOnPermissionChangeListeners = new OnPermissionChangeListeners(
             FgThread.get().getLooper());

     getDefaultDisplayMetrics(context, mMetrics);
     //得到全局系统配置信息
     SystemConfig systemConfig = SystemConfig.getInstance();
  		//获取全局的groupId 
     mGlobalGids = systemConfig.getGlobalGids();
  		//获取系统权限
     mSystemPermissions = systemConfig.getSystemPermissions();
     mAvailableFeatures = systemConfig.getAvailableFeatures();

     mProtectedPackages = new ProtectedPackages(mContext);

     //安装APK时需要的锁,保护所有对installd的访问。
     synchronized (mInstallLock) {
     //更新APK时需要的锁,保护内存中已经解析的包信息等内容
     synchronized (mPackages) {
         //创建后台线程ServiceThread
         mHandlerThread = new ServiceThread(TAG,
                 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
         mHandlerThread.start();
         //创建PackageHandler绑定到ServiceThread的消息队列
         mHandler = new PackageHandler(mHandlerThread.getLooper());
         mProcessLoggingHandler = new ProcessLoggingHandler();
         //将PackageHandler添加到Watchdog的检测集中
         Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);

         mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
				
         //在Data分区创建一些目录
         File dataDir = Environment.getDataDirectory();
         mAppInstallDir = new File(dataDir, "app");
         mAppLib32InstallDir = new File(dataDir, "app-lib");
         mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
         mAsecInternalPath = new File(dataDir, "app-asec").getPath();
         mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
         mRegionalizationAppInstallDir = new File(dataDir, "app-regional");

         //创建多用户管理服务
         sUserManager = new UserManagerService(context, this, mPackages);

         mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
					
       	//解析packages.xml等文件的信息,保存到Settings的对应字段中。packages.xml中记录系统中所有安装的应用信息,包括基本信息、签名和权限。如果packages.xml有安装的应用信息,readLPw方法会返回true,mFirstBoot的值为false,说明PMS不是首次被启动。
         mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));

扫描系统阶段

  1. 创建system子目录
  2. 扫描系统文件
//打印扫描系统阶段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);

// Set flag to monitor and not change apk file paths when
// scanning install directories.
final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;

final String bootClassPath = System.getenv("BOOTCLASSPATH");
final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");

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

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

final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
final String[] dexCodeInstructionSets =
  getDexCodeInstructionSets(
  allInstructionSets.toArray(new String[allInstructionSets.size()]));

/**
             * Ensure all external libraries have had dexopt run on them.
             */
if (mSharedLibraries.size() > 0) {
  // NOTE: For now, we're compiling these system "shared libraries"
  // (and framework jars) into all available architectures. It's possible
  // to compile them only when we come across an app that uses them (there's
  // already logic for that in scanPackageLI) but that adds some complexity.
  for (String dexCodeInstructionSet : dexCodeInstructionSets) {
    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
      final String lib = libEntry.path;
      if (lib == null) {
        continue;
      }

      try {
        // Shared libraries do not have profiles so we perform a full
        // AOT compilation (if needed).
        int dexoptNeeded = DexFile.getDexOptNeeded(
          lib, dexCodeInstructionSet,
          getCompilerFilterForReason(REASON_SHARED_APK),
          false /* newProfile */);
        if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
          mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
                            dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
                            getCompilerFilterForReason(REASON_SHARED_APK),
                            StorageManager.UUID_PRIVATE_INTERNAL,
                            SKIP_SHARED_LIBRARY_CHECK);
        }
      } catch (FileNotFoundException e) {
        Slog.w(TAG, "Library not found: " + lib);
      } catch (IOException | InstallerException e) {
        Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
               + e.getMessage());
      }
    }
  }
}

//在/system中创建framework目录
File frameworkDir = new File(Environment.getRootDirectory(), "framework");

final VersionInfo ver = mSettings.getInternalVersion();
mIsUpgrade = !Build.FINGERPRINT.equals(ver.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);
    }
  }
}

// Collect vendor 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.
String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY);
 //扫描/vendor/overlay目录下的文件
if (!overlayThemeDir.isEmpty()) {
  scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags
                  | PackageParser.PARSE_IS_SYSTEM
                  | PackageParser.PARSE_IS_SYSTEM_DIR
                  | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
}
scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR
                | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);

// Find base frameworks (resource packages without code).
//收集包名:/system/framework
scanDirTracedLI(frameworkDir, mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR
                | PackageParser.PARSE_IS_PRIVILEGED,
                scanFlags | SCAN_NO_DEX, 0);

// Collected privileged system packages.
//收集私有的系统包名:/system/priv-app
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirTracedLI(privilegedAppDir, mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR
                | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);

// Collect ordinary system packages.
//收集一般的系统包名:/system/app
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirTracedLI(systemAppDir, mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

// Collect all vendor packages.
//收集所有的供应商包名:/vendor/app
File vendorAppDir = new File("/vendor/app");
try {
  vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
  // failed to look up canonical path, continue with original one
}
scanDirTracedLI(vendorAppDir, mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

// Collect all OEM packages.
//收集所有OEM包名:/oem/app
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
scanDirTracedLI(oemAppDir, mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

// Collect all Regionalization packages form Carrier's res packages.
if (RegionalizationEnvironment.isSupported()) {
  Log.d(TAG, "Load Regionalization vendor apks");
  final List<File> RegionalizationDirs =
    RegionalizationEnvironment.getAllPackageDirectories();
  for (File f : RegionalizationDirs) {
    File RegionalizationSystemDir = new File(f, "system");
    // Collect packages in <Package>/system/priv-app
    scanDirLI(new File(RegionalizationSystemDir, "priv-app"),
              PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR
              | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
    // Collect packages in <Package>/system/app
    scanDirLI(new File(RegionalizationSystemDir, "app"),
              PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR,
              scanFlags, 0);
    // Collect overlay in <Package>/system/vendor
    scanDirLI(new File(RegionalizationSystemDir, "vendor/overlay"),
              PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR,
              scanFlags | SCAN_TRUSTED_OVERLAY, 0);
  }
}

// Prune any system packages that no longer exist.
// 这个列表代表有可能有升级包的系统App
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
if (!mOnlyCore) {
  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)) {  //1
        logCriticalInfo(Log.WARN, "Expecting better updated system app for "
                        + ps.name + "; removing system app.  Last known codePath="
                        + ps.codePathString + ", installStatus=" + ps.installStatus
                        + ", versionCode=" + ps.versionCode + "; scanned versionCode="
                        + scannedPkg.mVersionCode);
        //将这个系统App的PackageSetting从PMS的mPackages中移除
        removePackageLI(scannedPkg, true);
        //将升级包的路径添加到mExpectingBetter列表中
        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 {
      final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
      //这个系统App升级包信息在mDisabledSysPackages中,但是没有发现这个升级包存在
      if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {//2
        possiblyDeletedUpdatedSystemApps.add(ps.name);
      }
    }
  }
}

//look for any incomplete package installations
//清理所有安装不完整的包
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
for (int i = 0; i < deletePkgsList.size(); i++) {
  // Actual deletion of code and data will be handled by later
  // reconciliation step
  final String packageName = deletePkgsList.get(i).name;
  logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
  synchronized (mPackages) {
    mSettings.removePackageLPw(packageName);
  }
}

//delete tmp files
//删除临时文件
deleteTempPackageFiles();

// Remove any shared userIDs that have no associated packages
mSettings.pruneSharedUsersLPw();

扫描Data分区

  1. 扫描/data/app或app-private
  2. 对已有APP进行检查
//如果设备没有加密,那么就开始扫描Data分区	
if (!mOnlyCore) {
    //打印扫描Data分区阶段日志
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
    //扫描/data/app目录下的文件 
    scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
    //扫描/data/app-private目录下的文件
    scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
                    | PackageParser.PARSE_FORWARD_LOCK,
                    scanFlags | SCAN_REQUIRE_KNOWN, 0);
    //扫描/data/app-ephemeral目录下的文件
    scanDirLI(mEphemeralInstallDir, mDefParseFlags
              | PackageParser.PARSE_IS_EPHEMERAL,
              scanFlags | SCAN_REQUIRE_KNOWN, 0);

    /**
    * Remove disable package settings for any updated system
    * apps that were removed via an OTA. If they're not a
    * previously-updated app, remove them completely.
    * Otherwise, just revoke their system-level permissions.
    * 处理possiblyDeletedUpdatedSystemApps列表
    * 
    */
    for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
      PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
      mSettings.removeDisabledSystemPackageLPw(deletedAppName);

      String msg;
      if (deletedPkg == null) {
        //1 如果这个系统App的包信息不在PMS的变量mPackages中,说明是残留的App信息,后续会删除它的数据
        msg = "Updated system package " + deletedAppName
          + " no longer exists; it's data will be wiped";
        // Actual deletion of code and data will be handled by later
        // reconciliation step
      } else {
        //2 如果这个系统App在mPackages中,说明是存在于Data分区,不属于系统App,那么移除其系统权限。
        msg = "Updated system app + " + deletedAppName
          + " no longer present; removing system privileges for "
          + deletedAppName;

        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;

        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
        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.
    */
     //遍历mExpectingBetter列表
    for (int i = 0; i < mExpectingBetter.size(); i++) {
      final String packageName = mExpectingBetter.keyAt(i);
      if (!mPackages.containsKey(packageName)) {
        //得到系统App的升级包路径
        final File scanFile = mExpectingBetter.valueAt(i);

        logCriticalInfo(Log.WARN, "Expected better " + packageName
                        + " but never showed up; reverting to system");
 
        
        //3 根据系统App所在的目录设置扫描的解析参数
        int reparseFlags = mDefParseFlags;
        if (FileUtils.contains(privilegedAppDir, scanFile)) {
          reparseFlags = PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR
            | PackageParser.PARSE_IS_PRIVILEGED;
        } else if (FileUtils.contains(systemAppDir, scanFile)) {
          reparseFlags = PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR;
        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
          reparseFlags = PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR;
        } else if (FileUtils.contains(oemAppDir, scanFile)) {
          reparseFlags = PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR;
        } else {
          Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
          continue;
        }

        //4 将packageName对应的包设置数据(PackageSetting)添加到mSettings的mPackages中
        mSettings.enableSystemPackageLPw(packageName);

        try {
          //5 扫描系统App的升级包
          scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
        } catch (PackageManagerException e) {
          Slog.e(TAG, "Failed to parse original system package: "
                 + e.getMessage());
        }
      }
    }
  }
 //清除mExpectingBetter列表
  mExpectingBetter.clear();

扫描结束阶段

  1. SDK工作
  2. setting保存到packages.xml
//打印扫描结束阶段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());

            // 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版本不一致时,需要更新权限
            int updateFlags = UPDATE_PERMISSIONS_ALL;
            if (ver.sdkVersion != mSdkVersion) {
                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                        + mSdkVersion + "; regranting permissions for internal storage");
                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
            }
            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
            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.
   					//如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选App
            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : sUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
                    applyFactoryDefaultBrowserLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }

            //在引导过程中尽早为系统用户准备存储,
            //因为核心系统应用程序,如设置Provider和SystemUI无法等待用户启动
            final int storageFlags;
            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
                storageFlags = StorageManager.FLAG_STORAGE_DE;
            } else {
                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            }
            reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
                    storageFlags);

            // 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后的第一次启动,会清除代码缓存目录
            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();

            //当权限和其他默认项都完成更新,则清理相关信息
            mExistingSystemPackages.clear();
            mPromoteSystemApps = false;

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

            // 把Settings的内容保存到packages.xml中
            mSettings.writeLPr();

准备阶段

创建好PackageInstallerService

//打印准备阶段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());

if (!mOnlyCore) {
  	mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
  	mRequiredInstallerPackage = getRequiredInstallerLPr();
    mRequiredUninstallerPackage = getRequiredUninstallerLPr();
    mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                                                    mIntentFilterVerifierComponent);
    mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
      PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
    mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
      PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
} else {
    mRequiredVerifierPackage = null;
    if (mOnlyPowerOffAlarm) {
      mRequiredInstallerPackage = getRequiredInstallerLPr();
    } else {
      mRequiredInstallerPackage = null;
    }
    mRequiredUninstallerPackage = null;
    mIntentFilterVerifierComponent = null;
    mIntentFilterVerifier = null;
    mServicesSystemSharedLibraryPackageName = null;
    mSharedSystemSharedLibraryPackageName = null;
}

//创建PackageInstallerService,用于管理安装会话的服务,它会为每次安装过程分配一个SessionId
mInstallerService = new PackageInstallerService(context, this);

//进行一次垃圾收集
untime.getRuntime().gc();

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

// 将PackageManagerInternalImpl(PackageManager的本地服务)添加到LocalServices中,LocalServices用于存储运行在当前的进程中的本地服务
LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());

APK的安装

ok,到这里我们已经成功创建好了PMS服务和一个PackageInstallerService服务

应用安装程序

其实当我们点击APK进行安装的时候,系统运行了一个应用安装程序,我们是可以看到他的activity的

image-20240719205208954

PackageInstallerActivity

可以看到是PackageInstallerActivity。

我们看看,点击之后就会startInstall 开始安装

    public void onClick(View v) {
        if (v == mOk) {
            if (mOkCanInstall || mScrollView == null) {
                if (mSessionId != -1) {
                    mInstaller.setPermissionsResult(mSessionId, true);
                    clearCachedApkIfNeededAndFinish();
                } else {
                    startInstall();
                }
            } else {
                mScrollView.pageScroll(View.FOCUS_DOWN);
            }
        } else if (v == mCancel) {
            // Cancel and finish
            setResult(RESULT_CANCELED);
            if (mSessionId != -1) {
                mInstaller.setPermissionsResult(mSessionId, false);
            }
            clearCachedApkIfNeededAndFinish();
        }
    }

接着跟,可以看到下一步用一个intent跳转到了InstallAppProgress

    private void startInstall() {
        // Start subactivity to actually install the application
        Intent newIntent = new Intent();
        newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
                mPkgInfo.applicationInfo);
        newIntent.setData(mPackageURI);
        newIntent.setClass(this, InstallAppProgress.class);
        String installerPackageName = getIntent().getStringExtra(
                Intent.EXTRA_INSTALLER_PACKAGE_NAME);
        if (mOriginatingURI != null) {
            newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI);
        }
        if (mReferrerURI != null) {
            newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
        }
        if (mOriginatingUid != VerificationParams.NO_UID) {
            newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
        }
        if (installerPackageName != null) {
            newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME,
                    installerPackageName);
        }
        if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
            newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
            newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        }
        if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
        startActivity(newIntent);
        finish();
    }

InstallAppProgress

来到InstallAppProgress这个的oncreate,里面干了两件事

  1. 开启安装线程
  2. 注册安装监听的广播
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        Intent intent = getIntent();
        mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
        mPackageURI = intent.getData();

        final String scheme = mPackageURI.getScheme();
        if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) {
            throw new IllegalArgumentException("unexpected scheme " + scheme);
        }

        mInstallThread = new HandlerThread("InstallThread");
        mInstallThread.start();
        mInstallHandler = new Handler(mInstallThread.getLooper());

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BROADCAST_ACTION);
        registerReceiver(
                mBroadcastReceiver, intentFilter, BROADCAST_SENDER_PERMISSION, null /*scheduler*/);

        initView();
    }

后续来到initView();

  1. 初步解析apk信息
  2. 执行安装 重点是dopackagestate
    void initView() {
        setContentView(R.layout.op_progress);

        final PackageUtil.AppSnippet as;
        final PackageManager pm = getPackageManager();
        final int installFlags = getInstallFlags(mAppInfo.packageName);

        if((installFlags & PackageManager.INSTALL_REPLACE_EXISTING )!= 0) {
            Log.w(TAG, "Replacing package:" + mAppInfo.packageName);
        }
        if ("package".equals(mPackageURI.getScheme())) {
            as = new PackageUtil.AppSnippet(pm.getApplicationLabel(mAppInfo),
                    pm.getApplicationIcon(mAppInfo));
        } else {
            final File sourceFile = new File(mPackageURI.getPath());
            as = PackageUtil.getAppSnippet(this, mAppInfo, sourceFile);
        }
        mLabel = as.label;
        PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
        mStatusTextView = (TextView)findViewById(R.id.center_text);
        mExplanationTextView = (TextView) findViewById(R.id.explanation);
        mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
        mProgressBar.setIndeterminate(true);
        // Hide button till progress is being displayed
        mOkPanel = findViewById(R.id.buttons_panel);
        mDoneButton = (Button)findViewById(R.id.done_button);
        mLaunchButton = (Button)findViewById(R.id.launch_button);
        mOkPanel.setVisibility(View.INVISIBLE);

        if ("package".equals(mPackageURI.getScheme())) {
            try {
                pm.installExistingPackage(mAppInfo.packageName);
                onPackageInstalled(PackageInstaller.STATUS_SUCCESS);
            } catch (PackageManager.NameNotFoundException e) {
                onPackageInstalled(PackageInstaller.STATUS_FAILURE_INVALID);
            }
        } else {
            final PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
            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);

            mInstallHandler.post(new Runnable() {
                @Override
                public void run() {
                    doPackageStage(pm, params);
                }
            });
        }
    }

来到doPackageStage

  1. 获取sessionid
  2. 获取session对象
  3. 根据session获取outputstream把文件输入流
  4. 使用session.commit
    private void doPackageStage(PackageManager pm, PackageInstaller.SessionParams params) {
        final PackageInstaller packageInstaller = pm.getPackageInstaller();
        PackageInstaller.Session session = null;
        try {
            final String packageLocation = mPackageURI.getPath();
            final File file = new File(packageLocation);
            final int sessionId = packageInstaller.createSession(params);
            final byte[] buffer = new byte[65536];

            session = packageInstaller.openSession(sessionId);

            final InputStream in = new FileInputStream(file);
            final long sizeBytes = file.length();
            final OutputStream out = session.openWrite("PackageInstaller", 0, sizeBytes);
            try {
                int c;
                while ((c = in.read(buffer)) != -1) {
                    out.write(buffer, 0, c);
                    if (sizeBytes > 0) {
                        final float fraction = ((float) c / (float) sizeBytes);
                        session.addProgress(fraction);
                    }
                }
                session.fsync(out);
            } finally {
                IoUtils.closeQuietly(in);
                IoUtils.closeQuietly(out);
            }

            // Create a PendingIntent and use it to generate the IntentSender
            Intent broadcastIntent = new Intent(BROADCAST_ACTION);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(
                    InstallAppProgress.this /*context*/,
                    sessionId,
                    broadcastIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            session.commit(pendingIntent.getIntentSender());
        } catch (IOException e) {
            onPackageInstalled(PackageInstaller.STATUS_FAILURE);
        } finally {
            IoUtils.closeQuietly(session);
        }
    }

PackageInstallerSession

后续逻辑来到session.commit 看看他干嘛了

    public void commit(IntentSender statusReceiver) {
        Preconditions.checkNotNull(statusReceiver);

        final boolean wasSealed;
        synchronized (mLock) {
            wasSealed = mSealed;
            if (!mSealed) {
                // Verify that all writers are hands-off
                for (FileBridge bridge : mBridges) {
                    if (!bridge.isClosed()) {
                        throw new SecurityException("Files still open");
                    }
                }
                mSealed = true;
            }

            // Client staging is fully done at this point
            mClientProgress = 1f;
            computeProgressLocked(true);
        }

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

        // This ongoing commit should keep session active, even though client
        // will probably close their end.
        mActiveCount.incrementAndGet();

        final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(mContext,
                statusReceiver, sessionId, mIsInstallerDeviceOwner, userId);
        mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget();
    }

可以看到上面的最后发送了一个信息

看看handle是怎么处理的

    private final Handler.Callback mHandlerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            synchronized (mLock) {
                if (msg.obj != null) {
                    mRemoteObserver = (IPackageInstallObserver2) msg.obj;
                }

                try {
                    commitLocked();
                } catch (PackageManagerException e) {
                    final String completeMsg = ExceptionUtils.getCompleteMessage(e);
                    Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
                    destroyInternal();
                    dispatchSessionFinished(e.error, completeMsg, null);
                }

                return true;
            }
        }
    };

继续跟commitLocked 这个也比较长 删掉了一些

    private void commitLocked() throws PackageManagerException {


        mRelinquished = true;
        mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params,
                installerPackageName, installerUid, user, mCertificates);
    }

可以看到这里的逻辑来到了mPm.installStage,后续的就来到PMS进行处理了

总结上面就干了两件事

把APK信息以IO 写给session
session的commit方法把apk信息给PMS处理

PMS层面处理安装请求

可以看到下面代码里面发送了一个INIT_COPY的信息

    void installStage(String packageName, File stagedDir, String stagedCid,
            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
            String installerPackageName, int installerUid, UserHandle user,
            Certificate[][] certificates) {
        if (DEBUG_EPHEMERAL) {
            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
                Slog.d(TAG, "Ephemeral install of " + packageName);
            }
        }
        final VerificationInfo verificationInfo = new VerificationInfo(
                sessionParams.originatingUri, sessionParams.referrerUri,
                sessionParams.originatingUid, installerUid);

        final OriginInfo origin;
        if (stagedDir != null) {
            origin = OriginInfo.fromStagedFile(stagedDir);
        } else {
            origin = OriginInfo.fromStagedContainer(stagedCid);
        }

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final InstallParams params = new InstallParams(origin, null, observer,
                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
                verificationInfo, user, sessionParams.abiOverride,
                sessionParams.grantedRuntimePermissions, certificates);
        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);
    }

我们看看他是怎么处理的

就来到handlemessage

handlemessage

因为很长所以就先看init copy里面的信息

  1. 检查defaultcontainerservice是否绑定,总之要绑定,还有IMediaContainerService相关处理,这些处理里面又把一些APK的基础信息解析了一下
  2. 发送MCS_BOUND信息
        void doHandleMessage(Message msg) {
            switch (msg.what) {
                case INIT_COPY: {
                    HandlerParams params = (HandlerParams) msg.obj;
                    int idx = mPendingInstalls.size();
                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
                    // If a bind was already initiated we dont really
                    // need to do anything. The pending install
                    // will be processed later on.
                    if (!mBound) {
                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
                                System.identityHashCode(mHandler));
                        // If this is the only one pending we might
                        // have to bind to the service again.
                        if (!connectToService()) {
                            Slog.e(TAG, "Failed to bind to media container service");
                            params.serviceError();
                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
                                    System.identityHashCode(mHandler));
                            if (params.traceMethod != null) {
                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
                                        params.traceCookie);
                            }
                            return;
                        } else {
                            // Once we bind to the service, the first
                            // pending request will be processed.
                            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;
                }

还是这个handle 是MCS_BOUND分支

  1. 做一些基础的判断
  2. 重点是来到if (params.startCopy()) { //6 这个地方 开始copy
case MCS_BOUND: {
                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
                    if (msg.obj != null) {
                        mContainerService = (IMediaContainerService) msg.obj;
                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
                                System.identityHashCode(mHandler));
                    }
                    if (mContainerService == null) {
                        if (!mBound) {
                            // Something seriously wrong since we are not bound and we are not
                            // waiting for connection. Bail out.
                            Slog.e(TAG, "Cannot bind to media container service");
                            for (HandlerParams params : mPendingInstalls) {
                                // Indicate service bind error
                                params.serviceError();
                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                                        System.identityHashCode(params));
                                if (params.traceMethod != null) {
                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
                                            params.traceMethod, params.traceCookie);
                                }
                                return;
                            }
                            mPendingInstalls.clear();
                        } else {
                            Slog.w(TAG, "Waiting to connect to media container service");
                        }
                    } else if (mPendingInstalls.size() > 0) {
                        HandlerParams params = mPendingInstalls.get(0);
                        if (params != null) {
                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                                    System.identityHashCode(params));
                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
                            if (params.startCopy()) {
                                // We are done...  look for more work or to
                                // go idle.
                                if (DEBUG_SD_INSTALL) Log.i(TAG,
                                        "Checking for more work or unbind...");
                                // Delete pending install
                                if (mPendingInstalls.size() > 0) {
                                    mPendingInstalls.remove(0);
                                }
                                if (mPendingInstalls.size() == 0) {
                                    if (mBound) {
                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
                                                "Posting delayed MCS_UNBIND");
                                        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.
                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
                                            "Posting MCS_BOUND for next work");
                                    mHandler.sendEmptyMessage(MCS_BOUND);
                                }
                            }
                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                        }
                    } else {
                        // Should never happen ideally.
                        Slog.w(TAG, "Empty queue");
                    }
                    break;
                }

startCopy 重要分支

跟,可以看到对复制次数做判断,然后handleStartCopy和handleReturnCode一个个看

        final boolean startCopy() {
            boolean res;
            try {
                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);

                if (++mRetries > MAX_RETRIES) {
                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
                    handleServiceError();
                    return false;
                } else {
                    handleStartCopy();
                    res = true;
                }
            } catch (RemoteException e) {
                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
                mHandler.sendEmptyMessage(MCS_RECONNECT);
                res = false;
            }
            handleReturnCode();
            return res;
        }

复制APK

先handleStartCopy,比较长 看刘老师的精简版

  1. 获取之前的一些APK信息
  2. 确认安装位置
  3. 创建InstallArgs对象(根据参数设置不同的安装逻辑,移动已安装APP或是安装到SD卡或是安装到DATA)
public void handleStartCopy() throws RemoteException {
           int ret = PackageManager.INSTALL_SUCCEEDED;
  
  					//确定APK的安装位置。
  					//onSd:安装到SD卡, onInt:内部存储即Data分区,ephemeral:安装到临时存储(Instant Apps安装)
           final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
           final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
           final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
           PackageInfoLite pkgLite = null;

           if (onInt && onSd) {
               // // APK不能同时安装在SD卡和Data分区
               Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
               ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
           } else if (onSd && ephemeral) {
               ////安装标志冲突,Instant Apps不能安装到SD卡中
               Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
               ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
           } else {
               //获取APK的少量的信息
               pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
                       packageAbiOverride);
             	......
           }

           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);
               }
           }
					
  					//根据InstallParams创建InstallArgs对象
           final InstallArgs args = createInstallArgs(this);
           mArgs = args;

           if (ret == PackageManager.INSTALL_SUCCEEDED) {
                 .....
                   
                 ret = args.copyApk(mContainerService, true);
               }
           }

           mRet = ret;
       }

看看

private InstallArgs createInstallArgs(InstallParams params) {
        if (params.move != null) {
            return new MoveInstallArgs(params);
        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
            return new AsecInstallArgs(params);
        } else {
            return new FileInstallArgs(params);
        }
    }

以FileInstallArg为例子 上面调用的就是下面的doCopyApk

  1. 在data/app 创建临时目录
  2. 把apk复制进去
        try {
            final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
            //创建临时文件存储目录
            final File tempDir =
                    mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);//1
            codeFile = tempDir;
            resourceFile = tempDir;
        } catch (IOException e) {
            Slog.w(TAG, "Failed to create copy file: " + e);
            return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
        }

        final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
            @Override
            public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
                if (!FileUtils.isValidExtFilename(name)) {
                    throw new IllegalArgumentException("Invalid filename: " + name);
                }
                try {
                    final File file = new File(codeFile, name);
                    final FileDescriptor fd = Os.open(file.getAbsolutePath(),
                            O_RDWR | O_CREAT, 0644);
                    Os.chmod(file.getAbsolutePath(), 0644);
                    return new ParcelFileDescriptor(fd);
                } catch (ErrnoException e) {
                    throw new RemoteException("Failed to open: " + e.getMessage());
                }
            }
        };

        int ret = PackageManager.INSTALL_SUCCEEDED;
        ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);//2
        if (ret != PackageManager.INSTALL_SUCCEEDED) {
            Slog.e(TAG, "Failed to copy package");
            return ret;
        }

        return ret;
    }

安装APK

之前看了handleStartCopy 做了一些准备工作

接下来就是handleReturnCode

@Override
    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) {
Slog.d(TAG,"welen:" + "handleReturnCode");
            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() {
				Slog.d(TAG,"welen:" + "processPendingInstall");
                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);
                }
              ......

我们主要看安装installPackageTracedLI

private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
            installPackageLI(args, res);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

这个还是很长的

  1. 解析APK
  2. 检查APK是否已经存在 在的话就是替换安装
  3. 根据setting看APK信息是否安装过 签名是否正确
  4. 之前data/app下是临时文件名 现在改成正常的
  5. 根据replace 替换安装就是replacePackageLIF 新APK就是installNewPackageLIF
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
  		  ......
        
   			PackageParser pp = new PackageParser();
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setDisplayMetrics(mMetrics);

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
        final PackageParser.Package pkg;
        try {
            // 解析APK
            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
        } catch (PackageParserException e) {
            res.setError("Failed parse during installPackageLI", e);
            return;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
  
  			......
          
  			pp = null;
        String oldCodePath = null;
        boolean systemApp = false;
  			synchronized (mPackages) {
           // 判断APK是否存在,存在replace = true
           if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
                String oldName = mSettings.mRenamedPackages.get(pkgName);
                if (pkg.mOriginalPackages != null
                        && pkg.mOriginalPackages.contains(oldName)
                        && mPackages.containsKey(oldName)) {
                    // This package is derived from an original package,
                    // and this device has been updating from that original
                    // name.  We must continue using the original name, so
                    // rename the new package here.
                    pkg.setPackageName(oldName);
                    pkgName = pkg.packageName;
                    replace = true;
                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
                            + oldName + " pkgName=" + pkgName);
                } else if (mPackages.containsKey(pkgName)) {
                    // This package, under its official name, already exists
                    // on the device; we should replace it.
                    replace = true;
                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
                }
            }
          PackageSetting ps = mSettings.mPackages.get(pkgName);
          //查看Settings中是否存有要安装的APK的信息,如果有就获取签名信息
          if (ps != null) {
                //检查签名信息
                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
                    //新APK与老APK签名不一致
                    if (!checkUpgradeKeySetLP(ps, pkg)) {
                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
                                + pkg.packageName + " upgrade keys do not match the "
                                + "previously installed version");
                        return;
                    }
                } else {
                    try {
                        //确保签名一致
                        verifySignaturesLP(ps, pkg);
                    } catch (PackageManagerException e) {
                        res.setError(e.error, e.getMessage());
                        return;
                    }
                }
            }
          
          
          int N = pkg.permissions.size();
          //遍历每个权限,对权限进行处理
          for (int i = N-1; i >= 0; i--) {
                PackageParser.Permission perm = pkg.permissions.get(i);
                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
            ......
          }
        }
  			
  			f (systemApp) {
            if (onExternal) {
                // //系统APP不能在SD卡上替换安装
                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                        "Cannot install updates to system apps on sdcard");
                return;
            } else if (ephemeral) {
                // 系统APP不能被Instant App替换
                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
                        "Cannot update a system app with an ephemeral app");
                return;
            }
        }
  	
  			......
          
        //重命名临时文件
  			if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
            return;
        }

        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);

        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
                "installPackageLI")) {
            if (replace) {
                //替换安装
                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
                        installerPackageName, res);
            } else {
                //安装新APK
                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
                        args.user, installerPackageName, volumeUuid, res);
            }
        }
        synchronized (mPackages) {
            final PackageSetting ps = mSettings.mPackages.get(pkgName);
            if (ps != null) {
                //更新应用程序所属的用户
                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
            }
          ......
        }

}

看安装新APK installNewPackageLIF

记住这边三个

  1. scanPackageTracedLI
  2. updateSettingsLI
  3. prepareAppDataAfterInstallLIF
/*
    * Install a non-existing package.
    */
   private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
           int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
           PackageInstalledInfo res) {
       Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");

       // Remember this for later, in case we need to rollback this install
       String pkgName = pkg.packageName;

       try {
           //扫描APK
           PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
                   System.currentTimeMillis(), user);
					//更新Settings信息
           updateSettingsLI(newPackage, installerPackageName, null, res, user);

           if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
             	//安装成功后,为新安装的应用程序准备数据
               prepareAppDataAfterInstallLIF(newPackage);

           } else {
               //安装失败则删除APK
               deletePackageLIF(pkgName, UserHandle.ALL, false, null,
                       PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
           }
       } catch (PackageManagerException e) {
           res.setError("Package couldn't be installed in " + pkg.codePath, e);
       }

       Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
   }

scanPackageTracedLI

这里跟到底就是对App中的provider,service,receiver,activity全都保存到PMS的成员集合类

private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
            final int policyFlags, int scanFlags, long currentTime, UserHandle user)
                    throws PackageManagerException {
     
        final PackageParser.Package scannedPkg;
        try {
            // Scan the parent
            scannedPkg = scanPackageLI(pkg, policyFlags, 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 childPkg = pkg.childPackages.get(i);
                scanPackageLI(childPkg, policyFlags,
                        scanFlags, currentTime, user);
            }
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }

        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
        }
        return scannedPkg;
    }

private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
        boolean success = false;
        try {
            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
                    currentTime, user);
            success = true;
            return res;
        } finally {
            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
            }
        }
    }

private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
            final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
            throws PackageManagerException {
        final File scanFile = new File(pkg.codePath);
        ......

            // // 处理provider
            int N = pkg.providers.size();
            StringBuilder r = null;
            int i;
            for (i=0; i<N; i++) {
                PackageParser.Provider p = pkg.providers.get(i);
                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
                        p.info.processName, pkg.applicationInfo.uid);
                mProviders.addProvider(p);
            }
            // 处理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, pkg.applicationInfo.uid);
                mServices.addService(s);
               
            }
          
 
            // 处理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, pkg.applicationInfo.uid);
                mReceivers.addActivity(a, "receiver");
              
            }
            

            // 处理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, pkg.applicationInfo.uid);
                mActivities.addActivity(a, "activity");
            }
            

            // 处理permissionGroup权限组
            N = pkg.permissionGroups.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
                final String curPackageName = cur == null ? null : cur.info.packageName;
                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
                if (cur == null || isPackageUpdate) {
                    mPermissionGroups.put(pg.info.name, pg);
                }
            }
          

            // 处理permission
            N = pkg.permissions.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.Permission p = pkg.permissions.get(i);

                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;

                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                    p.group = mPermissionGroups.get(p.info.group);
                    // Warn for a permission in an unknown group.
                    if (p.info.group != null && p.group == null) {
                        Slog.w(TAG, "Permission " + p.info.name + " from package "
                                + p.info.packageName + " in an unknown group " + p.info.group);
                    }
                }

                ArrayMap<String, BasePermission> permissionMap =
                        p.tree ? mSettings.mPermissionTrees
                                : mSettings.mPermissions;
                BasePermission bp = permissionMap.get(p.info.name);

                // Allow system apps to redefine non-system permissions
                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
                    final boolean currentOwnerIsSystem = (bp.perm != null
                            && isSystemApp(bp.perm.owner));
                    if (isSystemApp(p.owner)) {
                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
                            // It's a built-in permission and no owner, take ownership now
                            bp.packageSetting = pkgSetting;
                            bp.perm = p;
                            bp.uid = pkg.applicationInfo.uid;
                            bp.sourcePackage = p.info.packageName;
                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
                        } else if (!currentOwnerIsSystem) {
                            String msg = "New decl " + p.owner + " of permission  "
                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
                            reportSettingsProblem(Log.WARN, msg);
                            bp = null;
                        }
                    }
                }

                if (bp == null) {
                    bp = new BasePermission(p.info.name, p.info.packageName,
                            BasePermission.TYPE_NORMAL);
                    permissionMap.put(p.info.name, bp);
                }

                if (bp.perm == null) {
                    if (bp.sourcePackage == null
                            || bp.sourcePackage.equals(p.info.packageName)) {
                        BasePermission tree = findPermissionTreeLP(p.info.name);
                        if (tree == null
                                || tree.sourcePackage.equals(p.info.packageName)) {
                            bp.packageSetting = pkgSetting;
                            bp.perm = p;
                            bp.uid = pkg.applicationInfo.uid;
                            bp.sourcePackage = p.info.packageName;
                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
                            if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
                                if (r == null) {
                                    r = new StringBuilder(256);
                                } else {
                                    r.append(' ');
                                }
                                r.append(p.info.name);
                            }
                        } else {
                            Slog.w(TAG, "Permission " + p.info.name + " from package "
                                    + p.info.packageName + " ignored: base tree "
                                    + tree.name + " is from package "
                                    + tree.sourcePackage);
                        }
                    } else {
                        Slog.w(TAG, "Permission " + p.info.name + " from package "
                                + p.info.packageName + " ignored: original from "
                                + bp.sourcePackage);
                    }
                } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append("DUP:");
                    r.append(p.info.name);
                }
                if (bp.perm == p) {
                    bp.protectionLevel = p.info.protectionLevel;
                }
            }

            // 处理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.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
                a.info.dataDir = pkg.applicationInfo.dataDir;
                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;

                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
                mInstrumentation.put(a.getComponentName(), a);
               
            }
           
            // 处理protectedBroadcast
            if (pkg.protectedBroadcasts != null) {
                N = pkg.protectedBroadcasts.size();
                for (i=0; i<N; i++) {
                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
                }
            }

            // 设置时间戳为扫描文件的时间戳
            pkgSetting.setTimeStamp(scanFileTime);
           ......
        return pkg;
    }

updateSettingsLI

private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
            int[] allUsers, PackageInstalledInfo res, UserHandle user) {
        // Update the parent package setting
        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
                res, user);
        // Update the child packages setting
        final int childCount = (newPackage.childPackages != null)
                ? newPackage.childPackages.size() : 0;
        for (int i = 0; i < childCount; i++) {
            PackageParser.Package childPackage = newPackage.childPackages.get(i);
            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
                    childRes.origUsers, childRes, user);
        }
    }

private void updateSettingsInternalLI(PackageParser.Package newPackage,
         String installerPackageName, int[] allUsers, int[] installedForUsers,
         PackageInstalledInfo res, UserHandle user) {
     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");

     String pkgName = newPackage.packageName;
     synchronized (mPackages) {
         //write settings. the installStatus will be incomplete at this stage.
         //note that the new package setting would have already been
         //added to mPackages. It hasn't been persisted yet.
         mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
         mSettings.writeLPr();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }

     synchronized (mPackages) {
         updatePermissionsLPw(newPackage.packageName, newPackage,
                 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
                         ? UPDATE_PERMISSIONS_ALL : 0));
         // For system-bundled packages, we assume that installing an upgraded version
         // of the package implies that the user actually wants to run that new code,
         // so we enable the package.
         PackageSetting ps = mSettings.mPackages.get(pkgName);
         final int userId = user.getIdentifier();
         if (ps != null) {
             if (isSystemApp(newPackage)) {
                 if (DEBUG_INSTALL) {
                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
                 }
                 // Enable system package for requested users
                 if (res.origUsers != null) {
                     for (int origUserId : res.origUsers) {
                         if (userId == UserHandle.USER_ALL || userId == origUserId) {
                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
                                     origUserId, installerPackageName);
                         }
                     }
                 }
                 // Also convey the prior install/uninstall state
                 if (allUsers != null && installedForUsers != null) {
                     for (int currentUserId : allUsers) {
                         final boolean installed = ArrayUtils.contains(
                                 installedForUsers, currentUserId);
                         if (DEBUG_INSTALL) {
                             Slog.d(TAG, "    user " + currentUserId + " => " + installed);
                         }
                         ps.setInstalled(installed, currentUserId);
                     }
                     // these install state changes will be persisted in the
                     // upcoming call to mSettings.writeLPr().
                 }
             }
             // It's implied that when a user requests installation, they want the app to be
             // installed and enabled.
             if (userId != UserHandle.USER_ALL) {
                 ps.setInstalled(true, userId);
                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
             }
         }
         res.name = pkgName;
         res.uid = newPackage.applicationInfo.uid;
         res.pkg = newPackage;
         mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
         mSettings.setInstallerPackageName(pkgName, installerPackageName);
         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
         //to update install status
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
         mSettings.writeLPr();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }

     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 }

看看wrtieKLPr干嘛的

private void updateSettingsInternalLI(PackageParser.Package newPackage,
         String installerPackageName, int[] allUsers, int[] installedForUsers,
         PackageInstalledInfo res, UserHandle user) {
     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");

     String pkgName = newPackage.packageName;
     synchronized (mPackages) {
         //write settings. the installStatus will be incomplete at this stage.
         //note that the new package setting would have already been
         //added to mPackages. It hasn't been persisted yet.
         mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
         mSettings.writeLPr();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }

     synchronized (mPackages) {
         updatePermissionsLPw(newPackage.packageName, newPackage,
                 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
                         ? UPDATE_PERMISSIONS_ALL : 0));
         // For system-bundled packages, we assume that installing an upgraded version
         // of the package implies that the user actually wants to run that new code,
         // so we enable the package.
         PackageSetting ps = mSettings.mPackages.get(pkgName);
         final int userId = user.getIdentifier();
         if (ps != null) {
             if (isSystemApp(newPackage)) {
                 if (DEBUG_INSTALL) {
                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
                 }
                 // Enable system package for requested users
                 if (res.origUsers != null) {
                     for (int origUserId : res.origUsers) {
                         if (userId == UserHandle.USER_ALL || userId == origUserId) {
                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
                                     origUserId, installerPackageName);
                         }
                     }
                 }
                 // Also convey the prior install/uninstall state
                 if (allUsers != null && installedForUsers != null) {
                     for (int currentUserId : allUsers) {
                         final boolean installed = ArrayUtils.contains(
                                 installedForUsers, currentUserId);
                         if (DEBUG_INSTALL) {
                             Slog.d(TAG, "    user " + currentUserId + " => " + installed);
                         }
                         ps.setInstalled(installed, currentUserId);
                     }
                     // these install state changes will be persisted in the
                     // upcoming call to mSettings.writeLPr().
                 }
             }
             // It's implied that when a user requests installation, they want the app to be
             // installed and enabled.
             if (userId != UserHandle.USER_ALL) {
                 ps.setInstalled(true, userId);
                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
             }
         }
         res.name = pkgName;
         res.uid = newPackage.applicationInfo.uid;
         res.pkg = newPackage;
         mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
         mSettings.setInstallerPackageName(pkgName, installerPackageName);
         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
         //to update install status
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
         mSettings.writeLPr();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }

     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 }

原来是对data/system/packages.xml data/system/packages.list操作

我们拉出手上测试机的看一看

image-20240719212748735

image-20240719212756187

确实是通过update更新的

prepareAppDataAfterInstallLIF

跟的比较长 总结功能就是 mInstaller.createAppDatamInstaller.linkNativeLibraryDirectory,mInstaller我们之前有了解过,Installer继承自SystemService,和PMS、AMS一样是系统的服务(引导服务),PMS很多的操作都是由Installer来完成的。

ok到这里就算ok了

其实总结一下,APK的安装,深入到PMS的逻辑其实就是把APK复制进某文件夹,解析信息到setting,保存到一些packages相关xml list。