android系统的程序安装主要通过四种途径安装,分别是:

1.系统开机时加载的apk,这一部分的包主要是系统包和一些用户自己安装的程序,无安装界面。

2.通过网络下载安装的包,这一部分主要通过调用PackageManager安装,有部分界面

3.通过adb安装,没有安装界面

4.通过安装器安装,这一部分主要通过调用PackageInstaller安装

我们通过代码依次分析以上四部分:

系统启动安装:

可能要给android做一个类似白名单的东西,只要加入白名单的程序运行,所以需要看一下 android启动时加载安装程序,也就是PackageManagerService的实现。PackageManagerService是由SystemServer启动的所以我们从SystemServer看起。SystemServer的代码位于frameworks/base/services/java/com/android/server/SystemServer.java,其实现是一个标准的java程序,入口代码如下:

 1 public class SystemServer {
 2     private static final String TAG = "SystemServer";
 3     //...
 4 
 5     /**
 6      * This method is called from Zygote to initialize the system. This will cause the native
 7      * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
 8      * up into init2() to start the Android services.
 9      */
10     native public static void init1(String[] args);
11 
12     public static void main(String[] args) {
13     //...
14 
15         System.loadLibrary("android_servers");
16         init1(args);
17 }

其中init1完成初始化的工作,从这个函数的定义可以看出这个函数是一个c/c++的函数,需要用到java的JNI技术,这个函数的定义位于base/services/jni/com_android_server_SystemServer.cpp文件中,这个文件的代码比较少可以全部列出来,代码如下:

 1 namespace android {
 2 
 3 extern "C" int system_init();
 4 
 5 static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
 6 {
 7     system_init();
 8 }
 9 
10 /*
11  * JNI registration.
12  */
13 static JNINativeMethod gMethods[] = {
14     /* name, signature, funcPtr */
15     { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
16 };
17 
18 int register_android_server_SystemServer(JNIEnv* env)
19 {
20     return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
21             gMethods, NELEM(gMethods));
22 }
23 
24 }; // namespace android

从这段代码可以看出真正调用的函数是system_init,这个函数的定义位于base/cmds/system_server/library/system_init.cpp部分定义如下:

extern "C" status_t system_init()
{
    ALOGI("Entered system_init()");

    sp<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p\n", sm.get());

    sp<GrimReaper> grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
    //...

     jclass clazz = env->FindClass("com/android/server/SystemServer");
     if (clazz == NULL) {
         return UNKNOWN_ERROR;
     }
     jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
     if (methodId == NULL) {
         return UNKNOWN_ERROR;
     }
     env->CallStaticVoidMethod(clazz, methodId);
 
     ALOGI("System server: entering thread pool.\n");
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
     ALOGI("System server: exiting thread pool.\n");
 
     return NO_ERROR;
 }

熟悉android的朋友一眼就知道开头几行函数的意义,这几行的作用主要是完成进程间通信。我们重点看下面的几行

1 jclass clazz = env->FindClass("com/android/server/SystemServer");
2      if (clazz == NULL) {
3          return UNKNOWN_ERROR;
4      }
5      jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
6      if (methodId == NULL) {
7          return UNKNOWN_ERROR;
8      }
9      env->CallStaticVoidMethod(clazz, methodId);

以上几行的作用主要是调用init2这个函数,该函数定义在SystemServer.java文件中定义如下:

1  public static final void init2() {
2      Slog.i(TAG, "Entered the Android system server!");
3      Thread thr = new ServerThread();
4      thr.setName("android.server.ServerThread");
5      thr.start();
6  }

在以上的代码中开始执行这个线程,这个线程的本身定义在SystemServer.java这个文件中,定义如下:

 1 class ServerThread extends Thread {
 2     //...
 3 
 4     @Override
 5     public void run() {
 6     //...
 7     IPackageManager pm = null;
 8     pm = PackageManagerService.main(context, installer,
 9           factoryTest != SystemServer.FACTORY_TEST_OFF,
10           onlyCore);
11   boolean firstBoot = false;
12   try {
13       firstBoot = pm.isFirstBoot();
14   } catch (RemoteException e) {
15   }
16     //...   
27 }

在这个run函数中启动了android所需要的系统服务如PowerManagerService,ActivityManagerService 等系统服务,但是我们今天主要分析android的PackageManagerService。以上的函数调用定义在base/services/java/com/android/server/pm/PackageManagerService.java,定义如下:

 public static final IPackageManager main(Context context, Installer installer,
         boolean factoryTest, boolean onlyCore) {
     PackageManagerService m = new PackageManagerService(context, installer,
             factoryTest, onlyCore);
     ServiceManager.addService("package", m);
     return m;
 }

在该段代码中主要完成了向serviceManager的注册,其中PackageManagerService实现如下:

 1  public PackageManagerService(Context context, Installer installer,
 2             boolean factoryTest, boolean onlyCore) {
 3     //...
 4  File dataDir = Environment.getDataDirectory();
 5             mAppDataDir = new File(dataDir, "data");
 6             mAppInstallDir = new File(dataDir, "app");
 7             mAppLibInstallDir = new File(dataDir, "app-lib");
 8             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
 9             mUserAppDataDir = new File(dataDir, "user");
10             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
11     //...
12             mFrameworkInstallObserver = new AppDirObserver(
13                 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
14             mFrameworkInstallObserver.startWatching();
15             scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
16                     | PackageParser.PARSE_IS_SYSTEM_DIR,
17                     scanMode | SCAN_NO_DEX, 0);
18 
19             // Collect all system packages.
20             mSystemAppDir = new File(Environment.getRootDirectory(), "app");
21             mSystemInstallObserver = new AppDirObserver(
22                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
23             mSystemInstallObserver.startWatching();
24             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
25                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
26 
27             // Collect all vendor packages.
28             mVendorAppDir = new File("/vendor/app");
29             mVendorInstallObserver = new AppDirObserver(
30                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
31             mVendorInstallObserver.startWatching();
32             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
33                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
34     //...
35 }

系统启动以后将搜索以下目录中的apk文件

/system/framework
/system/app
/vendor/app
/data/app
/data/app-private

搜索apk文件的函数主要由scanDirLI来实现,具体实现如下:

 1      private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
 2          String[] files = dir.list();
 3          if (files == null) {
 4              Log.d(TAG, "No files in app dir " + dir);
 5              return;
 6          }
 7  
 8          if (DEBUG_PACKAGE_SCANNING) {
 9              Log.d(TAG, "Scanning app dir " + dir);
10          }
11  
12          int i;
13          for (i=0; i<files.length; i++) {
14              File file = new File(dir, files[i]);
15              if (!isPackageFilename(files[i])) {
16                  // Ignore entries which are not apk's
17                  continue;
18              }
19              PackageParser.Package pkg = scanPackageLI(file,
20                      flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
21              // Don't mess around with apps in system partition.
22              if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
23                      mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
24                  // Delete the apk
25                  Slog.w(TAG, "Cleaning up failed install of " + file);
26                  file.delete();
27              }
28          }
29      }

 接下来我们看一下scanPackageLI这个函数,这个函数内容如下:

 1    private PackageParser.Package scanPackageLI(File scanFile,
 2            int parseFlags, int scanMode, long currentTime, UserHandle user) {
 3        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
 4        String scanPath = scanFile.getPath();
 5        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath);
 6        parseFlags |= mDefParseFlags;
 7        PackageParser pp = new PackageParser(scanPath);
 8        pp.setSeparateProcesses(mSeparateProcesses);
 9        pp.setOnlyCoreApps(mOnlyCore);
10        final PackageParser.Package pkg = pp.parsePackage(scanFile,
11                scanPath, mMetrics, parseFlags);
12        if (pkg == null) {
13            mLastScanError = pp.getParseError();
14            return null;
15        }
16        PackageSetting ps = null;
17        PackageSetting updatedPkg;
18     //...
19 }

在这个函数中我们看到它调用一个新的对象PackageParser,这个对象定义在base/core/java/android/content/pm/PackageParser.java这个文件中,在这里我们主要看调用的parsePackage函数,该函数定义如下:

 public Package parsePackage(File sourceFile, String destCodePath,
         DisplayMetrics metrics, int flags) {
   //...
try {
    assmgr = new AssetManager();
    int cookie = assmgr.addAssetPath(mArchiveSourcePath);
    if (cookie != 0) {
        res = new Resources(assmgr, metrics, null);
        assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                Build.VERSION.RESOURCES_SDK_INT);
        parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
        assetError = false;
    } else {
        Slog.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);
    }
} catch (Exception e) {
    Slog.w(TAG, "Unable to read AndroidManifest.xml of "
            + mArchiveSourcePath, e);
}
//...

该段代码主要用来解析Manifest文件。具体的代码此处不再分析,接着看下面的代码:

 1 {
 2     //...
 3  Package pkg = null;
 4  Exception errorException = null;
 5  try {
 6      // XXXX todo: need to figure out correct configuration.
 7      pkg = parsePackage(res, parser, flags, errorText);
 8  } catch (Exception e) {
 9      errorException = e;
10      mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
11  }
12 //...
13 }

从代码注释可以看出,此处主要是解析程序配置。接着我们回到scanPackageLI函数,接下来的代码如下:

 1  synchronized (mPackages) {
 2     
 3      String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
 4      if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
 5 
 6          ps = mSettings.peekPackageLPr(oldName);
 7      }
 8 
 9      if (ps == null) {
10          ps = mSettings.peekPackageLPr(pkg.packageName);
11      }
12 
13      updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
14 
15  }

