Extract verification logic out of InstallParams

InstallParams is now solely used for installing packages. If we call
installStage() method then package will be installed without
verification. This function is now used during movePackage to bypass
verification. In future, we can use this for staged installation to
bypass verification during boot.

The extracted logic is placed into VerificationParams. Once verification
is completed, we no longer continue to install phase. We return the
result to caller and allow the caller to decide how the flow will
progress.

Bug: 159331446
Test: atest StagedInstallTest
Test: atest GtsSecurityHostTestCases
Test: atest CtsAtomicInstallTestCases
Change-Id: I4b831a3eb194d4cf02e0d65adc9f0dcdb1628a0e
This commit is contained in:
Mohammad Samiul Islam
2020-06-03 17:36:32 +01:00
parent 71008157a7
commit 9e5ffa91de
4 changed files with 338 additions and 145 deletions

View File

@@ -1736,7 +1736,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
try {
installNonStaged(childSessions);
verifyNonStaged(childSessions);
} catch (PackageManagerException e) {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
@@ -1745,10 +1745,51 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
private void verifyNonStaged(List<PackageInstallerSession> childSessions)
throws PackageManagerException {
final PackageManagerService.ActiveInstallSession verifyingSession =
makeSessionActiveForVerification();
if (verifyingSession == null) {
return;
}
if (isMultiPackage()) {
List<PackageManagerService.ActiveInstallSession> verifyingChildSessions =
new ArrayList<>(childSessions.size());
boolean success = true;
PackageManagerException failure = null;
for (int i = 0; i < childSessions.size(); ++i) {
final PackageInstallerSession session = childSessions.get(i);
try {
final PackageManagerService.ActiveInstallSession verifyingChildSession =
session.makeSessionActiveForVerification();
if (verifyingChildSession != null) {
verifyingChildSessions.add(verifyingChildSession);
}
} catch (PackageManagerException e) {
failure = e;
success = false;
}
}
if (!success) {
final IntentSender statusReceiver;
synchronized (mLock) {
statusReceiver = mRemoteStatusReceiver;
}
sendOnPackageInstalled(mContext, statusReceiver, sessionId,
isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId, null,
failure.error, failure.getLocalizedMessage(), null);
return;
}
mPm.verifyStage(verifyingSession, verifyingChildSessions);
} else {
mPm.verifyStage(verifyingSession);
}
}
private void installNonStaged(List<PackageInstallerSession> childSessions)
throws PackageManagerException {
final PackageManagerService.ActiveInstallSession installingSession =
makeSessionActive();
makeSessionActiveForInstall();
if (installingSession == null) {
return;
}
@@ -1761,7 +1802,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final PackageInstallerSession session = childSessions.get(i);
try {
final PackageManagerService.ActiveInstallSession installingChildSession =
session.makeSessionActive();
session.makeSessionActiveForInstall();
if (installingChildSession != null) {
installingChildSessions.add(installingChildSession);
}
@@ -1787,11 +1828,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
/**
* Stages this session for install and returns a
* Stages this session for verification and returns a
* {@link PackageManagerService.ActiveInstallSession} representing this new staged state or null
* in case permissions need to be requested before install can proceed.
* in case permissions need to be requested before verification can proceed.
*/
private PackageManagerService.ActiveInstallSession makeSessionActive()
private PackageManagerService.ActiveInstallSession makeSessionActiveForVerification()
throws PackageManagerException {
assertNotLocked("makeSessionActive");
@@ -1810,6 +1851,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
// TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc
if (!params.isMultiPackage && needToAskForPermissions()) {
// User needs to confirm installation;
// give installer an intent they can use to involve
@@ -1831,12 +1873,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
synchronized (mLock) {
return makeSessionActiveLocked();
return makeSessionActiveForVerificationLocked();
}
}
@GuardedBy("mLock")
private PackageManagerService.ActiveInstallSession makeSessionActiveLocked()
private PackageManagerService.ActiveInstallSession makeSessionActiveForVerificationLocked()
throws PackageManagerException {
if (!params.isMultiPackage) {
Objects.requireNonNull(mPackageName);
@@ -1900,6 +1942,80 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
}
final IPackageInstallObserver2 localObserver;
if (!hasParentSessionId()) {
// Avoid attaching this observer to child session since they won't use it.
localObserver = new IPackageInstallObserver2.Stub() {
@Override
public void onUserActionRequired(Intent intent) {
throw new IllegalStateException();
}
@Override
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
onVerificationComplete();
} else {
destroyInternal();
dispatchSessionFinished(returnCode, msg, extras);
}
}
};
} else {
localObserver = null;
}
final UserHandle user;
if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
} else {
user = new UserHandle(userId);
}
mRelinquished = true;
// TODO(159331446): create VerificationParams directly by passing information that is
// required for verification only
return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir,
localObserver, sessionId, params, mInstallerUid, mInstallSource, user,
mSigningDetails);
}
private void onVerificationComplete() {
if ((params.installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
destroyInternal();
dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Dry run", new Bundle());
return;
}
List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
try {
installNonStaged(childSessions);
} catch (PackageManagerException e) {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
destroyInternal();
dispatchSessionFinished(e.error, completeMsg, null);
}
}
/**
* Stages this session for install and returns a
* {@link PackageManagerService.ActiveInstallSession} representing this new staged state.
*/
private PackageManagerService.ActiveInstallSession makeSessionActiveForInstall()
throws PackageManagerException {
synchronized (mLock) {
if (mDestroyed) {
throw new PackageManagerException(
INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed");
}
if (!mSealed) {
throw new PackageManagerException(
INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed");
}
}
// We've reached point of no return; call into PMS to install the stage.
// Regardless of success or failure we always destroy session.
final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
@@ -1916,34 +2032,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
};
// An observer through which PMS returns the result of verification
// TODO(samiul): We are temporarily assigning two observer to ActiveInstallSession. One for
// installation and one for verification. This will be fixed within next few CLs.
final IPackageInstallObserver2 sessionVerificationObserver;
if (!hasParentSessionId()) {
// Avoid attaching this observer to child session since they won't use it.
sessionVerificationObserver = new IPackageInstallObserver2.Stub() {
@Override
public void onUserActionRequired(Intent intent) {
throw new IllegalStateException();
}
@Override
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
// TODO(samiul): In future, packages will not be installed immediately after
// verification. Package verification will return control back to here,
// and we will have call into PMS again to install package.
//
// For now, this is a no op.
}
}
};
} else {
sessionVerificationObserver = null;
}
final UserHandle user;
if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
@@ -1951,10 +2039,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
user = new UserHandle(userId);
}
mRelinquished = true;
return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver,
sessionVerificationObserver, sessionId, params, mInstallerUid, mInstallSource, user,
mSigningDetails);
synchronized (mLock) {
return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir,
localObserver, sessionId, params, mInstallerUid, mInstallSource, user,
mSigningDetails);
}
}
private static void maybeRenameFile(File from, File to) throws PackageManagerException {

View File

@@ -1159,7 +1159,7 @@ public class PackageManagerService extends IPackageManager.Stub
final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();
/** List of packages waiting for rollback to be enabled. */
final SparseArray<InstallParams> mPendingEnableRollback = new SparseArray<>();
final SparseArray<VerificationParams> mPendingEnableRollback = new SparseArray<>();
final PackageInstallerService mInstallerService;
@@ -1833,7 +1833,7 @@ public class PackageManagerService extends IPackageManager.Stub
if ((state != null) && !state.isVerificationComplete()
&& !state.timeoutExtended()) {
final InstallParams params = state.getInstallParams();
final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
Slog.i(TAG, "Verification timed out for " + originUri);
@@ -1874,7 +1874,7 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageVerificationState state = mPendingVerification.get(verificationId);
if (state != null && !state.isIntegrityVerificationComplete()) {
final InstallParams params = state.getInstallParams();
final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
Slog.i(TAG, "Integrity verification timed out for " + originUri);
@@ -1919,7 +1919,7 @@ public class PackageManagerService extends IPackageManager.Stub
state.setVerifierResponse(response.callerUid, response.code);
if (state.isVerificationComplete()) {
final InstallParams params = state.getInstallParams();
final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
if (state.isInstallAllowed()) {
@@ -1953,7 +1953,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final int response = (Integer) msg.obj;
final InstallParams params = state.getInstallParams();
final VerificationParams params = state.getVerificationParams();
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
state.setIntegrityVerificationResult(response);
@@ -2037,7 +2037,8 @@ public class PackageManagerService extends IPackageManager.Stub
case ENABLE_ROLLBACK_STATUS: {
final int enableRollbackToken = msg.arg1;
final int enableRollbackCode = msg.arg2;
InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
final VerificationParams params =
mPendingEnableRollback.get(enableRollbackToken);
if (params == null) {
Slog.w(TAG, "Invalid rollback enabled token "
+ enableRollbackToken + " received");
@@ -2061,7 +2062,8 @@ public class PackageManagerService extends IPackageManager.Stub
case ENABLE_ROLLBACK_TIMEOUT: {
final int enableRollbackToken = msg.arg1;
final int sessionId = msg.arg2;
final InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
final VerificationParams params =
mPendingEnableRollback.get(enableRollbackToken);
if (params != null) {
final Uri originUri = Uri.fromFile(params.origin.resolvedFile);
@@ -12867,6 +12869,22 @@ public class PackageManagerService extends IPackageManager.Stub
mHandler.sendMessage(msg);
}
void verifyStage(ActiveInstallSession activeInstallSession) {
final VerificationParams params = new VerificationParams(activeInstallSession);
mHandler.post(()-> {
params.startCopy();
});
}
void verifyStage(ActiveInstallSession parent, List<ActiveInstallSession> children)
throws PackageManagerException {
final MultiPackageVerificationParams params =
new MultiPackageVerificationParams(UserHandle.ALL, parent, children);
mHandler.post(()-> {
params.startCopy();
});
}
private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
int userId, int dataLoaderType) {
final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
@@ -14727,13 +14745,8 @@ public class PackageManagerService extends IPackageManager.Stub
* committed together.
*/
class MultiPackageInstallParams extends HandlerParams {
private final IPackageInstallObserver2 mVerificationObserver;
@NonNull
private final ArrayList<InstallParams> mChildParams;
// TODO(samiul): mCurrentState will relocated to a install-specific class in future
@NonNull
private final Map<InstallArgs, Integer> mCurrentState;
private final Map<InstallParams, Integer> mVerificationState;
MultiPackageInstallParams(
@NonNull UserHandle user,
@@ -14751,8 +14764,6 @@ public class PackageManagerService extends IPackageManager.Stub
this.mChildParams.add(childParams);
}
this.mCurrentState = new ArrayMap<>(mChildParams.size());
this.mVerificationState = new ArrayMap<>(mChildParams.size());
mVerificationObserver = parent.getVerificationObserver();
}
@Override
@@ -14769,7 +14780,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
// TODO(samiul): this method will relocated to a install-specific class in future
void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
mCurrentState.put(args, currentStatus);
if (mCurrentState.size() != mChildParams.size()) {
@@ -14793,43 +14803,16 @@ public class PackageManagerService extends IPackageManager.Stub
completeStatus == PackageManager.INSTALL_SUCCEEDED,
installRequests);
}
void trySendVerificationCompleteNotification(InstallParams child, int currentStatus) {
mVerificationState.put(child, currentStatus);
if (mVerificationState.size() != mChildParams.size()) {
return;
}
int completeStatus = PackageManager.INSTALL_SUCCEEDED;
for (Integer status : mVerificationState.values()) {
if (status == PackageManager.INSTALL_UNKNOWN) {
return;
} else if (status != PackageManager.INSTALL_SUCCEEDED) {
completeStatus = status;
break;
}
}
try {
mVerificationObserver.onPackageInstalled(null, completeStatus,
"Package Verification Result", new Bundle());
} catch (RemoteException e) {
Slog.i(TAG, "Observer no longer exists.");
}
}
}
class InstallParams extends HandlerParams {
// TODO: see if we can collapse this into ActiveInstallSession
final OriginInfo origin;
final MoveInfo move;
final IPackageInstallObserver2 mInstallObserver;
private final IPackageInstallObserver2 mVerificationObserver;
final IPackageInstallObserver2 observer;
int installFlags;
@NonNull final InstallSource installSource;
final String volumeUuid;
private boolean mWaitForVerificationToComplete;
private boolean mWaitForIntegrityVerificationToComplete;
private boolean mWaitForEnableRollbackToComplete;
int mRet;
final String packageAbiOverride;
final String[] grantedRuntimePermissions;
@@ -14845,7 +14828,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int mDataLoaderType;
final int mSessionId;
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 installObserver,
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
int installFlags, InstallSource installSource, String volumeUuid,
VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
@@ -14855,8 +14838,7 @@ public class PackageManagerService extends IPackageManager.Stub
super(user);
this.origin = origin;
this.move = move;
this.mInstallObserver = installObserver;
this.mVerificationObserver = null;
this.observer = observer;
this.installFlags = installFlags;
this.installSource = Preconditions.checkNotNull(installSource);
this.volumeUuid = volumeUuid;
@@ -14894,8 +14876,7 @@ public class PackageManagerService extends IPackageManager.Stub
activeInstallSession.getInstallSource().installerPackageName,
activeInstallSession.getInstallerUid(),
sessionParams.installReason);
mInstallObserver = activeInstallSession.getInstallObserver();
mVerificationObserver = activeInstallSession.getVerificationObserver();
observer = activeInstallSession.getObserver();
installFlags = sessionParams.installFlags;
installSource = activeInstallSession.getInstallSource();
volumeUuid = sessionParams.volumeUuid;
@@ -15052,16 +15033,174 @@ public class PackageManagerService extends IPackageManager.Stub
* policy if needed and then create install arguments based
* on the install location.
*/
public void handleStartCopy() {
PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
origin.resolvedPath, installFlags, packageAbiOverride);
mRet = overrideInstallLocation(pkgLite);
}
@Override
void handleReturnCode() {
processPendingInstall();
}
private void processPendingInstall() {
InstallArgs args = createInstallArgs(this);
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
mRet = args.copyApk();
}
if (mParentInstallParams != null) {
mParentInstallParams.tryProcessInstallRequest(args, mRet);
} else {
PackageInstalledInfo res = createPackageInstalledInfo(mRet);
processInstallRequestsAsync(
res.returnCode == PackageManager.INSTALL_SUCCEEDED,
Collections.singletonList(new InstallRequest(args, res)));
}
}
}
/**
* Container for a multi-package install which refers to all install sessions and args being
* committed together.
*/
class MultiPackageVerificationParams extends HandlerParams {
private final IPackageInstallObserver2 mObserver;
private final ArrayList<VerificationParams> mChildParams;
private final Map<VerificationParams, Integer> mVerificationState;
MultiPackageVerificationParams(
@NonNull UserHandle user,
@NonNull ActiveInstallSession parent,
@NonNull List<ActiveInstallSession> activeInstallSessions)
throws PackageManagerException {
super(user);
if (activeInstallSessions.size() == 0) {
throw new PackageManagerException("No child sessions found!");
}
mChildParams = new ArrayList<>(activeInstallSessions.size());
for (int i = 0; i < activeInstallSessions.size(); i++) {
final VerificationParams childParams =
new VerificationParams(activeInstallSessions.get(i));
childParams.mParentVerificationParams = this;
this.mChildParams.add(childParams);
}
this.mVerificationState = new ArrayMap<>(mChildParams.size());
mObserver = parent.getObserver();
}
@Override
void handleStartCopy() {
for (VerificationParams params : mChildParams) {
params.handleStartCopy();
}
}
@Override
void handleReturnCode() {
for (VerificationParams params : mChildParams) {
params.handleReturnCode();
}
}
void trySendVerificationCompleteNotification(VerificationParams child, int currentStatus) {
mVerificationState.put(child, currentStatus);
if (mVerificationState.size() != mChildParams.size()) {
return;
}
int completeStatus = PackageManager.INSTALL_SUCCEEDED;
for (Integer status : mVerificationState.values()) {
if (status == PackageManager.INSTALL_UNKNOWN) {
return;
} else if (status != PackageManager.INSTALL_SUCCEEDED) {
completeStatus = status;
break;
}
}
try {
mObserver.onPackageInstalled(null, completeStatus,
"Package Verification Result", new Bundle());
} catch (RemoteException e) {
Slog.i(TAG, "Observer no longer exists.");
}
}
}
class VerificationParams extends HandlerParams {
final OriginInfo origin;
final MoveInfo move;
final IPackageInstallObserver2 observer;
int installFlags;
@NonNull final InstallSource installSource;
final String volumeUuid;
private boolean mWaitForVerificationToComplete;
private boolean mWaitForIntegrityVerificationToComplete;
private boolean mWaitForEnableRollbackToComplete;
int mRet;
final String packageAbiOverride;
final String[] grantedRuntimePermissions;
final List<String> whitelistedRestrictedPermissions;
final int autoRevokePermissionsMode;
final VerificationInfo verificationInfo;
final PackageParser.SigningDetails signingDetails;
final int installReason;
@Nullable
MultiPackageVerificationParams mParentVerificationParams;
final long requiredInstalledVersionCode;
final boolean forceQueryableOverride;
final int mDataLoaderType;
final int mSessionId;
VerificationParams(ActiveInstallSession activeInstallSession) {
super(activeInstallSession.getUser());
final PackageInstaller.SessionParams sessionParams =
activeInstallSession.getSessionParams();
if (DEBUG_INSTANT) {
if ((sessionParams.installFlags
& PackageManager.INSTALL_INSTANT_APP) != 0) {
Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
}
}
verificationInfo = new VerificationInfo(
sessionParams.originatingUri,
sessionParams.referrerUri,
sessionParams.originatingUid,
activeInstallSession.getInstallerUid());
origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
move = null;
installReason = fixUpInstallReason(
activeInstallSession.getInstallSource().installerPackageName,
activeInstallSession.getInstallerUid(),
sessionParams.installReason);
observer = activeInstallSession.getObserver();
installFlags = sessionParams.installFlags;
installSource = activeInstallSession.getInstallSource();
volumeUuid = sessionParams.volumeUuid;
packageAbiOverride = sessionParams.abiOverride;
grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
autoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
signingDetails = activeInstallSession.getSigningDetails();
requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
forceQueryableOverride = sessionParams.forceQueryableOverride;
mDataLoaderType = (sessionParams.dataLoaderParams != null)
? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
mSessionId = activeInstallSession.getSessionId();
}
@Override
public String toString() {
return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
+ " file=" + origin.file + "}";
}
public void handleStartCopy() {
PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
origin.resolvedPath, installFlags, packageAbiOverride);
mRet = verifyReplacingVersionCode(pkgLite);
if (mRet == INSTALL_SUCCEEDED) {
mRet = overrideInstallLocation(pkgLite);
}
// Perform package verification and enable rollback (unless we are simply moving the
// package).
if (mRet == INSTALL_SUCCEEDED && !origin.existing) {
@@ -15223,7 +15362,7 @@ public class PackageManagerService extends IPackageManager.Stub
final long idleDuration = getVerificationTimeout();
idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
idleDuration,
idleDuration,
false, "integrity component");
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setTemporaryAppWhitelistDuration(idleDuration);
@@ -15457,44 +15596,16 @@ public class PackageManagerService extends IPackageManager.Stub
|| mWaitForEnableRollbackToComplete) {
return;
}
if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
try {
mInstallObserver.onPackageInstalled(null, mRet, "Dry run", new Bundle());
} catch (RemoteException e) {
Slog.i(TAG, "Observer no longer exists.");
}
return;
}
sendVerificationCompleteNotification();
// TODO(samiul): In future return once verification is complete
processPendingInstall();
}
private void processPendingInstall() {
InstallArgs args = createInstallArgs(this);
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
mRet = args.copyApk();
}
if (mParentInstallParams != null) {
mParentInstallParams.tryProcessInstallRequest(args, mRet);
} else {
PackageInstalledInfo res = createPackageInstalledInfo(mRet);
processInstallRequestsAsync(
res.returnCode == PackageManager.INSTALL_SUCCEEDED,
Collections.singletonList(new InstallRequest(args, res)));
}
}
private void sendVerificationCompleteNotification() {
if (mParentInstallParams != null) {
mParentInstallParams.trySendVerificationCompleteNotification(this, mRet);
if (mParentVerificationParams != null) {
mParentVerificationParams.trySendVerificationCompleteNotification(this, mRet);
} else {
try {
mVerificationObserver.onPackageInstalled(null, mRet,
"Package Verification Result", new Bundle());
observer.onPackageInstalled(null, mRet, "Package Verification Result",
new Bundle());
} catch (RemoteException e) {
Slog.i(TAG, "Observer no longer exists.");
}
@@ -15578,7 +15689,7 @@ public class PackageManagerService extends IPackageManager.Stub
/** New install */
InstallArgs(InstallParams params) {
this(params.origin, params.move, params.mInstallObserver, params.installFlags,
this(params.origin, params.move, params.observer, params.installFlags,
params.installSource, params.volumeUuid,
params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
@@ -25610,13 +25721,12 @@ public class PackageManagerService extends IPackageManager.Stub
return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
}
// TODO(samiul): Get rid of this class. The callers can create InstallParams and
// VerificationParams directly.
static class ActiveInstallSession {
private final String mPackageName;
private final File mStagedDir;
private final IPackageInstallObserver2 mInstallObserver;
// TODO(samiul): We are temporarily assigning two observer to ActiveInstallSession. One for
// installation and one for verification. This will be fixed within next few CLs.
private final IPackageInstallObserver2 mVerificationObserver;
private final IPackageInstallObserver2 mObserver;
private final int mSessionId;
private final PackageInstaller.SessionParams mSessionParams;
private final int mInstallerUid;
@@ -25624,15 +25734,12 @@ public class PackageManagerService extends IPackageManager.Stub
private final UserHandle mUser;
private final SigningDetails mSigningDetails;
ActiveInstallSession(String packageName, File stagedDir,
IPackageInstallObserver2 installObserver,
IPackageInstallObserver2 verificationObserver,
ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer,
int sessionId, PackageInstaller.SessionParams sessionParams, int installerUid,
InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
mPackageName = packageName;
mStagedDir = stagedDir;
mInstallObserver = installObserver;
mVerificationObserver = verificationObserver;
mObserver = observer;
mSessionId = sessionId;
mSessionParams = sessionParams;
mInstallerUid = installerUid;
@@ -25649,12 +25756,8 @@ public class PackageManagerService extends IPackageManager.Stub
return mStagedDir;
}
public IPackageInstallObserver2 getInstallObserver() {
return mInstallObserver;
}
public IPackageInstallObserver2 getVerificationObserver() {
return mVerificationObserver;
public IPackageInstallObserver2 getObserver() {
return mObserver;
}
public int getSessionId() {

View File

@@ -19,7 +19,7 @@ package com.android.server.pm;
import android.content.pm.PackageManager;
import android.util.SparseBooleanArray;
import com.android.server.pm.PackageManagerService.InstallParams;
import com.android.server.pm.PackageManagerService.VerificationParams;
/**
* Tracks the package verification state for a particular package. Each package verification has a
@@ -28,7 +28,7 @@ import com.android.server.pm.PackageManagerService.InstallParams;
* sufficient verifiers, then package verification is considered complete.
*/
class PackageVerificationState {
private final InstallParams mParams;
private final VerificationParams mParams;
private final SparseBooleanArray mSufficientVerifierUids;
@@ -50,13 +50,13 @@ class PackageVerificationState {
* Create a new package verification state where {@code requiredVerifierUid} is the user ID for
* the package that must reply affirmative before things can continue.
*/
PackageVerificationState(InstallParams params) {
PackageVerificationState(VerificationParams params) {
mParams = params;
mSufficientVerifierUids = new SparseBooleanArray();
mExtendedTimeout = false;
}
InstallParams getInstallParams() {
VerificationParams getVerificationParams() {
return mParams;
}

View File

@@ -804,6 +804,7 @@ public class StagingManager {
params.isStaged = false;
if (preReboot) {
params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
params.installFlags |= PackageManager.INSTALL_DRY_RUN;
}
final int apkParentSessionId = mPi.createSession(
params, session.getInstallerPackageName(), session.getInstallerAttributionTag(),