adb install 发生了什么-PMS篇

255 阅读9分钟

adb install 发生了什么-PMS篇

在上一篇中,最后通过binder调用了shellCommand。

//frameworks/native/libs/binder/Binder.cpp
status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int err,
    Vector<String16>& args, const sp<IShellCallback>& callback,
    const sp<IResultReceiver>& resultReceiver)
{
    Parcel send;
    Parcel reply;
    send.writeFileDescriptor(in);
    send.writeFileDescriptor(out);
    send.writeFileDescriptor(err);
    const size_t numArgs = args.size();
    send.writeInt32(numArgs);
    for (size_t i = 0; i < numArgs; i++) {
        send.writeString16(args[i]);
    }
    send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);
    send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);
    return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
}

通过transact将消息发送到了service中,code为SHELL_COMMAND_TRANSACTION。

//frameworks/base/core/java/android/os/Binder.java 
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
            int flags) throws RemoteException {
  
        ...
       
        if (code == SHELL_COMMAND_TRANSACTION) {//code等于SHELL_COMMAND_TRANSACTION
            ParcelFileDescriptor in = data.readFileDescriptor();
            ParcelFileDescriptor out = data.readFileDescriptor();
            ParcelFileDescriptor err = data.readFileDescriptor();
            String[] args = data.readStringArray();
            ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
            ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
            try {
                if (out != null) {
                    shellCommand(in != null ? in.getFileDescriptor() : null,
                            out.getFileDescriptor(),
                            err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
                            args, shellCallback, resultReceiver);
                }
            }
          ...
    }

当code为SHELL_COMMAND_TRANSACTION时,会调用shellCommand。

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java      
@Override
        public void onShellCommand(FileDescriptor in, FileDescriptor out,
                FileDescriptor err, String[] args, ShellCallback callback,
                ResultReceiver resultReceiver) {
            (new PackageManagerShellCommand(this, mContext,
                    mDomainVerificationManager.getShell()))
                    .exec(this, in, out, err, args, callback, resultReceiver);
        }
​

创建了一个PackageManagerShellCommand对象,然后调用了exec.这是父类中的方法。

//frameworks/libs/modules-utils/java/com/android/modules/utils/BasicShellCommandHandler.java
public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args) {
      
        int res = -1;
        try {
            res = onCommand(mCmd);
            if (DEBUG) Log.d(TAG, "Executed command " + mCmd + " on " + mTarget);
        } 
      ...
        return res;
    }

执行部分调用onCommand方法。

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java 
@Override
    public int onCommand(String cmd) {
        final PrintWriter pw = getOutPrintWriter();
        try {
            switch (cmd) {
                
               ...
                 
                case "install":
                    return runInstall();
              ....
        return -1;
    }
          
     private int runInstall() throws RemoteException {
        return doRunInstall(makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS));
    }
​
          

install指令最后调用到doRunInstall。

 private int doRunInstall(final InstallParams params) throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();
​
        ArrayList<String> args = getRemainingArgs();
​
        ...
​
        final int sessionId = doCreateSession(params.sessionParams,
                params.installerPackageName, params.userId);//创建Session
        boolean abandonSession = true;
        try {
            if (isStreaming) {
                if (doAddFiles(sessionId, args, params.sessionParams.sizeBytes, isApex)
                        != PackageInstaller.STATUS_SUCCESS) {
                    return 1;
                }
            } else {
                if (doWriteSplits(sessionId, args, params.sessionParams.sizeBytes, isApex)
                        != PackageInstaller.STATUS_SUCCESS) {//写入数据
                    return 1;
                }
            }
            if (doCommitSession(sessionId, false /*logSuccess*/)
                    != PackageInstaller.STATUS_SUCCESS) {//执行操作
                return 1;
            }
            abandonSession = false;
​
            if (params.sessionParams.isStaged && params.stagedReadyTimeoutMs > 0) {
                return doWaitForStagedSessionReady(sessionId, params.stagedReadyTimeoutMs, pw);
            }
​
            pw.println("Success");
            return 0;
        } 
    }      

很直接的分为三步:

  1. doCreateSession
  2. doWriteSplits
  3. doCommitSession

先看看doCreateSession

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java 
private int doCreateSession(SessionParams params, String installerPackageName, int userId)
            throws RemoteException {
        if (userId == UserHandle.USER_ALL) {
            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
        }
        final int translatedUserId =
                translateUserId(userId, UserHandle.USER_SYSTEM, "doCreateSession");//获取一个userid
        final int sessionId = mInterface.getPackageInstaller()
                .createSession(params, installerPackageName, null /*installerAttributionTag*/,
                        translatedUserId);
        return sessionId;
    }