该段代码主要用来检查该包是否被重命名过,接下来看下面的内容:

1 {
2    //...
3 codePath = pkg.mScanPath;
4 setApplicationInfoPaths(pkg, codePath, resPath);
5 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
6         | SCAN_UPDATE_SIGNATURE, currentTime, user);
7    //...
8 }

在这里我们看一下scanPackageLI这个函数的另一个重载版本:

 1 private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
 2         int parseFlags, int scanMode, long currentTime, UserHandle user) {
 3     //...
 4 
 5 // Check if we are renaming from an original package name.
 6 PackageSetting origPackage = null;
 7 String realName = null;
 8 if (pkg.mOriginalPackages != null) {
 9     final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
10     if (pkg.mOriginalPackages.contains(renamed)) {
11         realName = pkg.mRealPackage;
12         if (!pkg.packageName.equals(renamed)) {
13             pkg.setPackageName(renamed);
14         }
15 
16     } else {
17 
18                 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
19                     if ((origPackage = mSettings.peekPackageLPr(
20                             pkg.mOriginalPackages.get(i))) != null) {
21                         if (!verifyPackageUpdateLPr(origPackage, pkg)) {
22                             origPackage = null;
23                             continue;
24                         } else if (origPackage.sharedUser != null) {
25                             if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
26                                 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
27                                         + " to " + pkg.packageName + ": old uid "
28                                         + origPackage.sharedUser.name
29                                         + " differs from " + pkg.mSharedUserId);
30                                 origPackage = null;
31                                 continue;
32                             }
33                         } else {
34                             if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
35                                     + pkg.packageName + " to old name " + origPackage.name);
36                         }
37                         break;
38                     }
39                 }
40             }
41         }
42 
43     //...
44 }

