Android PackageManagerService(二)下载安装详解
下载安装可分为两部分:拷贝应用和安装应用。拷贝过程的函数调用时序图如图2所示
frameworks层的入口函数为PackageManager.installPackage,由应用市场APP调用,然后调用PMS.installPackageAsUser,然后发送消息INIT_COPY、MCS_BOUND开始复制,调用HandlerParams.startCopy。这个方法主要分两部分,一部分是拷贝应用的执行程序,另一部分是创建应用的数据目录,拷贝部分由handleStartCopy完成。之后调用handlerReturnCode来处理创建数据目录。拷贝部分会调用DefaultContainerService来完成,该服务为那些可能位于可删除空间上的文件提供检查和拷贝功能。当底层设置被移除时,这样设计可以防止系统进程保留打开的文件时,不被内核杀死。
handleStartcopy实现在PMS内部类InstallParams中,它的功能是调用远程方法获取包信息和安装位置,下面我们结合关键代码做进一步分析。
@Override
public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
int installFlags, String installerPackageName, int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
final int callingUid = Binder.getCallingUid();
//确认权限
enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
//adb安装
if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
installFlags |= PackageManager.INSTALL_FROM_ADB;
} else {
// Caller holds INSTALL_PACKAGES permission, so we're less strict
// about installerPackageName.
installFlags &= ~PackageManager.INSTALL_FROM_ADB;
installFlags &= ~PackageManager.INSTALL_ALL_USERS;
}
UserHandle user;
//所有用户
if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
} else {
user = new UserHandle(userId);
}
// Only system components can circumvent runtime permissions when installing.
//权限校验
if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
&& mContext.checkCallingOrSelfPermission(Manifest.permission
.INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
throw new SecurityException("You need the "
+ "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
+ "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
}
if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
|| (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
throw new IllegalArgumentException(
"New installs into ASEC containers no longer supported");
}
final File originFile = new File(originPath);
final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
final Message msg = mHandler.obtainMessage(INIT_COPY);
params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
//发送拷贝的消息
mHandler.sendMessage(msg);
}
接收消息
//PackageHandler.doHandleMessage
void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {
HandlerParams params = (HandlerParams) msg.obj;
int idx = mPendingInstalls.size();
if (!mBound) {
//连接服务,当服务绑定好之后,会在发一个MCS_BOUND消息
if (!connectToService()) {
Slog.e(TAG, "Failed to bind to media container service");
params.serviceError();
if (params.traceMethod != null) {
}
return;
} else {
添加到任务队列
mPendingInstalls.add(idx, params);
}
} else {
mPendingInstalls.add(idx, params);
if (idx == 0) {
//发送一个已经绑定的消息
mHandler.sendEmptyMessage(MCS_BOUND);
}
}
break;
}
接收MCS_BOUND消息
//PackageHandler.doHandleMessage
case MCS_BOUND: {
if (msg.obj != null) {
//获取服务
mContainerService = (IMediaContainerService) msg.obj;
}
if (mContainerService == null) {
//如果没有绑定清空队列
if (!mBound) {
for (HandlerParams params : mPendingInstalls) {
params.serviceError();
return;
}
mPendingInstalls.clear();
}
} else if (mPendingInstalls.size() > 0) {
HandlerParams params = mPendingInstalls.get(0);
if (params != null) {
//调用startCopy
if (params.startCopy()) {
if (mPendingInstalls.size() > 0) {
mPendingInstalls.remove(0);
}
if (mPendingInstalls.size() == 0) {
if (mBound) {
removeMessages(MCS_UNBIND);
Message ubmsg = obtainMessage(MCS_UNBIND);
sendMessageDelayed(ubmsg, 10000);
}
} else {
mHandler.sendEmptyMessage(MCS_BOUND);
}
}
}
}
break;
}
获取HandlerParams 并调用startCopy
// [InstallParams.startCopy]
final boolean startCopy() {
boolean res;
try {
if (++mRetries > MAX_RETRIES) {
mHandler.sendEmptyMessage(MCS_GIVE_UP);
handleServiceError();
return false;
} else {
handleStartCopy();
res = true;
}
} catch (RemoteException e) {
mHandler.sendEmptyMessage(MCS_RECONNECT);
res = false;
}
handleReturnCode();
return res;
}
尝试处理4次,如果成功调用handleReturnCode,否则返回错误。
接下来进入InstallParams.handleStartCopy方法看一下。
// [InstallParams.handleStartCopy]
public void handleStartCopy() throws RemoteException {
int ret = PackageManager.INSTALL_SUCCEEDED;
// 首先检查文件和cid是否已生成,如生成则设置installFlags。
if (origin.staged) {
if (origin.file != null) {
installFlags |= PackageManager.INSTALL_INTERNAL;
installFlags &= ~PackageManager.INSTALL_EXTERNAL;
} else if (origin.cid != null) {
installFlags |= PackageManager.INSTALL_EXTERNAL;
installFlags &= ~PackageManager.INSTALL_INTERNAL;
} else {
throw new IllegalStateException("Invalid stage location");
}
}
//在sd卡
final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
//在内部存储
final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
//免安装app
final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
PackageInfoLite pkgLite = null;
if (onInt && onSd) {
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} else if (onSd && ephemeral) {
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} else {
pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
packageAbiOverride);
/*
* 然后检查空间大小,如果空间不够则释放无用空间。
*/
if (!origin.staged && pkgLite.recommendedInstallLocation
== PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
// TODO: 集中释放目标设备上的磁盘空间
final StorageManager storage = StorageManager.from(mContext);
//最小临界值
final long lowThreshold = storage.getStorageLowBytes(
Environment.getDataDirectory());
//计算所需空间的大小
final long sizeBytes = mContainerService.calculateInstalledSize(
origin.resolvedPath, isForwardLocked(), packageAbiOverride);
try {
//释放缓存
mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
//获取轻量级的包信息
pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
installFlags, packageAbiOverride);
} catch (InstallerException e) {
Slog.w(TAG, "Failed to free cache", e);
}
}
}
//覆盖原有安装位置的文件,并根据返回结果来确定函数的返回值,并设置installFlags。
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 {
// 更具安装策略获取安装位置
loc = installLocationPolicy(pkgLite);
if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
} else if (!onSd && !onInt) {
// Override install location with flags
if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
// Set the flag to install on external media.
installFlags |= PackageManager.INSTALL_EXTERNAL;
installFlags &= ~PackageManager.INSTALL_INTERNAL;
} else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
}
installFlags |= PackageManager.INSTALL_INSTANT_APP;
installFlags &= ~(PackageManager.INSTALL_EXTERNAL
|PackageManager.INSTALL_INTERNAL);
} else {
// Make sure the flag for installing on external
// media is unset
installFlags |= PackageManager.INSTALL_INTERNAL;
installFlags &= ~PackageManager.INSTALL_EXTERNAL;
}
}
}
}
//创建安装参数
final InstallArgs args = createInstallArgs(this);
mArgs = args;
if (ret == PackageManager.INSTALL_SUCCEEDED) {
//确定我们是否安装了包验证器。如果我们这样做,那么我们将遵从他们来验证软件包。
final int requiredUid = mRequiredVerifierPackage == null ? -1
: getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
verifierUser.getIdentifier());
final int installerUid =
verificationInfo == null ? -1 : verificationInfo.installerUid;
....省略包验证,一般安装不走这个流程
....确定是否有任何已安装的包验证器,如有,则延迟检测。主要分三步:
首先新建一个验证Intent,然后设置相关的信息,之后获取验证器列表,最后向每个验证器发送验证Intent。
/*
*没有启用包验证,因此立即启动远程调用,使用临时文件初始化复制。
*/
ret = args.copyApk(mContainerService, true);
}
mRet = ret;
}
向验证器客户端发送intent,只有当验证成功之后才会开启copy工作。如果没有任何验证器则直接拷贝。
接着调用InstallArgs.copyApk方法,手机内部存储安装子类为FileInstallArgs
//FileInstallArgs.copyApk
int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
try {
return doCopyApk(imcs, temp);
} finally {
}
}
////FileInstallArgs.doCopyApk
private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
//如果已经确定位置直接返回
if (origin.staged) {
codeFile = origin.file;
resourceFile = origin.file;
return PackageManager.INSTALL_SUCCEEDED;
}
try {
final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
//创建临时目录
final File tempDir =
mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
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;
//从把原始包拷贝到data\app\临时目录下面
ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
if (ret != PackageManager.INSTALL_SUCCEEDED) {
Slog.e(TAG, "Failed to copy package");
return ret;
}
final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(codeFile);
//拷贝native库
ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
abiOverride);
} catch (IOException e) {
Slog.e(TAG, "Copying native libraries failed", e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
} finally {
IoUtils.closeQuietly(handle);
}
return ret;
}
跨进程调用,防止阻塞当前进程
//DefaultContainerService.copyPackage
//1
@Override
public int copyPackage(String packagePath, IParcelFileDescriptorFactory target) {
if (packagePath == null || target == null) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
PackageLite pkg = null;
try {
final File packageFile = new File(packagePath);
//解析轻量级包
//内部调用copyPackageInner
pkg = PackageParser.parsePackageLite(packageFile, 0);
return copyPackageInner(pkg, target);
} catch (PackageParserException | IOException | RemoteException e) {
Slog.w(TAG, "Failed to copy package at " + packagePath + ": " + e);
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
}
//2
private int copyPackageInner(PackageLite pkg, IParcelFileDescriptorFactory target)
throws IOException, RemoteException {
//拷贝文件
copyFile(pkg.baseCodePath, target, "base.apk");
if (!ArrayUtils.isEmpty(pkg.splitNames)) {
for (int i = 0; i < pkg.splitNames.length; i++) {
copyFile(pkg.splitCodePaths[i], target, "split_" + pkg.splitNames[i] + ".apk");
}
}
return PackageManager.INSTALL_SUCCEEDED;
}
//3
private void copyFile(String sourcePath, IParcelFileDescriptorFactory target, String targetName)
throws IOException, RemoteException {
Slog.d(TAG, "Copying " + sourcePath + " to " + targetName);
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(sourcePath);
out = new ParcelFileDescriptor.AutoCloseOutputStream(
target.open(targetName, ParcelFileDescriptor.MODE_READ_WRITE));
//拷贝
Streams.copy(in, out);
} finally {
IoUtils.closeQuietly(out);
IoUtils.closeQuietly(in);
}
}
拷贝工作已经完成,接下来就到安装流程了、
//InstallParams.handleReturnCode
@Override
void handleReturnCode() {
// 当mArgs 不为空在走processPendingInstall
if (mArgs != null) {
processPendingInstall(mArgs, mRet);
}
}
下面为安装过程入口是PMS.processPendingInstall方法,调用时序图
【下载安装-安装过程图】
//PMS.processPendingInstall
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
// 将异步操作排队,因为包的安装可能需要一段时间。
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
// 要返回的结果对象
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);
}
if (!doRestore) {
//发送关于安装状态的广播,然后处理安装完的事情,比如打印错误信息,清除临时文件等。
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
mHandler.sendMessage(msg);
}
}
});
}
//PMS.installPackageTracedLI
private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
try {
installPackageLI(args, res);
} finally {
}
}
installPackageLI是安装过程的核心方法,然后调用installPackageLI.首先检查安装包的完整性并解析安装包。
PMS.installPackageLI
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
final int installFlags = args.installFlags;
final String installerPackageName = args.installerPackageName;
final String volumeUuid = args.volumeUuid;
final File tmpPackageFile = new File(args.getCodePath());
final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
|| (args.volumeUuid != null));
final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
final boolean virtualPreload =
((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
boolean replace = false;
int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
if (args.move != null) {
// moving a complete application; perform an initial scan on the new install location
scanFlags |= SCAN_INITIAL;
}
if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
scanFlags |= SCAN_DONT_KILL_APP;
}
if (instantApp) {
scanFlags |= SCAN_AS_INSTANT_APP;
}
if (fullApp) {
scanFlags |= SCAN_AS_FULL_APP;
}
if (virtualPreload) {
scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
}
// Result object to be returned
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
res.installerPackageName = installerPackageName;
if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
// 合理性检查
if (instantApp && (forwardLocked || onExternal)) {
Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
+ " external=" + onExternal);
res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
// 检索包集和解析包
final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| PackageParser.PARSE_ENFORCE_CODE
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
| (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
| (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setDisplayMetrics(mMetrics);
pp.setCallback(mPackageParserCallback);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
final PackageParser.Package pkg;
try {
//解析安装包,主要对Android清单文件的解析
pkg = pp.parsePackage(tmpPackageFile, parseFlags);
} catch (PackageParserException e) {
res.setError("Failed parse during installPackageLI", e);
return;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
检查SDK版本和沙箱版本,同时检查是否有静态共享库,如有则需要放在内部存储中。
//[PMS.installPackageLI]
//检查SDK版本和沙箱版本
if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
"Instant app package must target O");
return;
}
if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
Slog.w(TAG, "Instant app package " + pkg.packageName
+ " does not target targetSandboxVersion 2");
res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
"Instant app package must use targetSanboxVersion 2");
return;
}
//检查是否有静态共享库
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// Static shared libraries have synthetic package names
renameStaticSharedLibraryPackage(pkg);
// No static shared libs on external storage
if (onExternal) {
Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Packages declaring static-shared libs cannot be updated");
return;
}
}
检查是否有子安装包,如有则子安装包也需要检测。
//[PMS.installPackageLI]
// 检查是否有子安装包,如有则子安装包也需要检测。
if (pkg.childPackages != null) {
synchronized (mPackages) {
final int childCount = pkg.childPackages.size();
for (int i = 0; i < childCount; i++) {
PackageParser.Package childPkg = pkg.childPackages.get(i);
PackageInstalledInfo childRes = new PackageInstalledInfo();
childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
childRes.pkg = childPkg;
childRes.name = childPkg.packageName;
PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
if (childPs != null) {
childRes.origUsers = childPs.queryInstalledUsers(
sUserManager.getUserIds(), true);
}
if ((mPackages.containsKey(childPkg.packageName))) {
childRes.removedInfo = new PackageRemovedInfo(this);
childRes.removedInfo.removedPackage = childPkg.packageName;
childRes.removedInfo.installerPackageName = childPs.installerPackageName;
}
if (res.addedChildPackages == null) {
res.addedChildPackages = new ArrayMap<>();
}
res.addedChildPackages.put(childPkg.packageName, childRes);
}
}
}
- 检查安装包是否已存在,如已存在则需要检查旧的父包、沙箱、sdk等是否已为空,否则会报错。
- 校验安装包签名
//[PMS.installPackageLI]
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
PackageSetting signatureCheckPs = ps;
if (pkg.applicationInfo.isStaticSharedLibrary()) {
SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
if (libraryEntry != null) {
signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
}
}
if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
+ pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
return;
}
} else {
try {
verifySignaturesLP(signatureCheckPs, pkg);
} catch (PackageManagerException e) {
res.setError(e.error, e.getMessage());
return;
}
}
oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
if (ps.pkg != null && ps.pkg.applicationInfo != null) {
systemApp = (ps.pkg.applicationInfo.flags &
ApplicationInfo.FLAG_SYSTEM) != 0;
}
res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
}
如果这是一个系统应用,则检查是否在外部存储上或是是否被其他应用替换等
//[PMS.installPackageLI]
if (systemApp) {
if (onExternal) {
//中止更新;系统app不能被sdcard上的app替换
res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Cannot install updates to system apps on sdcard");
return;
} else if (instantApp) {
// 中止更新;系统应用程序不能被即时应用程序取代
res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
"Cannot update a system app with an instant app");
return;
}
}
if (args.move != null) {
// 我们做了原地移动,所以dex准备好了
scanFlags |= SCAN_NO_DEX;
scanFlags |= SCAN_MOVE;
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps == null) {
res.setError(INSTALL_FAILED_INTERNAL_ERROR,
"Missing settings for moved package " + pkgName);
}
//我们按原样移动了整个应用程序,因此引入了以前派生的ABI信息。
pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
}
} else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
// 启用SCAN_NO_DEX标志可以在稍后跳过dexopt
scanFlags |= SCAN_NO_DEX;
try {
String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
args.abiOverride : pkg.cpuAbiOverride);
final boolean extractNativeLibs = !pkg.isLibrary();
derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
extractNativeLibs, mAppLib32InstallDir);
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
return;
}
// 包的共享库需要更新。
synchronized (mPackages) {
try {
updateSharedLibrariesLPr(pkg, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
}
}
}
//把临时路径安装base64加密重命名
if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
return;
}
if (!instantApp) {
startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
} else {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
}
}
替换安装:其主要过程为更新设置,清除原有的某些APP数据,重新生成相关的app数据目录等步骤,同时要区分系统应用替换和非系统应用替换。而安装新包:则直接更新设置,生成APP数据即可。
//[PMS.installPackageLI]
//冻结安装包
try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
"installPackageLI")) {
//替换安装
if (replace) {
if (pkg.applicationInfo.isStaticSharedLibrary()) {
PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
+ "static-shared libs cannot be updated");
return;
}
}
//replacePackageLIF
replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
installerPackageName, res, args.installReason);
} else {
//安装新包
installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
args.user, installerPackageName, volumeUuid, res, args.installReason);
}
}
如有必要,优化dex文件
//[PMS.installPackageLI]
final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
&& !forwardLocked
&& !pkg.applicationInfo.isExternalAsec()
&& (!instantApp || Global.getInt(mContext.getContentResolver(),
Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
//根据条件是否进行dex优化
if (performDexopt) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
// Do not run PackageDexOptimizer through the local performDexOpt
// method because `pkg` may not be in `mPackages` yet.
//
// Also, don't fail application installs if the dexopt step fails.
DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
REASON_INSTALL,
DexoptOptions.DEXOPT_BOOT_COMPLETE);
mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
null /* instructionSets */,
getOrCreateCompilerPackageStats(pkg),
mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
dexoptOptions);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
先看替换安装的流程,检查安装限制,比如SDK版本,签名的有效性,共享id的检查,普通应用到即时应用的升级,更新删除的内容, 根据需要设置系统/特权标志,更具系统和分系统应用分两步进行。先看系统用。
//PMS.replacePackageLIF
private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
UserHandle user, String installerPackageName, PackageInstalledInfo res,
int installReason) {
final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final PackageParser.Package oldPackage;
final PackageSetting ps;
final String pkgName = pkg.packageName;
final int[] allUsers;
final int[] installedUsers;
synchronized(mPackages) {
oldPackage = mPackages.get(pkgName);
if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
// 不要允许从预发布SDK升级到正式发布的SDK
final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
== android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
== android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
if (oldTargetsPreRelease
&& !newTargetsPreRelease
&& ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
Slog.w(TAG, "Can't install package targeting released sdk");
res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
return;
}
ps = mSettings.mPackages.get(pkgName);
// 验证签名是否有效
if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
if (!checkUpgradeKeySetLP(ps, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package not signed by keys specified by upgrade-keysets: "
+ pkgName);
return;
}
} else {
// 默认为原始签名匹配
if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package has a different signature: " + pkgName);
return;
}
}
// 除非升级散列匹配,否则不要允许系统升级
if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
byte[] digestBytes = null;
try {
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
updateDigest(digest, new File(pkg.baseCodePath));
if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
for (String path : pkg.splitCodePaths) {
updateDigest(digest, new File(path));
}
}
digestBytes = digest.digest();
} catch (NoSuchAlgorithmException | IOException e) {
res.setError(INSTALL_FAILED_INVALID_APK,
"Could not compute hash: " + pkgName);
return;
}
if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
res.setError(INSTALL_FAILED_INVALID_APK,
"New package fails restrict-update check: " + pkgName);
return;
}
// 保留升级限制
pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
}
// 检查共享用户id更改
String invalidPackageName =
getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
if (invalidPackageName != null) {
res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
"Package " + invalidPackageName + " tried to change user "
+ oldPackage.mSharedUserId);
return;
}
// 在回滚的情况下,记住每个用户/配置文件的安装状态
allUsers = sUserManager.getUserIds();
installedUsers = ps.queryInstalledUsers(allUsers, true);
// don't allow an upgrade from full to ephemeral
if (isInstantApp) {
if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
for (int currentUser : allUsers) {
if (!ps.getInstantApp(currentUser)) {
// can't downgrade from full to instant
Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
+ " for user: " + currentUser);
res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
}
} else if (!ps.getInstantApp(user.getIdentifier())) {
// can't downgrade from full to instant
Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
+ " for user: " + user.getIdentifier());
res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
}
}
// 更新删除的内容
res.removedInfo = new PackageRemovedInfo(this);
res.removedInfo.uid = oldPackage.applicationInfo.uid;
res.removedInfo.removedPackage = oldPackage.packageName;
res.removedInfo.installerPackageName = ps.installerPackageName;
res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
res.removedInfo.isUpdate = true;
res.removedInfo.origUsers = installedUsers;
res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
for (int i = 0; i < installedUsers.length; i++) {
final int userId = installedUsers[i];
res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
}
final int childCount = (oldPackage.childPackages != null)
? oldPackage.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
boolean childPackageUpdated = false;
PackageParser.Package childPkg = oldPackage.childPackages.get(i);
final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
if (res.addedChildPackages != null) {
PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
if (childRes != null) {
childRes.removedInfo.uid = childPkg.applicationInfo.uid;
childRes.removedInfo.removedPackage = childPkg.packageName;
if (childPs != null) {
childRes.removedInfo.installerPackageName = childPs.installerPackageName;
}
childRes.removedInfo.isUpdate = true;
childRes.removedInfo.installReasons = res.removedInfo.installReasons;
childPackageUpdated = true;
}
}
if (!childPackageUpdated) {
PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
childRemovedRes.removedPackage = childPkg.packageName;
if (childPs != null) {
childRemovedRes.installerPackageName = childPs.installerPackageName;
}
childRemovedRes.isUpdate = false;
childRemovedRes.dataRemoved = true;
synchronized (mPackages) {
if (childPs != null) {
childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
}
}
if (res.removedInfo.removedChildPackages == null) {
res.removedInfo.removedChildPackages = new ArrayMap<>();
}
res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
}
}
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
// 根据需要设置系统/特权标志
final boolean privileged =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
final int systemPolicyFlags = policyFlags
| PackageParser.PARSE_IS_SYSTEM
| (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
user, allUsers, installerPackageName, res, installReason);
} else {
replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
user, allUsers, installerPackageName, res, installReason);
}
}
更新系统包的主要是先删除现有的旧包,禁用替换包,清除原来data目录和配置文件,把原来解析出来的包信息保存到PMS里面
scanPackageTracedLI,点击可以查看这个流程。创建data/data/包名/ 目录,更新相关设置。如果安装失败在回滚旧的安装信息。
//PMS.replaceSystemPackageLIF
public void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res,
int installReason) {
final boolean disabledSystem;
// 删除现有系统包
removePackageLI(deletedPackage, true);
synchronized (mPackages) {
disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
}
if (!disabledSystem) {
//我们不需要禁用当前系统包中的.apk,这意味着我们将替换已经安装的另一个更新。我们需要确保删除了老的。
res.removedInfo.args = createInstallArgsForExisting(0,
deletedPackage.applicationInfo.getCodePath(),
deletedPackage.applicationInfo.getResourcePath(),
getAppDexInstructionSets(deletedPackage.applicationInfo));
} else {
res.removedInfo.args = null;
}
// 成功禁用旧的包。现在继续重新安装
//清除原来的data目录
clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
| StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
//清除原来应用的配置文件
clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
PackageParser.Package newPackage = null;
try {
// 将包添加到内部数据结构中,此处调用请参考初始化安装的流程,这里不做分析。
newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
//设置更新和安装时间
PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
System.currentTimeMillis());
// 如果成功,则更新包的动态状态
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//既然安装成功了,请确保我们删除了更新删除的子包的数据目录。
final int deletedChildCount = (deletedPackage.childPackages != null)
? deletedPackage.childPackages.size() : 0;
final int newChildCount = (newPackage.childPackages != null)
? newPackage.childPackages.size() : 0;
for (int i = 0; i < deletedChildCount; i++) {
PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
boolean childPackageDeleted = true;
for (int j = 0; j < newChildCount; j++) {
PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
childPackageDeleted = false;
break;
}
}
if (childPackageDeleted) {
PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
deletedChildPkg.packageName);
if (ps != null && res.removedInfo.removedChildPackages != null) {
PackageRemovedInfo removedChildRes = res.removedInfo
.removedChildPackages.get(deletedChildPkg.packageName);
removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
}
}
}
//更新设置
updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
installReason);
//准备data目录
prepareAppDataAfterInstallLIF(newPackage);
//通知dex优化
mDexManager.notifyPackageUpdated(newPackage.packageName,
newPackage.baseCodePath, newPackage.splitCodePaths);
}
} catch (PackageManagerException e) {
res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
// 重新安装失败。恢复旧信息,删除新的pkg信息
if (newPackage != null) {
removeInstalledPackageLI(newPackage, true);
}
// 添加回旧的系统包
synchronized (mPackages) {
if (disabledSystem) {
enableSystemPackageLPw(deletedPackage);
}
// 确保安装包的名称是最新的
setInstallerPackageNameLPw(deletedPackage, installerPackageName);
// 更新恢复包的权限
updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
//保存包信息到package.xml里面
mSettings.writeLPr();
}
}
}
与更新安装系统应用大体相同。
//PMS.replaceNonSystemPackageLIF
private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res,
int installReason) {
String pkgName = deletedPackage.packageName;
boolean deletedPkg = true;
boolean addedPkg = false;
boolean updatedSettings = false;
final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
final int deleteFlags = PackageManager.DELETE_KEEP_DATA
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
final long origUpdateTime = (pkg.mExtras != null)
? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
// 首先删除现有的包,同时保留数据目录
if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
res.removedInfo, true, pkg)) {
//如果现有的包没有被成功删除
res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
deletedPkg = false;
} else {
//成功删除旧包;进行替换。
// If deleted package lived in a container, give users a chance to
// relinquish resources before killing.
if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
if (DEBUG_INSTALL) {
Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
}
final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
final ArrayList<String> pkgList = new ArrayList<String>(1);
pkgList.add(deletedPackage.applicationInfo.packageName);
sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
}
clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
| StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
try {
final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
installReason);
// Update the in-memory copy of the previous code paths.
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (!killApp) {
if (ps.oldCodePaths == null) {
ps.oldCodePaths = new ArraySet<>();
}
Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
if (deletedPackage.splitCodePaths != null) {
Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
}
} else {
ps.oldCodePaths = null;
}
if (ps.childPackageNames != null) {
for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
final String childPkgName = ps.childPackageNames.get(i);
final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
childPs.oldCodePaths = ps.oldCodePaths;
}
}
// 设置即时应用程序状态,但只有在明确指定的情况下
final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
prepareAppDataAfterInstallLIF(newPackage);
addedPkg = true;
mDexManager.notifyPackageUpdated(newPackage.packageName,
newPackage.baseCodePath, newPackage.splitCodePaths);
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
}
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
// 为失败的安装恢复所有内部状态变化和添加的文件夹
if (addedPkg) {
deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
res.removedInfo, true, null);
}
// Restore the old package
if (deletedPkg) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
File restoreFile = new File(deletedPackage.codePath);
// 恢复旧包
boolean oldExternal = isExternal(deletedPackage);
int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
(deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
(oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
try {
scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
+ e.getMessage());
return;
}
synchronized (mPackages) {
// 确保安装包的名称是最新的
setInstallerPackageNameLPw(deletedPackage, installerPackageName);
// 更新恢复包的权限
updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
mSettings.writeLPr();
}
}
} else {
//安装成功,更新信息
synchronized (mPackages) {
PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
if (ps != null) {
res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
if (res.removedInfo.removedChildPackages != null) {
final int childCount = res.removedInfo.removedChildPackages.size();
// Iterate in reverse as we may modify the collection
for (int i = childCount - 1; i >= 0; i--) {
String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
if (res.addedChildPackages.containsKey(childPackageName)) {
res.removedInfo.removedChildPackages.removeAt(i);
} else {
PackageRemovedInfo childInfo = res.removedInfo
.removedChildPackages.valueAt(i);
childInfo.removedForAllUsers = mPackages.get(
childInfo.removedPackage) == null;
}
}
}
}
}
}
}
接下来看安装一个不存在的新包,流程相对简单。
//PMS.installNewPackageLIF
private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res, int installReason) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
// 请记住这一点,以防我们需要回滚此安装
String pkgName = pkg.packageName;
synchronized(mPackages) {
final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
if (renamedPackage != null) {
// 已经安装了同名的包,尽管它已被重命名为较旧的名称。
res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
+ " without first uninstalling package running as "
+ renamedPackage);
return;
}
if (mPackages.containsKey(pkgName)) {
// 不要允许安装在具有相同名称的现有包上。
res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
+ " without first uninstalling.");
return;
}
}
try {
//数据转移流程
PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
System.currentTimeMillis(), user);
//更新设置
updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//准备应用所需的要数据目录
prepareAppDataAfterInstallLIF(newPackage);
} else {
// 从内部结构中删除包,但保留可能已经存在的任何数据
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);
}
}
然后为已安装的应用准备数据目录,其依次的顺序是
- PMS.prepareAppDataAfterInstallLIF
- PMS.prepareAppDataLIF
- PMS.prepareAppDataLeafLIF
- Installer.createAppData
以上为下载安装的流程。其中PackageParser .parsePackage(tmpPackageFile, parseFlags)和scanPackageTracedLI这个两个流程在构造函数初始化安装中已经分析,这里不再赘述。请参考Android PackageManagerService(一)启动流程分析
本文地址:https://blog.csdn.net/FeiPeng_/article/details/107494202
推荐阅读
-
Android基于BaseExpandableListAdapter实现的二级列表仿通话记录功能详解
-
Android通信方式篇(二)-消息机制(ThreadLocal详解)
-
Android源码编译详解(二)
-
Android PackageManagerService(二)下载安装详解
-
Android studio下载安装教程和第一个程序运行(多图详解)
-
Android项目刮刮奖详解(二)
-
Android 五大数据存储 (最实用的开发详解) 二 SharedPreferences存储的使用
-
转[Android]APK打包过程详解(二)
-
Android zxing如何识别反转二维码详解
-
Android Gradle使用详解(二)--添加依赖