通过一个IPC调用创建了一个Session。mInterface是一个IPackageManager,在 PackageManagerShellCommand创建的时候传入的

 //frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public class IPackageManagerImpl extends IPackageManagerBase {
 @Override
        public void onShellCommand(FileDescriptor in, FileDescriptor out,
                FileDescriptor err, String[] args, ShellCallback callback,
                ResultReceiver resultReceiver) {
            (new PackageManagerShellCommand(this, mContext,
                    mDomainVerificationManager.getShell()))
                    .exec(this, in, out, err, args, callback, resultReceiver);
        }
}
//frameworks/base/services/core/java/com/android/server/pm/IPackageManagerBase.java
  public final IPackageInstaller getPackageInstaller() {
        // Return installer service for internal calls.
        if (PackageManagerServiceUtils.isSystemOrRoot()) {
            return mInstallerService;
        }
       
    }

getPackageInstaller返回的就是PackageInstallerService,接着看PackageInstallerService的createSession。

//frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java
 @Override
    public int createSession(SessionParams params, String installerPackageName,
            String callingAttributionTag, int userId) {
        try {
            return createSessionInternal(params, installerPackageName, callingAttributionTag,
                    userId);
        } catch (IOException e) {
            throw ExceptionUtils.wrap(e);
        }
    }
​
    private int createSessionInternal(SessionParams params, String installerPackageName,
            String installerAttributionTag, int userId)
            throws IOException {
        final int callingUid = Binder.getCallingUid();
        final Computer snapshot = mPm.snapshotComputer();
      
      。。。。
​
        final int sessionId;
        final PackageInstallerSession session;
        synchronized (mSessions) {
            // Check that the installer does not have too many active sessions.
            final int activeCount = getSessionCount(mSessions, callingUid);
​
            final int historicalCount = mHistoricalSessionsByInstaller.get(callingUid);
​
            sessionId = allocateSessionIdLocked();
        }
        File stageDir = null;
        String stageCid = null;
        if (!params.isMultiPackage) {//根据sessionId创建安装时的临时目录
            if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
                stageDir = buildSessionDir(sessionId, params);
            } else {
                stageCid = buildExternalStageCid(sessionId);
            }
        }
        InstallSource installSource = InstallSource.create(installerPackageName,
                originatingPackageName, requestedInstallerPackageName,
                installerAttributionTag, params.packageSource);
        session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
                mSilentUpdatePolicy, mInstallThread.getLooper(), mStagingManager, sessionId,
                userId, callingUid, installSource, params, createdMillis, 0L, stageDir, stageCid,
                null, null, false, false, false, false, null, SessionInfo.INVALID_ID,
                false, false, false, PackageManager.INSTALL_UNKNOWN, "");//创建了一个PackageInstallerSession
​
        synchronized (mSessions) {
            mSessions.put(sessionId, session);
        }
        mPm.addInstallerPackageName(session.getInstallSource());
​
        return sessionId;
    }

重要部分就是创建了一个PackageInstallerSession,然后和sessionId绑定起来,把sessionId返回给调用方。

下面看doWriteSplits

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
    private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
            boolean logSuccess) throws RemoteException {
        PackageInstaller.Session session = null;
        try {
            session = new PackageInstaller.Session(
                    mInterface.getPackageInstaller().openSession(sessionId));//根据sessionid创建本地的session
​
            final PrintWriter pw = getOutPrintWriter();
​
            final ParcelFileDescriptor fd;
            if (STDIN_PATH.equals(inPath)) {
                fd = ParcelFileDescriptor.dup(getInFileDescriptor());
            } else if (inPath != null) {
                fd = openFileForSystem(inPath, "r");
                if (fd == null) {
                    return -1;
                }
                sizeBytes = fd.getStatSize();
                if (sizeBytes < 0) {
                    getErrPrintWriter().println("Unable to get size of: " + inPath);
                    return -1;
                }
            } else {
                fd = ParcelFileDescriptor.dup(getInFileDescriptor());
            }
            
            session.write(splitName, 0, sizeBytes, fd);//拿到fd将文件fd写入session
​
            if (logSuccess) {
                pw.println("Success: streamed " + sizeBytes + " bytes");
            }
            return 0;
        } catch (IOException e) {
            getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
            return 1;
        } finally {
            IoUtils.closeQuietly(session);
        }
    }