以上的代码主要用来检查一个包是否被重命名,如果该包重命名过,那在此处要负责把它替换过来。

adb 安装

这一部分的安装主要是开发者在开发app时使用adb来安装app,我们先看一下adb的实现,其中定义文件如下system/core/adb/adb.c,入口函数如下:

 1 int main(int argc, char **argv)
 2 {
 3 #if ADB_HOST
 4     adb_sysdeps_init();
 5     adb_trace_init();
 6     D("Handling commandline()\n");
 7     return adb_commandline(argc - 1, argv + 1);
 8 #else
 9     /* If adbd runs inside the emulator this will enable adb tracing via
10      * adb-debug qemud service in the emulator. */
11     adb_qemu_trace_init();
12     if((argc > 1) && (!strcmp(argv[1],"recovery"))) {
13         adb_device_banner = "recovery";
14         recovery_mode = 1;
15     }
16 
17     start_device_log();
18     D("Handling main()\n");
19     return adb_main(0, DEFAULT_ADB_PORT);
20 #endif
21 }

我们主要看一下adb_commandline的实现,该函数定义在system/core/adb/commandline.c文件中,整个函数的实现比叫多,我们只关心install的部分,所以我们只列出install的部分

 1 int adb_commandline(int argc, char **argv)
 2 {
 3      //...
 4 
 5   if(!strcmp(argv[0], "install")) {
 6       if (argc < 2) return usage();
 7       return install_app(ttype, serial, argc, argv);
 8   }
 9 
10     //...
11 }

