summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mohammad Samiul Islam <samiul@google.com> 2020-10-06 09:15:39 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-10-06 09:15:39 +0000
commitb522c02e47dc3b0e5d446609e5d90fb12157b268 (patch)
tree8eff8816093d48aee8e5ead321124d62541ebfe0
parentdcd5a9cbb2d64ab29db398f36be312f08a51ba7e (diff)
parent038fd8d035689910230fa4bf32618e726befa13c (diff)
Merge changes from topic "app-staging"
* changes: Reverify certain conditions during staged install Ensure staged sessions are not installed in app-staging directory Stop creating extra apk session during post-reboot install phase
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java163
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java132
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java10
3 files changed, 200 insertions, 105 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 2aafe9a6f9a1..7efe0810946a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -28,6 +28,8 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
+import static android.content.pm.PackageManager.INSTALL_STAGED;
+import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
import static android.system.OsConstants.O_CREAT;
@@ -1458,7 +1460,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mChildSessionsRemaining.removeAt(sessionIndex);
if (mChildSessionsRemaining.size() == 0) {
destroyInternal();
- dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED,
+ dispatchSessionFinished(INSTALL_SUCCEEDED,
"Session installed", null);
}
} else if (PackageInstaller.STATUS_PENDING_USER_ACTION == status) {
@@ -1533,7 +1535,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
- assertPreparedAndNotDestroyedLocked("commit");
+ assertPreparedAndNotDestroyedLocked("commit of session " + sessionId);
assertNoWriteFileTransfersOpenLocked();
final boolean isSecureFrpEnabled =
@@ -1663,7 +1665,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throws PackageManagerException {
try {
assertNoWriteFileTransfersOpenLocked();
- assertPreparedAndNotDestroyedLocked("sealing of session");
+ assertPreparedAndNotDestroyedLocked("sealing of session " + sessionId);
mSealed = true;
} catch (Throwable e) {
// Convert all exceptions into package manager exceptions as only those are handled
@@ -1701,6 +1703,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
+ private void onSessionInstallationFailure(int error, String detailedMessage) {
+ Slog.e(TAG, "Install of session " + sessionId + " failed: " + detailedMessage);
+ destroyInternal();
+ dispatchSessionFinished(error, detailedMessage, null);
+ }
+
private void onStorageHealthStatusChanged(int status) {
final String packageName = getPackageName();
if (TextUtils.isEmpty(packageName)) {
@@ -1757,15 +1765,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
sealLocked();
- if (isApexSession()) {
- // APEX installations rely on certain fields to be populated after reboot.
- // E.g. mPackageName.
- validateApexInstallLocked();
- } else {
- // Populate mPackageName for this APK session which is required by the staging
- // manager to check duplicate apk-in-apex.
- PackageInstallerSession parent = allSessions.get(mParentSessionId);
- if (parent != null && parent.isStagedSessionReady()) {
+ // Session that are staged, ready and not multi package will be installed during
+ // this boot. As such, we need populate all the fields for successful installation.
+ if (isMultiPackage()) {
+ return;
+ }
+ final PackageInstallerSession root = hasParentSessionId()
+ ? allSessions.get(getParentSessionId())
+ : this;
+ if (root != null && root.isStagedSessionReady()) {
+ if (isApexSession()) {
+ validateApexInstallLocked();
+ } else {
validateApkInstallLocked();
}
}
@@ -1829,7 +1840,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mStagingManager.commitSession(this);
// TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even
// though ideally, we just need to send session committed broadcast.
- dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null);
+ dispatchSessionFinished(INSTALL_SUCCEEDED, "Session staged", null);
return;
}
@@ -1911,12 +1922,53 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
+ /**
+ * Installs apks of staged session while skipping the verification process for a committed and
+ * ready session.
+ */
+ void installStagedSession(IntentSender statusReceiver) {
+ assertCallerIsOwnerOrRootOrSystemLocked();
+ Preconditions.checkArgument(!hasParentSessionId()); // Don't allow installing child sessions
+ Preconditions.checkArgument(isCommitted() && isStagedSessionReady());
+
+ // Since staged sessions are installed during boot, the original reference to status
+ // receiver from the owner has already been lost. We can safely replace it with a
+ // status receiver from the system without effecting the flow.
+ updateRemoteStatusReceiver(statusReceiver);
+ install();
+ }
+
+ private void updateRemoteStatusReceiver(IntentSender remoteStatusReceiver) {
+ synchronized (mLock) {
+ mRemoteStatusReceiver = remoteStatusReceiver;
+ if (isMultiPackage()) {
+ final IntentSender childIntentSender =
+ new ChildStatusIntentReceiver(mChildSessions.clone(), remoteStatusReceiver)
+ .getIntentSender();
+ for (int i = mChildSessions.size() - 1; i >= 0; --i) {
+ mChildSessions.valueAt(i).mRemoteStatusReceiver = childIntentSender;
+ }
+ }
+ }
+ }
+
+ private void install() {
+ try {
+ installNonStaged();
+ } catch (PackageManagerException e) {
+ final String completeMsg = ExceptionUtils.getCompleteMessage(e);
+ onSessionInstallationFailure(e.error, completeMsg);
+ }
+ }
+
private void installNonStaged()
throws PackageManagerException {
- final PackageManagerService.InstallParams installingSession =
- makeInstallParams();
+ Preconditions.checkArgument(containsApkSession());
+
+ final PackageManagerService.InstallParams installingSession = makeInstallParams();
if (installingSession == null) {
- return;
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session should contain at least one apk session for installation");
}
if (isMultiPackage()) {
final List<PackageInstallerSession> childSessions;
@@ -2084,7 +2136,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
- if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
+ if (returnCode == INSTALL_SUCCEEDED) {
onVerificationComplete();
} else {
onSessionVerificationFailure(returnCode, msg);
@@ -2126,20 +2178,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return;
}
- try {
- installNonStaged();
- } catch (PackageManagerException e) {
- final String completeMsg = ExceptionUtils.getCompleteMessage(e);
- Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
- destroyInternal();
- dispatchSessionFinished(e.error, completeMsg, null);
- }
+ install();
}
/**
* Stages this session for install and returns a
* {@link PackageManagerService.InstallParams} representing this new staged state.
*/
+ @Nullable
private PackageManagerService.InstallParams makeInstallParams()
throws PackageManagerException {
synchronized (mLock) {
@@ -2153,8 +2199,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- // We've reached point of no return; call into PMS to install the stage.
- // Regardless of success or failure we always destroy session.
+ // Do not try to install apex session. Parent session will have at least one apk session.
+ if (!isMultiPackage() && isApexSession()) {
+ sendUpdateToRemoteStatusReceiver(INSTALL_SUCCEEDED,
+ "Apex package should have been installed by apexd", null);
+ return null;
+ }
+
final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() {
@Override
public void onUserActionRequired(Intent intent) {
@@ -2164,8 +2215,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) {
- destroyInternal();
- dispatchSessionFinished(returnCode, msg, extras);
+ if (isStaged()) {
+ sendUpdateToRemoteStatusReceiver(returnCode, msg, extras);
+ } else {
+ // We've reached point of no return; call into PMS to install the stage.
+ // Regardless of success or failure we always destroy session.
+ destroyInternal();
+ dispatchSessionFinished(returnCode, msg, extras);
+ }
}
};
@@ -2176,6 +2233,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
user = new UserHandle(userId);
}
+ if (params.isStaged) {
+ params.installFlags |= INSTALL_STAGED;
+ }
+
synchronized (mLock) {
return mPm.new InstallParams(stageDir, localObserver, params, mInstallSource, user,
mSigningDetails, mInstallerUid);
@@ -2952,7 +3013,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
handle = NativeLibraryHelper.Handle.create(packageDir);
final int res = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libDir,
abiOverride, isIncrementalInstallation());
- if (res != PackageManager.INSTALL_SUCCEEDED) {
+ if (res != INSTALL_SUCCEEDED) {
throw new PackageManagerException(res,
"Failed to extract native libraries, res=" + res);
}
@@ -3586,16 +3647,35 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
- final IntentSender statusReceiver;
- final String packageName;
+ sendUpdateToRemoteStatusReceiver(returnCode, msg, extras);
+
synchronized (mLock) {
mFinalStatus = returnCode;
mFinalMessage = msg;
+ }
+ final boolean success = (returnCode == INSTALL_SUCCEEDED);
+
+ // Send broadcast to default launcher only if it's a new install
+ // TODO(b/144270665): Secure the usage of this broadcast.
+ final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
+ if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts()) {
+ mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId);
+ }
+
+ mCallback.onSessionFinished(this, success);
+ if (isDataLoaderInstallation()) {
+ logDataLoaderInstallationSession(returnCode);
+ }
+ }
+
+ private void sendUpdateToRemoteStatusReceiver(int returnCode, String msg, Bundle extras) {
+ final IntentSender statusReceiver;
+ final String packageName;
+ synchronized (mLock) {
statusReceiver = mRemoteStatusReceiver;
packageName = mPackageName;
}
-
if (statusReceiver != null) {
// Execute observer.onPackageInstalled on different thread as we don't want callers
// inside the system server have to worry about catching the callbacks while they are
@@ -3606,23 +3686,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
args.arg3 = extras;
args.arg4 = statusReceiver;
args.argi1 = returnCode;
-
mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget();
}
-
- final boolean success = (returnCode == PackageManager.INSTALL_SUCCEEDED);
-
- // Send broadcast to default launcher only if it's a new install
- // TODO(b/144270665): Secure the usage of this broadcast.
- final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
- if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts()) {
- mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId);
- }
-
- mCallback.onSessionFinished(this, success);
- if (isDataLoaderInstallation()) {
- logDataLoaderInstallationSession(returnCode);
- }
}
/** {@hide} */
@@ -3834,7 +3899,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
boolean showNotification, int userId, String basePackageName, int returnCode,
String msg, Bundle extras) {
- if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
+ if (INSTALL_SUCCEEDED == returnCode && showNotification) {
boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
Notification notification = PackageInstallerService.buildSuccessNotification(context,
context.getResources()
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index cc1ef86bfb1a..8f1576516e07 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -66,6 +66,7 @@ import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTEN
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
+import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
@@ -14990,6 +14991,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Nullable MultiPackageInstallParams mParentInstallParams;
final boolean forceQueryableOverride;
final int mDataLoaderType;
+ final long requiredInstalledVersionCode;
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
int installFlags, InstallSource installSource, String volumeUuid,
@@ -15010,6 +15012,7 @@ public class PackageManagerService extends IPackageManager.Stub
this.installReason = PackageManager.INSTALL_REASON_UNKNOWN;
this.forceQueryableOverride = false;
this.mDataLoaderType = DataLoaderType.NONE;
+ this.requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
}
InstallParams(File stagedDir, IPackageInstallObserver2 observer,
@@ -15032,6 +15035,7 @@ public class PackageManagerService extends IPackageManager.Stub
forceQueryableOverride = sessionParams.forceQueryableOverride;
mDataLoaderType = (sessionParams.dataLoaderParams != null)
? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
+ requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
}
@Override
@@ -15178,6 +15182,18 @@ public class PackageManagerService extends IPackageManager.Stub
public void handleStartCopy() {
PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
origin.resolvedPath, installFlags, packageAbiOverride);
+
+ // For staged session, there is a delay between its verification and install. Device
+ // state can change within this delay and hence we need to re-verify certain conditions.
+ boolean isStaged = (installFlags & INSTALL_STAGED) != 0;
+ if (isStaged) {
+ mRet = verifyReplacingVersionCode(
+ pkgLite, requiredInstalledVersionCode, installFlags);
+ if (mRet != INSTALL_SUCCEEDED) {
+ return;
+ }
+ }
+
mRet = overrideInstallLocation(pkgLite);
}
@@ -15324,11 +15340,14 @@ public class PackageManagerService extends IPackageManager.Stub
PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
origin.resolvedPath, installFlags, packageAbiOverride);
- mRet = verifyReplacingVersionCode(pkgLite);
+ mRet = verifyReplacingVersionCode(pkgLite, requiredInstalledVersionCode, installFlags);
+ if (mRet != INSTALL_SUCCEEDED) {
+ return;
+ }
// Perform package verification and enable rollback (unless we are simply moving the
// package).
- if (mRet == INSTALL_SUCCEEDED && !origin.existing) {
+ if (!origin.existing) {
sendApkVerificationRequest(pkgLite);
if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
sendEnableRollbackRequest();
@@ -15336,54 +15355,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private int verifyReplacingVersionCode(PackageInfoLite pkgLite) {
- String packageName = pkgLite.packageName;
- synchronized (mLock) {
- // Package which currently owns the data that the new package will own if installed.
- // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
- // will be null whereas dataOwnerPkg will contain information about the package
- // which was uninstalled while keeping its data.
- AndroidPackage dataOwnerPkg = mPackages.get(packageName);
- if (dataOwnerPkg == null) {
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- dataOwnerPkg = ps.pkg;
- }
- }
-
- if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
- if (dataOwnerPkg == null) {
- Slog.w(TAG, "Required installed version code was "
- + requiredInstalledVersionCode
- + " but package is not installed");
- return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
- }
-
- if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
- Slog.w(TAG, "Required installed version code was "
- + requiredInstalledVersionCode
- + " but actual installed version is "
- + dataOwnerPkg.getLongVersionCode());
- return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
- }
- }
-
- if (dataOwnerPkg != null) {
- if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
- dataOwnerPkg.isDebuggable())) {
- try {
- checkDowngrade(dataOwnerPkg, pkgLite);
- } catch (PackageManagerException e) {
- Slog.w(TAG, "Downgrade detected: " + e.getMessage());
- return PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
- }
- }
- }
- }
- return PackageManager.INSTALL_SUCCEEDED;
- }
-
-
void sendApkVerificationRequest(PackageInfoLite pkgLite) {
final int verificationId = mPendingVerificationToken++;
@@ -15977,7 +15948,7 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
- final File targetDir = codeFile.getParentFile();
+ final File targetDir = resolveTargetDir();
final File beforeCodeFile = codeFile;
final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
@@ -16020,6 +15991,17 @@ public class PackageManagerService extends IPackageManager.Stub
return true;
}
+ // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
+ // flow, we won't need this method anymore.
+ private File resolveTargetDir() {
+ boolean isStagedInstall = (installFlags & INSTALL_STAGED) != 0;
+ if (isStagedInstall) {
+ return Environment.getDataAppDirectory(null);
+ } else {
+ return codeFile.getParentFile();
+ }
+ }
+
int doPostInstall(int status, int uid) {
if (status != PackageManager.INSTALL_SUCCEEDED) {
cleanUp();
@@ -24197,6 +24179,54 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ private int verifyReplacingVersionCode(PackageInfoLite pkgLite,
+ long requiredInstalledVersionCode, int installFlags) {
+ String packageName = pkgLite.packageName;
+ synchronized (mLock) {
+ // Package which currently owns the data that the new package will own if installed.
+ // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
+ // will be null whereas dataOwnerPkg will contain information about the package
+ // which was uninstalled while keeping its data.
+ AndroidPackage dataOwnerPkg = mPackages.get(packageName);
+ if (dataOwnerPkg == null) {
+ PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ dataOwnerPkg = ps.pkg;
+ }
+ }
+
+ if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
+ if (dataOwnerPkg == null) {
+ Slog.w(TAG, "Required installed version code was "
+ + requiredInstalledVersionCode
+ + " but package is not installed");
+ return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
+ }
+
+ if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
+ Slog.w(TAG, "Required installed version code was "
+ + requiredInstalledVersionCode
+ + " but actual installed version is "
+ + dataOwnerPkg.getLongVersionCode());
+ return PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
+ }
+ }
+
+ if (dataOwnerPkg != null) {
+ if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
+ dataOwnerPkg.isDebuggable())) {
+ try {
+ checkDowngrade(dataOwnerPkg, pkgLite);
+ } catch (PackageManagerException e) {
+ Slog.w(TAG, "Downgrade detected: " + e.getMessage());
+ return PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
+ }
+ }
+ }
+ }
+ return PackageManager.INSTALL_SUCCEEDED;
+ }
+
/**
* Check and throw if the given before/after packages would be considered a
* downgrade.
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 35c26d6cd54e..529f16af883d 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -794,18 +794,18 @@ public class StagingManager {
private void installApksInSession(PackageInstallerSession session)
throws PackageManagerException {
- final PackageInstallerSession apksToInstall = extractApksInSession(session);
- if (apksToInstall == null) {
+ if (!session.containsApkSession()) {
return;
}
- if ((apksToInstall.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+ if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
// If rollback is available for this session, notify the rollback
// manager of the apk session so it can properly enable rollback.
final RollbackManagerInternal rm =
LocalServices.getService(RollbackManagerInternal.class);
try {
- rm.notifyStagedApkSession(session.sessionId, apksToInstall.sessionId);
+ // TODO(b/136257624): extra apk session id in rollback is now redundant.
+ rm.notifyStagedApkSession(session.sessionId, session.sessionId);
} catch (RuntimeException re) {
Slog.e(TAG, "Failed to notifyStagedApkSession for session: "
+ session.sessionId, re);
@@ -813,7 +813,7 @@ public class StagingManager {
}
final LocalIntentReceiverSync receiver = new LocalIntentReceiverSync();
- apksToInstall.commit(receiver.getIntentSender(), false);
+ session.installStagedSession(receiver.getIntentSender());
final Intent result = receiver.getResult();
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);