​

这部分很简单,就是获取文件fd,然后写入session中。

//frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java
    @Override
    public void write(String name, long offsetBytes, long lengthBytes,
            ParcelFileDescriptor fd) {
        assertCanWrite(fd != null);
        try {
            doWriteInternal(name, offsetBytes, lengthBytes, fd);
        } catch (IOException e) {
            throw ExceptionUtils.wrap(e);
        }
    } 
private ParcelFileDescriptor doWriteInternal(String name, long offsetBytes, long lengthBytes,
            ParcelFileDescriptor incomingFd) throws IOException {
        final RevocableFileDescriptor fd;
        final FileBridge bridge;
       
​
        try {
            // Use installer provided name for now; we always rename later
          
            final File target;
            final long identity = Binder.clearCallingIdentity();
            try {
                target = new File(stageDir, name);//创建暂存文件
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
​
            ParcelFileDescriptor targetPfd = openTargetInternal(target.getAbsolutePath(),
                    O_CREAT | O_WRONLY, 0644);
            Os.chmod(target.getAbsolutePath(), 0644);
            .....
​
            if (incomingFd != null) {
​
                try {//将数据写入暂存文件
                    final Int64Ref last = new Int64Ref(0);
                    FileUtils.copy(incomingFd.getFileDescriptor(), targetPfd.getFileDescriptor(),
                            lengthBytes, null, Runnable::run,
                            (long progress) -> {
                                if (params.sizeBytes > 0) {
                                    final long delta = progress - last.value;
                                    last.value = progress;
                                    synchronized (mProgressLock) {
                                        setClientProgressLocked(mClientProgress
                                                + (float) delta / (float) params.sizeBytes);
                                    }
                                }
                            });
                } 
    }

通过fd将文件复制到了暂存目录下。

最后就是通过doCommitSession安装

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
private int doCommitSession(int sessionId, boolean logSuccess)
            throws RemoteException {
​
        final PrintWriter pw = getOutPrintWriter();
        PackageInstaller.Session session = null;
        try {//也是根据sessionId创建session
            session = new PackageInstaller.Session(
                    mInterface.getPackageInstaller().openSession(sessionId));
          ...
            
            final LocalIntentReceiver receiver = new LocalIntentReceiver();//注册Receiver接受结果
            session.commit(receiver.getIntentSender());//调用commit
            if (!session.isStaged()) {
                final Intent result = receiver.getResult();
                final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                        PackageInstaller.STATUS_FAILURE);
                if (status == PackageInstaller.STATUS_SUCCESS) {
                    if (logSuccess) {
                        pw.println("Success");
                    }
                } else {
                    pw.println("Failure ["
                            + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
                }
                return status;
            } 
    }

也看下PackageInstallerSession中的commit。

//frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java
public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
        
        ....
        dispatchSessionSealed();
    }
    private void dispatchSessionSealed() {
        mHandler.obtainMessage(MSG_ON_SESSION_SEALED).sendToTarget();//发送MSG_ON_SESSION_SEALED执行handleSessionSealed
    }
 private void handleSessionSealed() {
        assertSealed("dispatchSessionSealed");
        // Persist the fact that we've sealed ourselves to prevent
        // mutations of any hard links we create.
        mCallback.onSessionSealedBlocking(this);
        dispatchStreamValidateAndCommit();
    }
​
    private void dispatchStreamValidateAndCommit() {
        mHandler.obtainMessage(MSG_STREAM_VALIDATE_AND_COMMIT).sendToTarget();//发送MSG_STREAM_VALIDATE_AND_COMMIT 
    }
​
  .....
    
  private final Handler.Callback mHandlerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_ON_SESSION_SEALED:
                    handleSessionSealed();
                    break;
                case MSG_STREAM_VALIDATE_AND_COMMIT:
                    handleStreamValidateAndCommit();//在这里回做初步的apk解析获得PackageLite
                    break;
                case MSG_INSTALL:
                    handleInstall();
                    break;
                case MSG_ON_PACKAGE_INSTALLED:
                    final SomeArgs args = (SomeArgs) msg.obj;
                    final String packageName = (String) args.arg1;
                    final String message = (String) args.arg2;
                    final Bundle extras = (Bundle) args.arg3;
                    final IntentSender statusReceiver = (IntentSender) args.arg4;
                    final int returnCode = args.argi1;
                    args.recycle();
​
                    sendOnPackageInstalled(mContext, statusReceiver, sessionId,
                            isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId,
                            packageName, returnCode, message, extras);
​
                    break;
                case MSG_SESSION_VALIDATION_FAILURE:
                    final int error = msg.arg1;
                    final String detailMessage = (String) msg.obj;
                    onSessionValidationFailure(error, detailMessage);
                    break;
            }
​
            return true;
        }
    };