我们找到install_app的实现,这个函数实现如下:

 1  int install_app(transport_type transport, char* serial, int argc, char** argv)
 2  {
 3      static const char *const DATA_DEST = "/data/local/tmp/%s";
 4      static const char *const SD_DEST = "/sdcard/tmp/%s";
 5      const char* where = DATA_DEST;
 6      //...   
 7      pm_command(transport, serial, argc, argv);
 8  
 9  cleanup_apk:
10      if (verification_file != NULL) {
11          delete_file(transport, serial, verification_dest);
12      }
13  
14      delete_file(transport, serial, apk_dest);
15  
16      return err;
17  }

通过pm_command的处理我们已经将apk文件copy到了android的系统中,接下来我们看一下在android系统中到接到这一部分消息后是如何处理的。处理这一部分的代码定义在frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java文件中,我们找到对应install的部分代码定义如下:

 1 public final class Pm {
 2     IPackageManager mPm;
 3     IUserManager mUm;
 4 
 5     private WeakHashMap<String, Resources> mResourceCache
 6             = new WeakHashMap<String, Resources>();
 7 
 8     private String[] mArgs;
 9     private int mNextArg;
10     private String mCurArgData;
11 
12     private static final String PM_NOT_RUNNING_ERR =
13         "Error: Could not access the Package Manager.  Is the system running?";
14 
15     public static void main(String[] args) {
16         new Pm().run(args);
17     }
18 
19     public void run(String[] args) {
20         boolean validCommand = false;
21         if (args.length < 1) {
22             showUsage();
23             return;
24         }
25 
26         mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user"));
27         mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
28 
29    //...
30 
31     if ("install".equals(op)) {
32         runInstall();
33         return;
34     }
35 
36     //...
37 }
38 
39 }

我们找到对应的runInstall的实现,定义如下:

 1  private void runInstall() {
 2      int installFlags = PackageManager.INSTALL_ALL_USERS;
 3      String installerPackageName = null;
 4      //...
 5 
 6     PackageInstallObserver obs = new PackageInstallObserver();
 7     try {
 8         VerificationParams verificationParams = new VerificationParams(verificationURI,
 9                 originatingURI, referrerURI, VerificationParams.NO_UID, null);
10 
11         mPm.installPackageWithVerificationAndEncryption(apkURI, obs, installFlags,
12                 installerPackageName, verificationParams, encryptionParams);
13 
14         synchronized (obs) {
15             while (!obs.finished) {
16                 try {
17                     obs.wait();
18                 } catch (InterruptedException e) {
19                 }
20             }
21             if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
22                 System.out.println("Success");
23             } else {
24                 System.err.println("Failure ["
25                         + installFailureToString(obs.result)
26                         + "]");
27             }
28         }
29     } catch (RemoteException e) {
30         System.err.println(e.toString());
31         System.err.println(PM_NOT_RUNNING_ERR);
32     }
33 
34     //...
35 }

以上这一部分就是我们执行安装的部分,安装的过程是在PackageManager完成的,调用的函数为installPackageWithVerificationAndEncryption,该函数定义在PackageManager中,定义如下:

 1 public void installPackageWithVerificationAndEncryption(Uri packageURI,
 2         IPackageInstallObserver observer, int flags, String installerPackageName,
 3         VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
 4     mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
 5             null);
 6 
 7     final int uid = Binder.getCallingUid();
 8     if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
 9         try {
10             observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
11         } catch (RemoteException re) {
12         }
13         return;
14     }
15 
16     UserHandle user;
17     if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
18         user = UserHandle.ALL;
19     } else {
20         user = new UserHandle(UserHandle.getUserId(uid));
21     }
22 
23     final int filteredFlags;
24 
25     if (uid == Process.SHELL_UID || uid == 0) {
26         if (DEBUG_INSTALL) {
27             Slog.v(TAG, "Install from ADB");
28         }
29         filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
30     } else {
31         filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
32     }
33 
34     verificationParams.setInstallerUid(uid);
35 
36     final Message msg = mHandler.obtainMessage(INIT_COPY);
37     msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
38             verificationParams, encryptionParams, user);
39     mHandler.sendMessage(msg);
40 }

以上就是通过adb安装的过程了。需要说明的是这一部分的安装是没有界面的。

