classPackageHandlerextendsHandler { ... voiddoHandleMessage(Message msg) { switch (msg.what) { case INIT_COPY: { HandlerParamsparams= (HandlerParams) msg.obj; intidx= 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) { // 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(); 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; } case MCS_BOUND: { if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); if (msg.obj != null) { mContainerService = (IMediaContainerService) msg.obj; } if (mContainerService == null) { ... } elseif (mPendingInstalls.size() > 0) { HandlerParamsparams= mPendingInstalls.get(0); if (params != null) { if (params.startCopy()) { // We are done... look for more work or to // go idle. // Delete pending install if (mPendingInstalls.size() > 0) { mPendingInstalls.remove(0); } if (mPendingInstalls.size() == 0) { if (mBound) { if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting delayed MCS_UNBIND"); removeMessages(MCS_UNBIND); Messageubmsg= 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); } } } } else { // Should never happen ideally. Slog.w(TAG, "Empty queue"); } break; } } ... } ... }
if (ret == PackageManager.INSTALL_SUCCEEDED) { ... if (!origin.existing && requiredUid != -1 && isVerificationEnabled(userIdentifier, installFlags)) { ... if (ret == PackageManager.INSTALL_SUCCEEDED && mRequiredVerifierPackage != null) { /* * Send the intent to the required verification agent, * but only start the verification timeout after the * target BroadcastReceivers have run. */ verification.setComponent(requiredVerifierComponent); mContext.sendOrderedBroadcastAsUser(verification, getUser(), android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, newBroadcastReceiver() { @Override publicvoidonReceive(Context context, Intent intent) { finalMessagemsg= mHandler .obtainMessage(CHECK_PENDING_VERIFICATION); msg.arg1 = verificationId; mHandler.sendMessageDelayed(msg, getVerificationTimeout()); } }, null, 0, null, null);
/* * We don't want the copy to proceed until verification * succeeds, so null out this field. */ mArgs = null; } } else { /* * No package verification is enabled, so immediately start * the remote call to initiate copy using temporary file. */ ret = args.copyApk(mContainerService, true); } } } ... }
updateSettingsLI(newPackage, installerPackageName, null, null, res); // delete the partially installed application. the data directory will have to be // restored if it was already existing if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { // remove package from internal structures. Note that we want deletePackageX to // delete the package data and cache directories that it created in // scanPackageLocked, unless those directories existed before we even tried to // install. deletePackageLI(pkgName, UserHandle.ALL, false, null, null, dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, res.removedInfo, true); }
} catch (PackageManagerException e) { res.setError("Package couldn't be installed in " + pkg.codePath, e); } } ... }
publicclassPackageManagerServiceextendsIPackageManager.Stub { ... private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)throws PackageManagerException { booleansuccess=false; try { final PackageParser.Packageres= scanPackageDirtyLI(pkg, parseFlags, scanFlags, currentTime, user); success = true; return res; } finally { if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { removeDataDirsLI(pkg.packageName); } } } ... private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)throws PackageManagerException { ... // writer synchronized (mPackages) { // 验证已注册的ContentProvider是否有其他同名 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { finalintN= pkg.providers.size(); int i; for (i=0; i<N; i++) { PackageParser.Providerp= pkg.providers.get(i); if (p.info.authority != null) { String names[] = p.info.authority.split(";"); for (intj=0; j < names.length; j++) { if (mProvidersByAuthority.containsKey(names[j])) { PackageParser.Providerother= mProvidersByAuthority.get(names[j]); finalStringotherPackageName= ((other != null && other.getComponentName() != null) ? other.getComponentName().getPackageName() : "?"); thrownewPackageManagerException( INSTALL_FAILED_CONFLICTING_PROVIDER, "Can't install because provider name " + names[j] + " (in package " + pkg.applicationInfo.packageName + ") is already used by " + otherPackageName); } } } } } } if (mPlatformPackage == pkg) { ... } else { // This is a normal package, need to make its data directory. dataPath = getDataPathForPackage(pkg.packageName, 0); if (dataPath.exists()) { ... } else { //invoke installer to do the actual installation //这里创建了应用数据目录,用于存放用户数据 intret= createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo); ... } } // We also need to dexopt any apps that are dependent on this library. Note that // if these fail, we should abort the install since installing the library will // result in some apps being broken. if (clientLibPkgs != null) { if ((scanFlags & SCAN_NO_DEX) == 0) { for (inti=0; i < clientLibPkgs.size(); i++) { PackageParser.PackageclientPkg= clientLibPkgs.get(i); if (performDexOptLI(clientPkg, null/* instruction sets */, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) { thrownewPackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI failed to dexopt clientLibPkgs"); } } } } // writer synchronized (mPackages) { ... // 以下对四大组件进行注册 intN= pkg.providers.size(); StringBuilderr=null; int i; for (i=0; i<N; i++) { PackageParser.Providerp= pkg.providers.get(i); p.info.processName = fixProcessName(pkg.applicationInfo.processName, p.info.processName, pkg.applicationInfo.uid); mProviders.addProvider(p); ... } ... } } ... }
publicclassPackageManagerServiceextendsIPackageManager.Stub { ... privatevoidprocessPendingInstall(final InstallArgs args, finalint currentStatus) { // Queue up an async operation since the package installation may take a little while. mHandler.post(newRunnable() { publicvoidrun() { ... if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { IBackupManagerbm= IBackupManager.Stub.asInterface( ServiceManager.getService(Context.BACKUP_SERVICE)); if (bm != null) { if (DEBUG_INSTALL) Log.v(TAG, "token " + token + " to BM for possible restore"); try { if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); } else { doRestore = false; } } catch (RemoteException e) { // can't happen; the backup manager is local } catch (Exception e) { Slog.e(TAG, "Exception trying to enqueue restore", e); doRestore = false; } } else { Slog.e(TAG, "Backup Manager not found!"); doRestore = false; } } if (!doRestore) { // No restore possible, or the Backup Manager was mysteriously not // available -- just fire the post-install work request directly. if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); Messagemsg= mHandler.obtainMessage(POST_INSTALL, token, 0); mHandler.sendMessage(msg); } ... } } } ... }