handle作为状态机通过发送消息最后到handleInstall执行安装。

//frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java
@WorkerThread
    private void handleInstall() {
        ...
          
        if (sendPendingUserActionIntentIfNeeded()) {//如果一个Session 需要用户操作,则停止整个Session集的安装
            return;
        }
​
        if (params.isStaged) {
            mStagedSession.verifySession();
        } else {
            verify();//进行一些签名包名等判断
        }
    }
 private void verify() {
         
            ....
            verifyNonStaged();  
    }
 private void verifyNonStaged()
            throws PackageManagerException {
        mSessionProvider.getSessionVerifier().verify(this, (error, msg) -> {
          //verify之后的回调
            mHandler.post(() -> {
                if (error == INSTALL_SUCCEEDED) {
                    onVerificationComplete();
                } else {
                    onSessionVerificationFailure(error, msg);
                }
            });
        });
    }
private void onVerificationComplete() {
  ....
  install();
}
​

最后都会进入verify中进行安装前的判断,经过一系列的判断通过install安装

   private CompletableFuture<Void> install() {
        List<CompletableFuture<InstallResult>> futures = installNonStaged();
       ....
    }
 private List<CompletableFuture<InstallResult>> installNonStaged() {
            List<CompletableFuture<InstallResult>> futures = new ArrayList<>();
            CompletableFuture<InstallResult> future = new CompletableFuture<>();
            futures.add(future);
            final InstallParams installingSession = makeInstallParams(future);
            installingSession.installStage();
            ......
              
            return futures;
​
    }
​

最后通过installingSession.installStage();来执行安装。

//frameworks/base/services/core/java/com/android/server/pm/InstallParams.java
public void installStage() {
        final Message msg = mPm.mHandler.obtainMessage(INIT_COPY);
        msg.obj = this;
        mPm.mHandler.sendMessage(msg);
    }

installStage通过PMS的handle发送INIT_COPY,将操作都交给了PMS。mHandler初始化在PackageManagerService的构造函数中。

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java  
mHandler = injector.getHandler();             
//frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
    public Handler getHandler() {
        return mHandlerProducer.get(this, mPackageManager);
    }
​

在上一篇中已经了解了injector就是PackageManagerServiceInjector,mHandlerProducer是在PackageManagerServiceInjector初始化的时候传入的。