通过安装器安装:

一般的用户安装程序,可能接触到做多的就是这个了,下面就介绍一下通过安装器安装的流程。其中系统默认的安装器源码路径为:packages/apps/PackageInstaller/,下面我分析一下其实现,这个就是一个普通的android app应用,其入口文件为:PackageInstallerActivity.java,其中onCreate函数定义如下:

 1  protected void onCreate(Bundle icicle) {
 2      super.onCreate(icicle);
 3 
 4      // get intent information
 5      final Intent intent = getIntent();
 6      mPackageURI = intent.getData();
 7      mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
 8      mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
 9      mPm = getPackageManager();
10 
11      final String scheme = mPackageURI.getScheme();
12      if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) {
13          Log.w(TAG, "Unsupported scheme " + scheme);
14          setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI);
15          return;
16      }
17 
18   final PackageUtil.AppSnippet as;
19   if ("package".equals(mPackageURI.getScheme())) {
20       try {
21           mPkgInfo = mPm.getPackageInfo(mPackageURI.getSchemeSpecificPart(),
22                   PackageManager.GET_PERMISSIONS | PackageManager.GET_UNINSTALLED_PACKAGES);
23       } catch (NameNotFoundException e) {
24       }
25       if (mPkgInfo == null) {
26           Log.w(TAG, "Requested package " + mPackageURI.getScheme()
27                   + " not available. Discontinuing installation");
28           showDialogInner(DLG_PACKAGE_ERROR);
29           setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
30           return;
31       }
32       as = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo),
33               mPm.getApplicationIcon(mPkgInfo.applicationInfo));
34   } else {
35       final File sourceFile = new File(mPackageURI.getPath());
36       PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile);
37 
38       // Check for parse errors
39       if (parsed == null) {
40           Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
41           showDialogInner(DLG_PACKAGE_ERROR);
42           setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
43           return;
44       }
45       mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
46               PackageManager.GET_PERMISSIONS, 0, 0, null,
47               new PackageUserState());
48       mPkgDigest = parsed.manifestDigest;
49       as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
50   }

这一部分就比较简单了,首先根据intent获取传递的信息,之后调用PakcageManager的函数获取apk文件的信息,当用户点击安装时进行安装,其最终调用的函数为:

 1    if ("package".equals(mPackageURI.getScheme())) {
 2        try {
 3            pm.installExistingPackage(mAppInfo.packageName);
 4            observer.packageInstalled(mAppInfo.packageName,
 5                    PackageManager.INSTALL_SUCCEEDED);
 6        } catch (PackageManager.NameNotFoundException e) {
 7            observer.packageInstalled(mAppInfo.packageName,
 8                    PackageManager.INSTALL_FAILED_INVALID_APK);
 9        }
10    } else {
11        pm.installPackageWithVerificationAndEncryption(mPackageURI, observer, installFlags,
12                installerPackageName, verificationParams, null);
13    }

可以看到在此处做了一个判断,这个包是否已经被安装过了,两者调用了不同的函数。installExistingPackage函数定义在frameworks/base/core/java/android/app/ApplicationPackageManager.java文件中,实现如下:

 1  public int installExistingPackage(String packageName)
 2          throws NameNotFoundException {
 3      try {
 4          int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
 5          if (res == INSTALL_FAILED_INVALID_URI) {
 6              throw new NameNotFoundException("Package " + packageName + " doesn't exist");
 7          }
 8          return res;
 9      } catch (RemoteException e) {
10          // Should never happen!
11          throw new NameNotFoundException("Package " + packageName + " doesn't exist");
12      }
13  }

可以看到其最终调用了PackageManager的installExistingPackageAsUser函数。installPackageWithVerificationAndEncryption也定义frameworks/base/core/java/android/app/ApplicationPackageManager.java文件中,实现如下:

 1   public void installPackageWithVerificationAndEncryption(Uri packageURI,
 2         IPackageInstallObserver observer, int flags, String installerPackageName,
 3         VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
 4     try {
 5         mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
 6                 installerPackageName, verificationParams, encryptionParams);
 7     } catch (RemoteException e) {
 8         // Should never happen!
 9     }
10 }

其最终调用了PackageManager的installPackageWithVerificationAndEncryption函数。以上就是通过安装器安装的过程。