Merge "[pm] consolidate InstallRequest and InstalledPackageInfo"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9f7005c5e9
@@ -271,7 +271,8 @@ final class DeletePackageHelper {
|
||||
// other processes clean up before deleting resources.
|
||||
synchronized (mPm.mInstallLock) {
|
||||
if (info.mArgs != null) {
|
||||
mRemovePackageHelper.cleanUpResources(info.mArgs);
|
||||
mRemovePackageHelper.cleanUpResources(info.mArgs.mCodeFile,
|
||||
info.mArgs.mInstructionSets);
|
||||
}
|
||||
|
||||
boolean reEnableStub = false;
|
||||
|
||||
@@ -70,10 +70,9 @@ final class InstallArgs {
|
||||
UserHandle user, String[] instructionSets,
|
||||
String abiOverride, String[] installGrantPermissions,
|
||||
List<String> allowlistedRestrictedPermissions,
|
||||
int autoRevokePermissionsMode,
|
||||
String traceMethod, int traceCookie, SigningDetails signingDetails,
|
||||
int installReason, int installScenario, boolean forceQueryableOverride,
|
||||
int dataLoaderType, int packageSource) {
|
||||
int autoRevokePermissionsMode, String traceMethod, int traceCookie,
|
||||
SigningDetails signingDetails, int installReason, int installScenario,
|
||||
boolean forceQueryableOverride, int dataLoaderType, int packageSource) {
|
||||
mOriginInfo = originInfo;
|
||||
mMoveInfo = moveInfo;
|
||||
mInstallFlags = installFlags;
|
||||
@@ -96,18 +95,6 @@ final class InstallArgs {
|
||||
mPackageSource = packageSource;
|
||||
}
|
||||
|
||||
/** New install */
|
||||
InstallArgs(InstallingSession params) {
|
||||
this(params.mOriginInfo, params.mMoveInfo, params.mObserver, params.mInstallFlags,
|
||||
params.mInstallSource, params.mVolumeUuid,
|
||||
params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride,
|
||||
params.mGrantedRuntimePermissions, params.mAllowlistedRestrictedPermissions,
|
||||
params.mAutoRevokePermissionsMode,
|
||||
params.mTraceMethod, params.mTraceCookie, params.mSigningDetails,
|
||||
params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride,
|
||||
params.mDataLoaderType, params.mPackageSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create args that describe an existing installed package. Typically used
|
||||
* when cleaning up old installs, or used as a move source.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,12 +16,389 @@
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
final class InstallRequest {
|
||||
public final InstallArgs mArgs;
|
||||
public final PackageInstalledInfo mInstallResult;
|
||||
import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN;
|
||||
import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT;
|
||||
|
||||
InstallRequest(InstallArgs args, PackageInstalledInfo res) {
|
||||
mArgs = args;
|
||||
mInstallResult = res;
|
||||
import static com.android.server.pm.PackageManagerService.TAG;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.apex.ApexInfo;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.pm.DataLoaderType;
|
||||
import android.content.pm.IPackageInstallObserver2;
|
||||
import android.content.pm.PackageInstaller;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.SigningDetails;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ExceptionUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.pm.pkg.AndroidPackage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
final class InstallRequest {
|
||||
private final int mUserId;
|
||||
@Nullable
|
||||
private final InstallArgs mInstallArgs;
|
||||
@NonNull
|
||||
private final PackageInstalledInfo mInstalledInfo;
|
||||
@Nullable
|
||||
private Runnable mPostInstallRunnable;
|
||||
@Nullable
|
||||
private PackageRemovedInfo mRemovedInfo;
|
||||
|
||||
// New install
|
||||
InstallRequest(InstallingSession params) {
|
||||
mUserId = params.getUser().getIdentifier();
|
||||
mInstallArgs = new InstallArgs(params.mOriginInfo, params.mMoveInfo, params.mObserver,
|
||||
params.mInstallFlags, params.mInstallSource, params.mVolumeUuid,
|
||||
params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride,
|
||||
params.mGrantedRuntimePermissions, params.mAllowlistedRestrictedPermissions,
|
||||
params.mAutoRevokePermissionsMode,
|
||||
params.mTraceMethod, params.mTraceCookie, params.mSigningDetails,
|
||||
params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride,
|
||||
params.mDataLoaderType, params.mPackageSource);
|
||||
mInstalledInfo = new PackageInstalledInfo();
|
||||
}
|
||||
|
||||
// Install existing package as user
|
||||
InstallRequest(int userId, int returnCode, AndroidPackage pkg, int[] newUsers,
|
||||
Runnable runnable) {
|
||||
mUserId = userId;
|
||||
mInstallArgs = null;
|
||||
mInstalledInfo = new PackageInstalledInfo();
|
||||
mInstalledInfo.mReturnCode = returnCode;
|
||||
mInstalledInfo.mPkg = pkg;
|
||||
mInstalledInfo.mNewUsers = newUsers;
|
||||
mPostInstallRunnable = runnable;
|
||||
}
|
||||
|
||||
private static class PackageInstalledInfo {
|
||||
String mName;
|
||||
int mUid = -1;
|
||||
// The set of users that originally had this package installed.
|
||||
int[] mOrigUsers;
|
||||
// The set of users that now have this package installed.
|
||||
int[] mNewUsers;
|
||||
AndroidPackage mPkg;
|
||||
int mReturnCode;
|
||||
String mReturnMsg;
|
||||
String mInstallerPackageName;
|
||||
// The set of packages consuming this shared library or null if no consumers exist.
|
||||
ArrayList<AndroidPackage> mLibraryConsumers;
|
||||
PackageFreezer mFreezer;
|
||||
// In some error cases we want to convey more info back to the observer
|
||||
String mOrigPackage;
|
||||
String mOrigPermission;
|
||||
// The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
|
||||
ApexInfo mApexInfo;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mInstalledInfo.mName;
|
||||
}
|
||||
|
||||
public String getReturnMsg() {
|
||||
return mInstalledInfo.mReturnMsg;
|
||||
}
|
||||
|
||||
public OriginInfo getOriginInfo() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mOriginInfo;
|
||||
}
|
||||
|
||||
public PackageRemovedInfo getRemovedInfo() {
|
||||
return mRemovedInfo;
|
||||
}
|
||||
|
||||
public String getOrigPackage() {
|
||||
return mInstalledInfo.mOrigPackage;
|
||||
}
|
||||
|
||||
public String getOrigPermission() {
|
||||
return mInstalledInfo.mOrigPermission;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public File getCodeFile() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mCodeFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCodePath() {
|
||||
return (mInstallArgs != null && mInstallArgs.mCodeFile != null)
|
||||
? mInstallArgs.mCodeFile.getAbsolutePath() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAbiOverride() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mAbiOverride;
|
||||
}
|
||||
|
||||
public int getReturnCode() {
|
||||
return mInstalledInfo.mReturnCode;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IPackageInstallObserver2 getObserver() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mObserver;
|
||||
}
|
||||
|
||||
public boolean isMoveInstall() {
|
||||
return mInstallArgs != null && mInstallArgs.mMoveInfo != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMoveToUuid() {
|
||||
return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
|
||||
? mInstallArgs.mMoveInfo.mToUuid : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMovePackageName() {
|
||||
return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
|
||||
? mInstallArgs.mMoveInfo.mPackageName : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMoveFromCodePath() {
|
||||
return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
|
||||
? mInstallArgs.mMoveInfo.mFromCodePath : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public File getOldCodeFile() {
|
||||
return (mRemovedInfo != null && mRemovedInfo.mArgs != null)
|
||||
? mRemovedInfo.mArgs.mCodeFile : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] getOldInstructionSet() {
|
||||
return (mRemovedInfo != null && mRemovedInfo.mArgs != null)
|
||||
? mRemovedInfo.mArgs.mInstructionSets : null;
|
||||
}
|
||||
|
||||
public UserHandle getUser() {
|
||||
return new UserHandle(mUserId);
|
||||
}
|
||||
|
||||
public int getUserId() {
|
||||
return mUserId;
|
||||
}
|
||||
|
||||
public int getInstallFlags() {
|
||||
return mInstallArgs == null ? 0 : mInstallArgs.mInstallFlags;
|
||||
}
|
||||
|
||||
public int getInstallReason() {
|
||||
return mInstallArgs == null ? INSTALL_REASON_UNKNOWN : mInstallArgs.mInstallReason;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getVolumeUuid() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mVolumeUuid;
|
||||
}
|
||||
|
||||
public AndroidPackage getPkg() {
|
||||
return mInstalledInfo.mPkg;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTraceMethod() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mTraceMethod;
|
||||
}
|
||||
|
||||
public int getTraceCookie() {
|
||||
return mInstallArgs == null ? 0 : mInstallArgs.mTraceCookie;
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return mRemovedInfo != null && mRemovedInfo.mRemovedPackage != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getRemovedPackage() {
|
||||
return mRemovedInfo != null ? mRemovedInfo.mRemovedPackage : null;
|
||||
}
|
||||
|
||||
public boolean isInstallForExistingUser() {
|
||||
return mInstallArgs == null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InstallSource getInstallSource() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mInstallSource;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getInstallerPackageName() {
|
||||
return (mInstallArgs != null && mInstallArgs.mInstallSource != null)
|
||||
? mInstallArgs.mInstallSource.installerPackageName : null;
|
||||
}
|
||||
|
||||
public int getDataLoaderType() {
|
||||
return mInstallArgs == null ? DataLoaderType.NONE : mInstallArgs.mDataLoaderType;
|
||||
}
|
||||
|
||||
public int getSignatureSchemeVersion() {
|
||||
return mInstallArgs == null ? SigningDetails.SignatureSchemeVersion.UNKNOWN
|
||||
: mInstallArgs.mSigningDetails.getSignatureSchemeVersion();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public SigningDetails getSigningDetails() {
|
||||
return mInstallArgs == null ? SigningDetails.UNKNOWN : mInstallArgs.mSigningDetails;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Uri getOriginUri() {
|
||||
return mInstallArgs == null ? null : Uri.fromFile(mInstallArgs.mOriginInfo.mResolvedFile);
|
||||
}
|
||||
|
||||
public ApexInfo getApexInfo() {
|
||||
return mInstalledInfo.mApexInfo;
|
||||
}
|
||||
|
||||
public String getSourceInstallerPackageName() {
|
||||
return mInstallArgs.mInstallSource.installerPackageName;
|
||||
}
|
||||
|
||||
public boolean isRollback() {
|
||||
return mInstallArgs != null
|
||||
&& mInstallArgs.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
|
||||
}
|
||||
|
||||
public int[] getNewUsers() {
|
||||
return mInstalledInfo.mNewUsers;
|
||||
}
|
||||
|
||||
public int[] getOriginUsers() {
|
||||
return mInstalledInfo.mOrigUsers;
|
||||
}
|
||||
|
||||
public int getUid() {
|
||||
return mInstalledInfo.mUid;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] getInstallGrantPermissions() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mInstallGrantPermissions;
|
||||
}
|
||||
|
||||
public ArrayList<AndroidPackage> getLibraryConsumers() {
|
||||
return mInstalledInfo.mLibraryConsumers;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<String> getAllowlistedRestrictedPermissions() {
|
||||
return mInstallArgs == null ? null : mInstallArgs.mAllowlistedRestrictedPermissions;
|
||||
}
|
||||
|
||||
public int getAutoRevokePermissionsMode() {
|
||||
return mInstallArgs == null
|
||||
? AppOpsManager.MODE_DEFAULT : mInstallArgs.mAutoRevokePermissionsMode;
|
||||
}
|
||||
|
||||
public int getPackageSource() {
|
||||
return mInstallArgs == null
|
||||
? PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED : mInstallArgs.mPackageSource;
|
||||
}
|
||||
|
||||
public int getInstallScenario() {
|
||||
return mInstallArgs == null ? INSTALL_SCENARIO_DEFAULT : mInstallArgs.mInstallScenario;
|
||||
}
|
||||
|
||||
public boolean isForceQueryableOverride() {
|
||||
return mInstallArgs != null && mInstallArgs.mForceQueryableOverride;
|
||||
}
|
||||
|
||||
public void closeFreezer() {
|
||||
if (mInstalledInfo.mFreezer != null) {
|
||||
mInstalledInfo.mFreezer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void runPostInstallRunnable() {
|
||||
if (mPostInstallRunnable != null) {
|
||||
mPostInstallRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCodeFile(File codeFile) {
|
||||
if (mInstallArgs != null) {
|
||||
mInstallArgs.mCodeFile = codeFile;
|
||||
}
|
||||
}
|
||||
|
||||
public void setError(int code, String msg) {
|
||||
setReturnCode(code);
|
||||
setReturnMessage(msg);
|
||||
Slog.w(TAG, msg);
|
||||
}
|
||||
|
||||
public void setError(String msg, PackageManagerException e) {
|
||||
mInstalledInfo.mReturnCode = e.error;
|
||||
setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
|
||||
Slog.w(TAG, msg, e);
|
||||
}
|
||||
|
||||
public void setReturnCode(int returnCode) {
|
||||
mInstalledInfo.mReturnCode = returnCode;
|
||||
}
|
||||
|
||||
public void setReturnMessage(String returnMsg) {
|
||||
mInstalledInfo.mReturnMsg = returnMsg;
|
||||
}
|
||||
|
||||
public void setApexInfo(ApexInfo apexInfo) {
|
||||
mInstalledInfo.mApexInfo = apexInfo;
|
||||
}
|
||||
|
||||
public void setPkg(AndroidPackage pkg) {
|
||||
mInstalledInfo.mPkg = pkg;
|
||||
}
|
||||
|
||||
public void setUid(int uid) {
|
||||
mInstalledInfo.mUid = uid;
|
||||
}
|
||||
|
||||
public void setNewUsers(int[] newUsers) {
|
||||
mInstalledInfo.mNewUsers = newUsers;
|
||||
}
|
||||
|
||||
public void setOriginPackage(String originPackage) {
|
||||
mInstalledInfo.mOrigPackage = originPackage;
|
||||
}
|
||||
|
||||
public void setOriginPermission(String originPermission) {
|
||||
mInstalledInfo.mOrigPermission = originPermission;
|
||||
}
|
||||
|
||||
public void setInstallerPackageName(String installerPackageName) {
|
||||
mInstalledInfo.mInstallerPackageName = installerPackageName;
|
||||
}
|
||||
|
||||
public void setName(String packageName) {
|
||||
mInstalledInfo.mName = packageName;
|
||||
}
|
||||
|
||||
public void setOriginUsers(int[] userIds) {
|
||||
mInstalledInfo.mOrigUsers = userIds;
|
||||
}
|
||||
|
||||
public void setFreezer(PackageFreezer freezer) {
|
||||
mInstalledInfo.mFreezer = freezer;
|
||||
}
|
||||
|
||||
public void setRemovedInfo(PackageRemovedInfo removedInfo) {
|
||||
mRemovedInfo = removedInfo;
|
||||
}
|
||||
|
||||
public void setLibraryConsumers(ArrayList<AndroidPackage> libraryConsumers) {
|
||||
mInstalledInfo.mLibraryConsumers = libraryConsumers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,68 +253,69 @@ class InstallingSession {
|
||||
}
|
||||
|
||||
private void processPendingInstall() {
|
||||
InstallArgs args = new InstallArgs(this);
|
||||
InstallRequest installRequest = new InstallRequest(this);
|
||||
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
|
||||
mRet = copyApk(args);
|
||||
mRet = copyApk(installRequest);
|
||||
}
|
||||
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
|
||||
F2fsUtils.releaseCompressedBlocks(
|
||||
mPm.mContext.getContentResolver(), new File(args.getCodePath()));
|
||||
mPm.mContext.getContentResolver(), new File(installRequest.getCodePath()));
|
||||
}
|
||||
installRequest.setReturnCode(mRet);
|
||||
if (mParentInstallingSession != null) {
|
||||
mParentInstallingSession.tryProcessInstallRequest(args, mRet);
|
||||
mParentInstallingSession.tryProcessInstallRequest(installRequest);
|
||||
} else {
|
||||
PackageInstalledInfo res = new PackageInstalledInfo(mRet);
|
||||
// Queue up an async operation since the package installation may take a little while.
|
||||
mPm.mHandler.post(() -> processInstallRequests(
|
||||
res.mReturnCode == PackageManager.INSTALL_SUCCEEDED /* success */,
|
||||
Collections.singletonList(new InstallRequest(args, res))));
|
||||
mRet == PackageManager.INSTALL_SUCCEEDED /* success */,
|
||||
Collections.singletonList(installRequest)));
|
||||
}
|
||||
}
|
||||
|
||||
private int copyApk(InstallArgs args) {
|
||||
private int copyApk(InstallRequest request) {
|
||||
if (mMoveInfo == null) {
|
||||
return copyApkForFileInstall(args);
|
||||
return copyApkForFileInstall(request);
|
||||
} else {
|
||||
return copyApkForMoveInstall(args);
|
||||
return copyApkForMoveInstall(request);
|
||||
}
|
||||
}
|
||||
|
||||
private int copyApkForFileInstall(InstallArgs args) {
|
||||
private int copyApkForFileInstall(InstallRequest request) {
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
|
||||
try {
|
||||
if (mOriginInfo.mStaged) {
|
||||
if (DEBUG_INSTALL) {
|
||||
Slog.d(TAG, mOriginInfo.mFile + " already staged; skipping copy");
|
||||
}
|
||||
args.mCodeFile = mOriginInfo.mFile;
|
||||
request.setCodeFile(mOriginInfo.mFile);
|
||||
return PackageManager.INSTALL_SUCCEEDED;
|
||||
}
|
||||
|
||||
try {
|
||||
final boolean isEphemeral =
|
||||
(mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
|
||||
args.mCodeFile =
|
||||
mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
|
||||
request.setCodeFile(
|
||||
mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral));
|
||||
} catch (IOException e) {
|
||||
Slog.w(TAG, "Failed to create copy file: " + e);
|
||||
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
|
||||
int ret = PackageManagerServiceUtils.copyPackage(
|
||||
mOriginInfo.mFile.getAbsolutePath(), args.mCodeFile);
|
||||
mOriginInfo.mFile.getAbsolutePath(), request.getCodeFile());
|
||||
if (ret != PackageManager.INSTALL_SUCCEEDED) {
|
||||
Slog.e(TAG, "Failed to copy package");
|
||||
return ret;
|
||||
}
|
||||
|
||||
final boolean isIncremental = isIncrementalPath(args.mCodeFile.getAbsolutePath());
|
||||
final File libraryRoot = new File(args.mCodeFile, LIB_DIR_NAME);
|
||||
final boolean isIncremental = isIncrementalPath(
|
||||
request.getCodeFile().getAbsolutePath());
|
||||
final File libraryRoot = new File(request.getCodeFile(), LIB_DIR_NAME);
|
||||
NativeLibraryHelper.Handle handle = null;
|
||||
try {
|
||||
handle = NativeLibraryHelper.Handle.create(args.mCodeFile);
|
||||
handle = NativeLibraryHelper.Handle.create(request.getCodeFile());
|
||||
ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
|
||||
args.mAbiOverride, isIncremental);
|
||||
request.getAbiOverride(), isIncremental);
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Copying native libraries failed", e);
|
||||
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
@@ -328,7 +329,7 @@ class InstallingSession {
|
||||
}
|
||||
}
|
||||
|
||||
private int copyApkForMoveInstall(InstallArgs args) {
|
||||
private int copyApkForMoveInstall(InstallRequest request) {
|
||||
if (DEBUG_INSTALL) {
|
||||
Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
|
||||
+ mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
|
||||
@@ -345,8 +346,9 @@ class InstallingSession {
|
||||
}
|
||||
|
||||
final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
|
||||
args.mCodeFile = new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName);
|
||||
if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + args.mCodeFile);
|
||||
request.setCodeFile(
|
||||
new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName));
|
||||
if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + request.getCodeFile());
|
||||
|
||||
return PackageManager.INSTALL_SUCCEEDED;
|
||||
}
|
||||
@@ -460,7 +462,7 @@ class InstallingSession {
|
||||
List<InstallRequest> apexInstallRequests = new ArrayList<>();
|
||||
List<InstallRequest> apkInstallRequests = new ArrayList<>();
|
||||
for (InstallRequest request : installRequests) {
|
||||
if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
|
||||
if ((request.getInstallFlags() & PackageManager.INSTALL_APEX) != 0) {
|
||||
apexInstallRequests.add(request);
|
||||
} else {
|
||||
apkInstallRequests.add(request);
|
||||
@@ -485,7 +487,7 @@ class InstallingSession {
|
||||
// processInstallRequestAsync. In that case just notify the observer about the
|
||||
// failure.
|
||||
InstallRequest request = apexInstallRequests.get(0);
|
||||
mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
|
||||
mPm.notifyInstallObserver(request);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -496,28 +498,25 @@ class InstallingSession {
|
||||
private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
|
||||
if (success) {
|
||||
for (InstallRequest request : installRequests) {
|
||||
if (request.mInstallResult.mReturnCode != PackageManager.INSTALL_SUCCEEDED) {
|
||||
cleanUpForFailedInstall(request.mArgs);
|
||||
if (request.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
|
||||
cleanUpForFailedInstall(request);
|
||||
}
|
||||
}
|
||||
|
||||
mInstallPackageHelper.installPackagesTraced(installRequests);
|
||||
|
||||
for (InstallRequest request : installRequests) {
|
||||
doPostInstall(request.mInstallResult.mReturnCode, request.mArgs);
|
||||
doPostInstall(request);
|
||||
}
|
||||
}
|
||||
for (InstallRequest request : installRequests) {
|
||||
mInstallPackageHelper.restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
|
||||
request.mInstallResult,
|
||||
new PostInstallData(request.mArgs,
|
||||
request.mInstallResult, null));
|
||||
mInstallPackageHelper.restoreAndPostInstall(request);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPostInstall(int status, InstallArgs args) {
|
||||
private void doPostInstall(InstallRequest request) {
|
||||
if (mMoveInfo != null) {
|
||||
if (status == PackageManager.INSTALL_SUCCEEDED) {
|
||||
if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) {
|
||||
mRemovePackageHelper.cleanUpForMoveInstall(mMoveInfo.mFromUuid,
|
||||
mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
|
||||
} else {
|
||||
@@ -525,18 +524,18 @@ class InstallingSession {
|
||||
mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
|
||||
}
|
||||
} else {
|
||||
if (status != PackageManager.INSTALL_SUCCEEDED) {
|
||||
mRemovePackageHelper.removeCodePath(args.mCodeFile);
|
||||
if (request.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
|
||||
mRemovePackageHelper.removeCodePath(request.getCodeFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanUpForFailedInstall(InstallArgs args) {
|
||||
if (args.mMoveInfo != null) {
|
||||
mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
|
||||
args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
|
||||
private void cleanUpForFailedInstall(InstallRequest request) {
|
||||
if (request.isMoveInstall()) {
|
||||
mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(),
|
||||
request.getMovePackageName(), request.getMoveFromCodePath());
|
||||
} else {
|
||||
mRemovePackageHelper.removeCodePath(args.mCodeFile);
|
||||
mRemovePackageHelper.removeCodePath(request.getCodeFile());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,7 +559,7 @@ class InstallingSession {
|
||||
InstallRequest request = requests.get(0);
|
||||
try {
|
||||
// Should directory scanning logic be moved to ApexManager for better test coverage?
|
||||
final File dir = request.mArgs.mOriginInfo.mResolvedFile;
|
||||
final File dir = request.getOriginInfo().mResolvedFile;
|
||||
final File[] apexes = dir.listFiles();
|
||||
if (apexes == null) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
|
||||
@@ -580,7 +579,7 @@ class InstallingSession {
|
||||
// The newly installed APEX will not be reverted even if
|
||||
// processApkInstallRequests() fails. Need a way to keep info stored in apexd
|
||||
// and PMS in sync in the face of install failures.
|
||||
request.mInstallResult.mApexInfo = apexInfo;
|
||||
request.setApexInfo(apexInfo);
|
||||
mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
|
||||
return;
|
||||
} else {
|
||||
@@ -588,10 +587,10 @@ class InstallingSession {
|
||||
}
|
||||
}
|
||||
} catch (PackageManagerException e) {
|
||||
request.mInstallResult.setError("APEX installation failed", e);
|
||||
request.setError("APEX installation failed", e);
|
||||
}
|
||||
PackageManagerService.invalidatePackageInfoCache();
|
||||
mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
|
||||
mPm.notifyInstallObserver(request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -600,7 +599,7 @@ class InstallingSession {
|
||||
*/
|
||||
private class MultiPackageInstallingSession {
|
||||
private final List<InstallingSession> mChildInstallingSessions;
|
||||
private final Map<InstallArgs, Integer> mCurrentState;
|
||||
private final Map<InstallRequest, Integer> mCurrentState;
|
||||
@NonNull
|
||||
final PackageManagerService mPm;
|
||||
final UserHandle mUser;
|
||||
@@ -636,8 +635,8 @@ class InstallingSession {
|
||||
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
||||
}
|
||||
|
||||
public void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
|
||||
mCurrentState.put(args, currentStatus);
|
||||
public void tryProcessInstallRequest(InstallRequest request) {
|
||||
mCurrentState.put(request, request.getReturnCode());
|
||||
if (mCurrentState.size() != mChildInstallingSessions.size()) {
|
||||
return;
|
||||
}
|
||||
@@ -651,9 +650,9 @@ class InstallingSession {
|
||||
}
|
||||
}
|
||||
final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
|
||||
for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
|
||||
installRequests.add(new InstallRequest(entry.getKey(),
|
||||
new PackageInstalledInfo(completeStatus)));
|
||||
for (Map.Entry<InstallRequest, Integer> entry : mCurrentState.entrySet()) {
|
||||
entry.getKey().setReturnCode(completeStatus);
|
||||
installRequests.add(entry.getKey());
|
||||
}
|
||||
int finalCompleteStatus = completeStatus;
|
||||
mPm.mHandler.post(() -> processInstallRequests(
|
||||
|
||||
@@ -89,18 +89,14 @@ final class PackageHandler extends Handler {
|
||||
case POST_INSTALL: {
|
||||
if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
|
||||
|
||||
PostInstallData data = mPm.mRunningInstalls.get(msg.arg1);
|
||||
InstallRequest request = mPm.mRunningInstalls.get(msg.arg1);
|
||||
final boolean didRestore = (msg.arg2 != 0);
|
||||
mPm.mRunningInstalls.delete(msg.arg1);
|
||||
|
||||
if (data != null && data.res.mFreezer != null) {
|
||||
data.res.mFreezer.close();
|
||||
}
|
||||
|
||||
if (data != null && data.mPostInstallRunnable != null) {
|
||||
data.mPostInstallRunnable.run();
|
||||
} else if (data != null && data.args != null) {
|
||||
mInstallPackageHelper.handlePackagePostInstall(data.res, data.args, didRestore);
|
||||
request.closeFreezer();
|
||||
request.runPostInstallRunnable();
|
||||
if (!request.isInstallForExistingUser()) {
|
||||
mInstallPackageHelper.handlePackagePostInstall(request, didRestore);
|
||||
} else if (DEBUG_INSTALL) {
|
||||
// No post-install when we run restore from installExistingPackageForUser
|
||||
Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
|
||||
@@ -111,7 +107,7 @@ final class PackageHandler extends Handler {
|
||||
case DEFERRED_NO_KILL_POST_DELETE: {
|
||||
InstallArgs args = (InstallArgs) msg.obj;
|
||||
if (args != null) {
|
||||
mRemovePackageHelper.cleanUpResources(args);
|
||||
mRemovePackageHelper.cleanUpResources(args.mCodeFile, args.mInstructionSets);
|
||||
}
|
||||
} break;
|
||||
case DEFERRED_NO_KILL_INSTALL_OBSERVER:
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import static com.android.server.pm.PackageManagerService.TAG;
|
||||
|
||||
import android.apex.ApexInfo;
|
||||
import android.util.ExceptionUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.pm.pkg.AndroidPackage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
final class PackageInstalledInfo {
|
||||
String mName;
|
||||
int mUid;
|
||||
// The set of users that originally had this package installed.
|
||||
int[] mOrigUsers;
|
||||
// The set of users that now have this package installed.
|
||||
int[] mNewUsers;
|
||||
AndroidPackage mPkg;
|
||||
int mReturnCode;
|
||||
String mReturnMsg;
|
||||
String mInstallerPackageName;
|
||||
PackageRemovedInfo mRemovedInfo;
|
||||
// The set of packages consuming this shared library or null if no consumers exist.
|
||||
ArrayList<AndroidPackage> mLibraryConsumers;
|
||||
PackageFreezer mFreezer;
|
||||
|
||||
// In some error cases we want to convey more info back to the observer
|
||||
String mOrigPackage;
|
||||
String mOrigPermission;
|
||||
|
||||
// The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
|
||||
ApexInfo mApexInfo;
|
||||
|
||||
PackageInstalledInfo(int currentStatus) {
|
||||
mReturnCode = currentStatus;
|
||||
mUid = -1;
|
||||
mPkg = null;
|
||||
mRemovedInfo = null;
|
||||
}
|
||||
|
||||
public void setError(int code, String msg) {
|
||||
setReturnCode(code);
|
||||
setReturnMessage(msg);
|
||||
Slog.w(TAG, msg);
|
||||
}
|
||||
|
||||
public void setError(String msg, PackageManagerException e) {
|
||||
mReturnCode = e.error;
|
||||
setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
|
||||
Slog.w(TAG, msg, e);
|
||||
}
|
||||
|
||||
public void setReturnCode(int returnCode) {
|
||||
mReturnCode = returnCode;
|
||||
}
|
||||
|
||||
private void setReturnMessage(String returnMsg) {
|
||||
mReturnMsg = returnMsg;
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,6 @@ import android.content.pm.IDexModuleRegisterCallback;
|
||||
import android.content.pm.IOnChecksumsReadyListener;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.IPackageDeleteObserver2;
|
||||
import android.content.pm.IPackageInstallObserver2;
|
||||
import android.content.pm.IPackageLoadingProgressCallback;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.IPackageMoveObserver;
|
||||
@@ -826,10 +825,10 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
@Watched(manual = true)
|
||||
private final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
|
||||
|
||||
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
|
||||
private final Map<String, InstallRequest>
|
||||
mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
|
||||
private final Map<String, InstallRequest>
|
||||
mPendingKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
// Internal interface for permission manager
|
||||
@@ -908,7 +907,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
// Stores a list of users whose package restrictions file needs to be updated
|
||||
final ArraySet<Integer> mDirtyUsers = new ArraySet<>();
|
||||
|
||||
final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
|
||||
final SparseArray<InstallRequest> mRunningInstalls = new SparseArray<>();
|
||||
int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
|
||||
|
||||
final @NonNull String[] mRequiredVerifierPackages;
|
||||
@@ -1155,32 +1154,30 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
}
|
||||
|
||||
void notifyInstallObserver(String packageName, boolean killApp) {
|
||||
final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
|
||||
final InstallRequest installRequest =
|
||||
killApp ? mPendingKillInstallObservers.remove(packageName)
|
||||
: mNoKillInstallObservers.remove(packageName);
|
||||
|
||||
if (pair != null) {
|
||||
notifyInstallObserver(pair.first, pair.second);
|
||||
if (installRequest != null) {
|
||||
notifyInstallObserver(installRequest);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyInstallObserver(PackageInstalledInfo info,
|
||||
IPackageInstallObserver2 installObserver) {
|
||||
if (installObserver != null) {
|
||||
void notifyInstallObserver(InstallRequest request) {
|
||||
if (request.getObserver() != null) {
|
||||
try {
|
||||
Bundle extras = extrasForInstallResult(info);
|
||||
installObserver.onPackageInstalled(info.mName, info.mReturnCode,
|
||||
info.mReturnMsg, extras);
|
||||
Bundle extras = extrasForInstallResult(request);
|
||||
request.getObserver().onPackageInstalled(request.getName(),
|
||||
request.getReturnCode(), request.getReturnMsg(), extras);
|
||||
} catch (RemoteException e) {
|
||||
Slog.i(TAG, "Observer no longer exists.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
|
||||
IPackageInstallObserver2 observer) {
|
||||
String packageName = info.mPkg.getPackageName();
|
||||
mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
|
||||
void scheduleDeferredNoKillInstallObserver(InstallRequest request) {
|
||||
String packageName = request.getPkg().getPackageName();
|
||||
mNoKillInstallObservers.put(packageName, request);
|
||||
Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
|
||||
mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
|
||||
}
|
||||
@@ -1196,10 +1193,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
delay ? getPruneUnusedSharedLibrariesDelay() : 0);
|
||||
}
|
||||
|
||||
void scheduleDeferredPendingKillInstallObserver(PackageInstalledInfo info,
|
||||
IPackageInstallObserver2 observer) {
|
||||
final String packageName = info.mPkg.getPackageName();
|
||||
mPendingKillInstallObservers.put(packageName, Pair.create(info, observer));
|
||||
void scheduleDeferredPendingKillInstallObserver(InstallRequest request) {
|
||||
final String packageName = request.getPkg().getPackageName();
|
||||
mPendingKillInstallObservers.put(packageName, request);
|
||||
final Message message = mHandler.obtainMessage(DEFERRED_PENDING_KILL_INSTALL_OBSERVER,
|
||||
packageName);
|
||||
mHandler.sendMessageDelayed(message, DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS);
|
||||
@@ -1312,21 +1308,22 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
}
|
||||
}
|
||||
|
||||
private static Bundle extrasForInstallResult(PackageInstalledInfo res) {
|
||||
private static Bundle extrasForInstallResult(InstallRequest request) {
|
||||
Bundle extras = null;
|
||||
switch (res.mReturnCode) {
|
||||
switch (request.getReturnCode()) {
|
||||
case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
|
||||
extras = new Bundle();
|
||||
extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
|
||||
res.mOrigPermission);
|
||||
request.getOrigPermission());
|
||||
extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
|
||||
res.mOrigPackage);
|
||||
request.getOrigPackage());
|
||||
break;
|
||||
}
|
||||
case PackageManager.INSTALL_SUCCEEDED: {
|
||||
extras = new Bundle();
|
||||
extras.putBoolean(Intent.EXTRA_REPLACING,
|
||||
res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null);
|
||||
request.getRemovedInfo() != null
|
||||
&& request.getRemovedInfo().mRemovedPackage != null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3111,14 +3108,14 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
// state for observers to see the FIRST_LAUNCH signal.
|
||||
mHandler.post(() -> {
|
||||
for (int i = 0; i < mRunningInstalls.size(); i++) {
|
||||
final PostInstallData data = mRunningInstalls.valueAt(i);
|
||||
if (data.res.mReturnCode != PackageManager.INSTALL_SUCCEEDED) {
|
||||
final InstallRequest installRequest = mRunningInstalls.valueAt(i);
|
||||
if (installRequest.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
|
||||
continue;
|
||||
}
|
||||
if (packageName.equals(data.res.mPkg.getPackageName())) {
|
||||
if (packageName.equals(installRequest.getPkg().getPackageName())) {
|
||||
// right package; but is it for the right user?
|
||||
for (int uIndex = 0; uIndex < data.res.mNewUsers.length; uIndex++) {
|
||||
if (userId == data.res.mNewUsers[uIndex]) {
|
||||
for (int uIndex = 0; uIndex < installRequest.getNewUsers().length; uIndex++) {
|
||||
if (userId == installRequest.getNewUsers()[uIndex]) {
|
||||
if (DEBUG_BACKUP) {
|
||||
Slog.i(TAG, "Package " + packageName
|
||||
+ " being restored so deferring FIRST_LAUNCH");
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerExemptionManager;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.LocalServices;
|
||||
@@ -42,8 +43,8 @@ final class PackageRemovedInfo {
|
||||
int[] mRemovedUsers = null;
|
||||
int[] mBroadcastUsers = null;
|
||||
int[] mInstantUserIds = null;
|
||||
SparseArray<Integer> mInstallReasons;
|
||||
SparseArray<Integer> mUninstallReasons;
|
||||
SparseIntArray mInstallReasons;
|
||||
SparseIntArray mUninstallReasons;
|
||||
boolean mIsRemovedPackageSystemUpdate = false;
|
||||
boolean mIsUpdate;
|
||||
boolean mDataRemoved;
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Record-keeping of restore-after-install operations that are currently in flight
|
||||
* between the Package Manager and the Backup Manager
|
||||
*/
|
||||
public final class PostInstallData {
|
||||
@Nullable
|
||||
public final InstallArgs args;
|
||||
@NonNull
|
||||
public final PackageInstalledInfo res;
|
||||
@Nullable
|
||||
public final Runnable mPostInstallRunnable;
|
||||
|
||||
PostInstallData(@Nullable InstallArgs args, @NonNull PackageInstalledInfo res,
|
||||
@Nullable Runnable postInstallRunnable) {
|
||||
this.args = args;
|
||||
this.res = res;
|
||||
mPostInstallRunnable = postInstallRunnable;
|
||||
}
|
||||
}
|
||||
@@ -77,11 +77,10 @@ final class ReconcilePackageUtils {
|
||||
}
|
||||
|
||||
// the following may be null if we're just reconciling on boot (and not during install)
|
||||
final InstallArgs installArgs = request.mInstallArgs.get(installPackageName);
|
||||
final PackageInstalledInfo res = request.mInstallResults.get(installPackageName);
|
||||
final InstallRequest installRequest = request.mInstallRequests.get(installPackageName);
|
||||
final PrepareResult prepareResult = request.mPreparedPackages.get(installPackageName);
|
||||
final boolean isInstall = installArgs != null;
|
||||
if (isInstall && (res == null || prepareResult == null)) {
|
||||
final boolean isInstall = installRequest != null;
|
||||
if (isInstall && prepareResult == null) {
|
||||
throw new ReconcileFailure("Reconcile arguments are not balanced for "
|
||||
+ installPackageName + "!");
|
||||
}
|
||||
@@ -92,7 +91,8 @@ final class ReconcilePackageUtils {
|
||||
final boolean killApp = (scanResult.mRequest.mScanFlags & SCAN_DONT_KILL_APP) == 0;
|
||||
final int deleteFlags = PackageManager.DELETE_KEEP_DATA
|
||||
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
|
||||
deletePackageAction = DeletePackageHelper.mayDeletePackageLocked(res.mRemovedInfo,
|
||||
deletePackageAction = DeletePackageHelper.mayDeletePackageLocked(
|
||||
installRequest.getRemovedInfo(),
|
||||
prepareResult.mOriginalPs, prepareResult.mDisabledPs,
|
||||
deleteFlags, null /* all users */);
|
||||
if (deletePackageAction == null) {
|
||||
@@ -146,8 +146,8 @@ final class ReconcilePackageUtils {
|
||||
request.mVersionInfos.get(installPackageName);
|
||||
final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
|
||||
final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
|
||||
final boolean isRollback = installArgs != null
|
||||
&& installArgs.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
|
||||
final boolean isRollback = installRequest != null
|
||||
&& installRequest.isRollback();
|
||||
final boolean compatMatch =
|
||||
PackageManagerServiceUtils.verifySignatures(signatureCheckPs,
|
||||
sharedUserSetting, disabledPkgSetting,
|
||||
@@ -257,8 +257,8 @@ final class ReconcilePackageUtils {
|
||||
}
|
||||
|
||||
result.put(installPackageName,
|
||||
new ReconciledPackage(request, installArgs, scanResult.mPkgSetting,
|
||||
res, request.mPreparedPackages.get(installPackageName), scanResult,
|
||||
new ReconciledPackage(request, installRequest, scanResult.mPkgSetting,
|
||||
request.mPreparedPackages.get(installPackageName), scanResult,
|
||||
deletePackageAction, allowedSharedLibInfos, signingDetails,
|
||||
sharedUserSignaturesChanged, removeAppKeySetData));
|
||||
}
|
||||
|
||||
@@ -34,20 +34,17 @@ final class ReconcileRequest {
|
||||
public final Map<String, ScanResult> mScannedPackages;
|
||||
|
||||
public final Map<String, AndroidPackage> mAllPackages;
|
||||
public final Map<String, InstallArgs> mInstallArgs;
|
||||
public final Map<String, PackageInstalledInfo> mInstallResults;
|
||||
public final Map<String, InstallRequest> mInstallRequests;
|
||||
public final Map<String, PrepareResult> mPreparedPackages;
|
||||
public final Map<String, Settings.VersionInfo> mVersionInfos;
|
||||
|
||||
ReconcileRequest(Map<String, ScanResult> scannedPackages,
|
||||
Map<String, InstallArgs> installArgs,
|
||||
Map<String, PackageInstalledInfo> installResults,
|
||||
Map<String, InstallRequest> installRequests,
|
||||
Map<String, PrepareResult> preparedPackages,
|
||||
Map<String, AndroidPackage> allPackages,
|
||||
Map<String, Settings.VersionInfo> versionInfos) {
|
||||
mScannedPackages = scannedPackages;
|
||||
mInstallArgs = installArgs;
|
||||
mInstallResults = installResults;
|
||||
mInstallRequests = installRequests;
|
||||
mPreparedPackages = preparedPackages;
|
||||
mAllPackages = allPackages;
|
||||
mVersionInfos = versionInfos;
|
||||
@@ -56,7 +53,7 @@ final class ReconcileRequest {
|
||||
ReconcileRequest(Map<String, ScanResult> scannedPackages,
|
||||
Map<String, AndroidPackage> allPackages,
|
||||
Map<String, Settings.VersionInfo> versionInfos) {
|
||||
this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
|
||||
this(scannedPackages, Collections.emptyMap(),
|
||||
Collections.emptyMap(), allPackages, versionInfos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,8 @@ final class ReconciledPackage {
|
||||
public final PackageSetting mPkgSetting;
|
||||
public final ScanResult mScanResult;
|
||||
// TODO: Remove install-specific details from the reconcile result
|
||||
public final PackageInstalledInfo mInstallResult;
|
||||
@Nullable public final PrepareResult mPrepareResult;
|
||||
@Nullable public final InstallArgs mInstallArgs;
|
||||
@Nullable public final InstallRequest mInstallRequest;
|
||||
public final DeletePackageAction mDeletePackageAction;
|
||||
public final List<SharedLibraryInfo> mAllowedSharedLibraryInfos;
|
||||
public final SigningDetails mSigningDetails;
|
||||
@@ -48,9 +47,8 @@ final class ReconciledPackage {
|
||||
public final boolean mRemoveAppKeySetData;
|
||||
|
||||
ReconciledPackage(ReconcileRequest request,
|
||||
InstallArgs installArgs,
|
||||
InstallRequest installRequest,
|
||||
PackageSetting pkgSetting,
|
||||
PackageInstalledInfo installResult,
|
||||
PrepareResult prepareResult,
|
||||
ScanResult scanResult,
|
||||
DeletePackageAction deletePackageAction,
|
||||
@@ -59,9 +57,8 @@ final class ReconciledPackage {
|
||||
boolean sharedUserSignaturesChanged,
|
||||
boolean removeAppKeySetData) {
|
||||
mRequest = request;
|
||||
mInstallArgs = installArgs;
|
||||
mInstallRequest = installRequest;
|
||||
mPkgSetting = pkgSetting;
|
||||
mInstallResult = installResult;
|
||||
mPrepareResult = prepareResult;
|
||||
mScanResult = scanResult;
|
||||
mDeletePackageAction = deletePackageAction;
|
||||
|
||||
@@ -385,29 +385,29 @@ final class RemovePackageHelper {
|
||||
}
|
||||
}
|
||||
|
||||
void cleanUpResources(InstallArgs args) {
|
||||
void cleanUpResources(File codeFile, String[] instructionSets) {
|
||||
synchronized (mPm.mInstallLock) {
|
||||
cleanUpResourcesLI(args);
|
||||
cleanUpResourcesLI(codeFile, instructionSets);
|
||||
}
|
||||
}
|
||||
|
||||
// Need installer lock especially for dex file removal.
|
||||
@GuardedBy("mPm.mInstallLock")
|
||||
private void cleanUpResourcesLI(InstallArgs args) {
|
||||
private void cleanUpResourcesLI(File codeFile, String[] instructionSets) {
|
||||
// Try enumerating all code paths before deleting
|
||||
List<String> allCodePaths = Collections.EMPTY_LIST;
|
||||
if (args.mCodeFile != null && args.mCodeFile.exists()) {
|
||||
if (codeFile != null && codeFile.exists()) {
|
||||
final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
|
||||
final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
|
||||
input.reset(), args.mCodeFile, /* flags */ 0);
|
||||
input.reset(), codeFile, /* flags */ 0);
|
||||
if (result.isSuccess()) {
|
||||
// Ignore error; we tried our best
|
||||
allCodePaths = result.getResult().getAllApkPaths();
|
||||
}
|
||||
}
|
||||
|
||||
removeCodePathLI(args.mCodeFile);
|
||||
removeDexFilesLI(allCodePaths, args.mInstructionSets);
|
||||
removeCodePathLI(codeFile);
|
||||
removeDexFilesLI(allCodePaths, instructionSets);
|
||||
}
|
||||
|
||||
@GuardedBy("mPm.mInstallLock")
|
||||
|
||||
Reference in New Issue
Block a user