(i, pm) -> {
                    HandlerThread thread = new ServiceThread(TAG,
                            Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
                    thread.start();
                    return new PackageHandler(thread.getLooper(), pm);
                }

mHandler就是一个PackageHandler变量,找到INIT_COPY。

INIT_COPY

//frameworks/base/services/core/java/com/android/server/pm/PackageHandler.java
void doHandleMessage(Message msg) {
        switch (msg.what) {
            case INIT_COPY: {
                HandlerParams params = (HandlerParams) msg.obj;//InstallParams中传的是this
                if (params != null) {   
                    params.startCopy();
                }
                break;
            }
            ....
        }
  //frameworks/base/services/core/java/com/android/server/pm/HandlerParams.java
  final void startCopy() {
​
        handleStartCopy();//调用的就是InstallParams的handleStartCopy        
        handleReturnCode();//InstallParams的handleReturnCode        
    }

回到InstallParams中看下实现

 public void handleStartCopy() {
​
        //获取基础的包信息
        PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mPm.mContext,
                mPackageLite, mOriginInfo.mResolvedPath, mInstallFlags, mPackageAbiOverride);
      
      ....
        
        mRet = overrideInstallLocation(pkgLite.packageName, pkgLite.recommendedInstallLocation,
                pkgLite.installLocation);//覆盖安装的话要根据原来的安装信息修改
    }
​

handleStartCopy只是一些准备操作,实际copy在handleReturnCode

//frameworks/base/services/core/java/com/android/server/pm/InstallParams.java
 @Override
    void handleReturnCode() {
        processPendingInstall();
    }
​
    private void processPendingInstall() {
        InstallArgs args = createInstallArgs(this);//创建的是一个FileInstallArgs
        if (mRet == PackageManager.INSTALL_SUCCEEDED) {
            mRet = args.copyApk();//FileInstallArgs的copy复制apk
        }
        if (mParentInstallParams != null) {
            mParentInstallParams.tryProcessInstallRequest(args, mRet);
        } else {
            PackageInstalledInfo res = new PackageInstalledInfo(mRet);
            processInstallRequestsAsync(
                    res.mReturnCode == PackageManager.INSTALL_SUCCEEDED,
                    Collections.singletonList(new InstallRequest(args, res)));//安装
        }
    }
​

copyApk

//frameworks/base/services/core/java/com/android/server/pm/FileInstallArgs.java
int copyApk() { 
            return doCopyApk();
    }
​
    private int doCopyApk() {
            .....
            final boolean isEphemeral = (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;            //创建目录
            final File tempDir =
                    mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
            mCodeFile = tempDir;
     
      //复制apk文件
        int ret = PackageManagerServiceUtils.copyPackage(
                mOriginInfo.mFile.getAbsolutePath(), mCodeFile);
        if (ret != PackageManager.INSTALL_SUCCEEDED) {
            Slog.e(TAG, "Failed to copy package");
            return ret;
        }
​
        final boolean isIncremental = isIncrementalPath(mCodeFile.getAbsolutePath());
        final File libraryRoot = new File(mCodeFile, LIB_DIR_NAME);//创建lib目录
        NativeLibraryHelper.Handle handle = null;
        handle = NativeLibraryHelper.Handle.create(mCodeFile);
        ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                    mAbiOverride, isIncremental);//复制so库
        return ret;
    }
//frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
 public static int copyPackage(String packagePath, File targetDir) {
​
        try {
            final File packageFile = new File(packagePath);
            final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
            final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
                    input.reset(), packageFile, /* flags */ 0);//获取简单解析结果和PMS启动时一样
​
            final PackageLite pkg = result.getResult();
            copyFile(pkg.getBaseApkPath(), targetDir, "base.apk");//复制apk到目标目录下,apk文件名是base.apk,所以在手机中安装之后apk都叫base.apk      
            return PackageManager.INSTALL_SUCCEEDED;
    }
   
​

processInstallRequestsAsync

//frameworks/base/services/core/java/com/android/server/pm/InstallParams.java
 private void processInstallRequestsAsync(boolean success,
            List<InstallRequest> installRequests) {
        mPm.mHandler.post(() -> {
            mInstallPackageHelper.processInstallRequests(success, installRequests);
        });
 //frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
    public void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
        .....
​
        if (success) {
            for (InstallRequest request : apkInstallRequests) {
                request.mArgs.doPreInstall(request.mInstallResult.mReturnCode);
            }
            synchronized (mPm.mInstallLock) {
                installPackagesTracedLI(apkInstallRequests);//执行安装
            }
            for (InstallRequest request : apkInstallRequests) {
                request.mArgs.doPostInstall(
                        request.mInstallResult.mReturnCode, request.mInstallResult.mUid);
            }
        }
        for (InstallRequest request : apkInstallRequests) {
            restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
                    request.mInstallResult,
                    new PostInstallData(request.mArgs,
                            request.mInstallResult, null));
        }
    }

其中安装部分分三步

  1. doPreInstall 清除无用信息
  2. installPackagesTracedLI 执行安装
  3. doPostInstall
//frameworks/base/services/core/java/com/android/server/pm/FileInstallArgs.java
int doPreInstall(int status) {
        if (status != PackageManager.INSTALL_SUCCEEDED) {
            cleanUp();
        }
        return status;
    }

重点是installPackagesTracedLI

//frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
 private void installPackagesTracedLI(List<InstallRequest> requests) {
        installPackagesLI(requests);
    }
  private void installPackagesLI(List<InstallRequest> requests) {
        boolean success = false;
        try {
           
            for (InstallRequest request : requests) {
              
                final PrepareResult prepareResult;
​
                    prepareResult =
                            preparePackageLI(request.mArgs, request.mInstallResult);//预处理数据
​
                request.mInstallResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                request.mInstallResult.mInstallerPackageName =
                        request.mArgs.mInstallSource.installerPackageName;
​
                final String packageName = prepareResult.mPackageToScan.getPackageName();
                prepareResults.put(packageName, prepareResult);
                installResults.put(packageName, request.mInstallResult);
                installArgs.put(packageName, request.mArgs);
                try {
                    final ScanResult result = scanPackageTracedLI(
                            prepareResult.mPackageToScan, prepareResult.mParseFlags,
                            prepareResult.mScanFlags, System.currentTimeMillis(),
                            request.mArgs.mUser, request.mArgs.mAbiOverride);//scan包数据
                   
                    createdAppId.put(packageName, optimisticallyRegisterAppId(result));
                    versionInfos.put(result.mPkgSetting.getPkg().getPackageName(),
                            mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg()));
                } catch (PackageManagerException e) {
                    request.mInstallResult.setError("Scanning Failed.", e);
                    return;
                }
            }
            ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
                    installResults, prepareResults,
                    Collections.unmodifiableMap(mPm.mPackages), versionInfos);//调和数据
            CommitRequest commitRequest = null;
            synchronized (mPm.mLock) {
                Map<String, ReconciledPackage> reconciledPackages;
                try {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
                    reconciledPackages = ReconcilePackageUtils.reconcilePackages(
                            reconcileRequest, mSharedLibraries,
                            mPm.mSettings.getKeySetManagerService(), mPm.mSettings);
                } catch (ReconcileFailure e) {
                    for (InstallRequest request : requests) {
                        request.mInstallResult.setError("Reconciliation failed...", e);
                    }
                    return;
                } finally {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
                try {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
                    commitRequest = new CommitRequest(reconciledPackages,
                            mPm.mUserManager.getUserIds());
                    commitPackagesLocked(commitRequest);//更新包信息
                    success = true;
                } finally {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
            }
            executePostCommitSteps(commitRequest);//完成安装
        } finally {
           
        }
    }

这里又分为5步

  1. preparePackageLI
  2. scanPackageTracedLI
  3. ReconcileRequest
  4. commitPackagesLocked
  5. executePostCommitSteps
preparePackageLI

这个方法特别长

//frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
 private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
            throws PrepareFailure {
        .....
      
        final ParsedPackage parsedPackage;//获取PackageParser2来解析文件
        try (PackageParser2 pp = mPm.mInjector.getPreparingPackageParser()) {
            parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
            AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
        } catch (PackageManagerException e) {
            throw new PrepareFailure("Failed parse during installPackageLI", e);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
​
        ....
        if (parsedPackage.isStaticSharedLibrary()) {//静态共享库
            // Static shared libraries have synthetic package names
            PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
​
        }
​
        boolean systemApp = false;
        boolean replace = false;
        synchronized (mPm.mLock) {
            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {//覆盖安装
                ....
                if (replace) {//判断覆盖安装的各种异常
                   ....
                }
            }
​
            PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
            PackageSetting signatureCheckPs = ps;
​
​
            if (parsedPackage.isStaticSharedLibrary()) {//共享库升级
                SharedLibraryInfo libraryInfo =
                        mSharedLibraries.getLatestStaticSharedLibraVersionLPr(parsedPackage);
                if (libraryInfo != null) {
                    signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName());
                }
            }
​
            if (signatureCheckPs != null) {
​
                final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
                final SharedUserSetting signatureCheckSus = mPm.mSettings.getSharedUserSettingLPr(
                        signatureCheckPs);
                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, signatureCheckSus,
                        scanFlags)) {//校验安装包签名
                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
                        throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
                                + parsedPackage.getPackageName() + " upgrade keys do not match the "
                                + "previously installed version");
                    }
                } 
            }
​
            //下面是权限相关代码,太长了就不详细看了
          
          ....
​
  
        if (args.mMoveInfo != null) {
            scanFlags |= SCAN_NO_DEX;
            scanFlags |= SCAN_MOVE;
​
            synchronized (mPm.mLock) {
                final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
              //设置abi
                parsedPackage.setPrimaryCpuAbi(ps.getPrimaryCpuAbi())
                        .setSecondaryCpuAbi(ps.getSecondaryCpuAbi());
            }
​
        } else {
            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
            scanFlags |= SCAN_NO_DEX;
​
            try {
                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
                        derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage,
                        isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
                        abiOverride, ScanPackageUtils.getAppLib32InstallDir());//生成安装包Abi
                derivedAbi.first.applyTo(parsedPackage);
                derivedAbi.second.applyTo(parsedPackage);
            } 
        }
​
​
​
        final PackageFreezer freezer =
                freezePackageForInstall(pkgName, installFlags, "installPackageLI");
        boolean shouldCloseFreezerBeforeReturn = true;
        try {
​
            if (replace) {//如果是替换安装证书之类的处理
               
            } else { // 新包安装
               
            }
​
            return new PrepareResult(replace, targetScanFlags, targetParseFlags,
                    oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
                    ps, disabledPs);
        } finally {
        }
    }
}

准备工作完成。接下来扫描apk

scanPackageTracedLI
  private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
            final @ParsingPackageUtils.ParseFlags int parseFlags,
            @PackageManagerService.ScanFlags int scanFlags, long currentTime,
            @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException {
  
            return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
                    cpuAbiOverride);
​
    }
 private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
            final @ParsingPackageUtils.ParseFlags int parseFlags,
            @PackageManagerService.ScanFlags int scanFlags, long currentTime,
            @Nullable UserHandle user, String cpuAbiOverride)
            throws PackageManagerException {
        ....
        synchronized (mPm.mLock) {
            .....
            return ScanPackageUtils.scanPackageOnlyLI(request, mPm.mInjector, mPm.mFactoryTest,
                    currentTime);
        }
    }

具体的扫描在scanPackageOnlyLI中

//frameworks/base/services/core/java/com/android/server/pm/ScanPackageUtils.java
 public static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
            PackageManagerServiceInjector injector,
            boolean isUnderFactoryTest, long currentTime)
            throws PackageManagerException {
        ......
​
        // Initialize package source and resource directories
        final File destCodeFile = new File(parsedPackage.getPath());//初始化目标文件夹
​
        final UUID newDomainSetId = injector.getDomainVerificationManagerInternal().generateNewId();
​
        final boolean createNewPackage = (pkgSetting == null);
        if (createNewPackage) {//如果是新的apk
            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
​
            int pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, null);
            int pkgPrivateFlags = PackageInfoUtils.appInfoPrivateFlags(parsedPackage, null);
​
          
            pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
                    originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
                    destCodeFile, parsedPackage.getNativeLibraryRootDir(),
                    AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
                    AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
                    parsedPackage.getLongVersionCode(), pkgFlags, pkgPrivateFlags, user,
                    true /*allowInstall*/, instantApp, virtualPreload,
                    UserManagerService.getInstance(), usesSdkLibraries,
                    parsedPackage.getUsesSdkLibrariesVersionsMajor(), usesStaticLibraries,
                    parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
                    newDomainSetId);//创建一个新的PackageSetting,保存了包所以的配置
          
        } else {//如果已存在就更新setting
          ...
        }
     
​
        final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
     
        pkgSetting.setLegacyNativeLibraryPath(parsedPackage.getNativeLibraryRootDir());
​
      
        // 更新安装时间
        final long scanFileTime = getLastModifiedTime(parsedPackage);
        final long existingFirstInstallTime = userId == UserHandle.USER_ALL
                ? PackageStateUtils.getEarliestFirstInstallTime(pkgSetting.getUserStates())
                : pkgSetting.readUserState(userId).getFirstInstallTime();
        if (currentTime != 0) {
            if (existingFirstInstallTime == 0) {
                pkgSetting.setFirstInstallTime(currentTime, userId)
                        .setLastUpdateTime(currentTime);
            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
                pkgSetting.setLastUpdateTime(currentTime);
            }
        } else if (existingFirstInstallTime == 0) {
            // We need *something*.  Take time stamp of the file.
            pkgSetting.setFirstInstallTime(scanFileTime, userId)
                    .setLastUpdateTime(scanFileTime);
        } else if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0) {
            if (scanFileTime != pkgSetting.getLastModifiedTime()) {
                // A package on the system image has changed; consider this
                // to be an update.
                pkgSetting.setLastUpdateTime(scanFileTime);
            }
        }
        pkgSetting.setLastModifiedTime(scanFileTime);
​
        pkgSetting.setPkg(parsedPackage)
                .setPkgFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
                        PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting));
        if (parsedPackage.getLongVersionCode() != pkgSetting.getVersionCode()) {
          //更新VersionCode
            pkgSetting.setLongVersionCode(parsedPackage.getLongVersionCode());
        }
​
        return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
                !createNewPackage /* existingSettingCopied */,
                Process.INVALID_UID /* previousAppId */ , sdkLibraryInfo,
                staticSharedLibraryInfo, dynamicSharedLibraryInfos);
    }

一个apk所有的信息都已经解析出来保存了起来,利用commitPackagesLocked提交

commitPackagesLocked
 private void commitPackagesLocked(final CommitRequest request) {
        for (ReconciledPackage reconciledPkg : request.mReconciledPackages.values()) {
          .....
                        // 如果有老的包就删除
                        deletePackageHelper.executeDeletePackageLIF(
                                reconciledPkg.mDeletePackageAction, packageName,
                                true, request.mAllUsers, false);
​
            AndroidPackage pkg = commitReconciledScanResultLocked(
                    reconciledPkg, request.mAllUsers);//提交结果
            updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, res);//更新Settings
​
            ....
    }
​

commitPackagesLocked主要功能就是删除老包,将解析出来的settings提交给PMS

executePostCommitSteps
 private void executePostCommitSteps(CommitRequest commitRequest) {
        final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
        for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) {
      
           // 创建AppData相关文件夹
            mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0);
           //创建AppProfile文件
            mArtManagerService.prepareAppProfiles(
                    pkg,
                    mPm.resolveUserIds(reconciledPkg.mInstallArgs.mUser.getIdentifier()),
                    /* updateReferenceProfileContent= */ true);
          //判断是否需要执行Dexopt
            final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
                    | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
                    | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
            
            DexoptOptions dexoptOptions =
                    new DexoptOptions(packageName, compilationReason, dexoptFlags);
​
            if (performDexopt) {/
              ....
​
                mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
                        null /* instructionSets */,
                        mPm.getOrCreateCompilerPackageStats(pkg),
                        mDexManager.getPackageUseInfoOrDefault(packageName),
                        dexoptOptions);//执行DexOpt
             
            }
            //notify包更新的消息
            BackgroundDexOptService.getService().notifyPackageChanged(packageName);
            notifyPackageChangeObserversOnUpdate(reconciledPkg);
        }
        PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental(
                incrementalStorages);
    }

主要看下prepareAppDataPostCommitLIF

//frameworks/base/services/core/java/com/android/server/pm/AppDataHelper.java
 public void prepareAppDataPostCommitLIF(AndroidPackage pkg, int previousAppId) {
        final PackageSetting ps;
        synchronized (mPm.mLock) {
            ps = mPm.mSettings.getPackageLPr(pkg.getPackageName());
            mPm.mSettings.writeKernelMappingLPr(ps);
        }
        for (UserInfo user : umInternal.getUsers(false /*excludeDying*/)) {
​
            if (ps.getInstalled(user.id)) {//获取
            //创建AppData文件夹
                prepareAppData(batch, pkg, previousAppId, user.id, flags).thenRun(() -> {
                      //完成之后的回调
                    if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
                      
                        int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
                        smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
                    }
                });
            }
        }
    }
   private @NonNull CompletableFuture<?> prepareAppData(@NonNull Installer.Batch batch,
            @Nullable AndroidPackage pkg, int previousAppId, int userId,
            @StorageManager.StorageFlags int flags) {
        return prepareAppDataLeaf(batch, pkg, previousAppId, userId, flags);
   }
 private @NonNull CompletableFuture<?> prepareAppDataLeaf(@NonNull Installer.Batch batch,
            @NonNull AndroidPackage pkg, int previousAppId, int userId, int flags) {
     
        return batch.createAppData(args).whenComplete((ceDataInode, e) -> {
            
    }

创建的是一个 CompletableFuture,看下execute

 public synchronized void execute(@NonNull Installer installer) throws InstallerException {
            mExecuted = true;
                final CreateAppDataResult[] results = installer.createAppDataBatched(args);
​
        }

经过层层调用到Installd服务的createAppDataBatched

//frameworks/native/cmds/installd/InstalldNativeService.cpp  
binder::Status InstalldNativeService::createAppDataBatched(
        const std::vector<android::os::CreateAppDataArgs>& args,
        std::vector<android::os::CreateAppDataResult>* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    // Locking is performed depeer in the callstack.
​
    std::vector<android::os::CreateAppDataResult> results;
    for (const auto &arg : args) {
        android::os::CreateAppDataResult result;
        createAppData(arg, &result);//会根据packagename创建/data/app/<packageName>等目录
        results.push_back(result);
    }
    *_aidl_return = results;
    return ok();
}

这样经过漫长的调用一次安装就结束了。