diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 1b1e06a9a92f7..485127a79c27a 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -845,18 +845,11 @@ public abstract class PackageManagerInternal { "android.content.pm.extra.ENABLE_ROLLBACK_TOKEN"; /** - * Extra field name for the installFlags of a request to enable rollback + * Extra field name for the session id of a request to enable rollback * for a package. */ - public static final String EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS = - "android.content.pm.extra.ENABLE_ROLLBACK_INSTALL_FLAGS"; - - /** - * Extra field name for the user id an install is associated with when - * enabling rollback. - */ - public static final String EXTRA_ENABLE_ROLLBACK_USER = - "android.content.pm.extra.ENABLE_ROLLBACK_USER"; + public static final String EXTRA_ENABLE_ROLLBACK_SESSION_ID = + "android.content.pm.extra.ENABLE_ROLLBACK_SESSION_ID"; /** * Used as the {@code enableRollbackCode} argument for diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 41988d6c57866..5cc5059613a8b 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -1689,8 +1689,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } mRelinquished = true; - return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, - localObserver, params, mInstallerUid, mInstallSource, user, mSigningDetails); + return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, + sessionId, params, mInstallerUid, mInstallSource, user, mSigningDetails); } private static void maybeRenameFile(File from, File to) throws PackageManagerException { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 74cb93d7a101d..36843d4a9a0fc 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1967,6 +1967,7 @@ 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); if (params != null) { final InstallArgs args = params.mArgs; @@ -1982,8 +1983,8 @@ public class PackageManagerService extends IPackageManager.Stub Intent rollbackTimeoutIntent = new Intent( Intent.ACTION_CANCEL_ENABLE_ROLLBACK); rollbackTimeoutIntent.putExtra( - PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, - enableRollbackToken); + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID, + sessionId); rollbackTimeoutIntent.addFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM, @@ -14260,6 +14261,7 @@ public class PackageManagerService extends IPackageManager.Stub final long requiredInstalledVersionCode; final boolean forceQueryableOverride; final int mDataLoaderType; + final int mSessionId; InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, @@ -14283,6 +14285,7 @@ public class PackageManagerService extends IPackageManager.Stub this.requiredInstalledVersionCode = requiredInstalledVersionCode; this.forceQueryableOverride = false; this.mDataLoaderType = dataLoaderType; + this.mSessionId = -1; } InstallParams(ActiveInstallSession activeInstallSession) { @@ -14318,6 +14321,7 @@ public class PackageManagerService extends IPackageManager.Stub forceQueryableOverride = sessionParams.forceQueryableOverride; mDataLoaderType = (sessionParams.dataLoaderParams != null) ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE; + mSessionId = activeInstallSession.getSessionId(); } @Override @@ -14549,13 +14553,9 @@ public class PackageManagerService extends IPackageManager.Stub PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, enableRollbackToken); enableRollbackIntent.putExtra( - PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS, - installFlags); - enableRollbackIntent.putExtra( - PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER, - getRollbackUser().getIdentifier()); - enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), - PACKAGE_MIME_TYPE); + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID, + mSessionId); + enableRollbackIntent.setType(PACKAGE_MIME_TYPE); enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Allow the broadcast to be sent before boot complete. @@ -14581,6 +14581,7 @@ public class PackageManagerService extends IPackageManager.Stub final Message msg = mHandler.obtainMessage( ENABLE_ROLLBACK_TIMEOUT); msg.arg1 = enableRollbackToken; + msg.arg2 = mSessionId; mHandler.sendMessageDelayed(msg, rollbackTimeout); } }, null, 0, null, null); @@ -24590,6 +24591,7 @@ public class PackageManagerService extends IPackageManager.Stub private final String mPackageName; private final File mStagedDir; private final IPackageInstallObserver2 mObserver; + private final int mSessionId; private final PackageInstaller.SessionParams mSessionParams; private final int mInstallerUid; @NonNull private final InstallSource mInstallSource; @@ -24597,11 +24599,12 @@ public class PackageManagerService extends IPackageManager.Stub private final SigningDetails mSigningDetails; ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer, - PackageInstaller.SessionParams sessionParams, int installerUid, + int sessionId, PackageInstaller.SessionParams sessionParams, int installerUid, InstallSource installSource, UserHandle user, SigningDetails signingDetails) { mPackageName = packageName; mStagedDir = stagedDir; mObserver = observer; + mSessionId = sessionId; mSessionParams = sessionParams; mInstallerUid = installerUid; mInstallSource = Preconditions.checkNotNull(installSource); @@ -24621,6 +24624,10 @@ public class PackageManagerService extends IPackageManager.Stub return mObserver; } + public int getSessionId() { + return mSessionId; + } + public PackageInstaller.SessionParams getSessionParams() { return mSessionParams; } diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java index 7b96777b5987c..885f561d2a196 100644 --- a/services/core/java/com/android/server/rollback/Rollback.java +++ b/services/core/java/com/android/server/rollback/Rollback.java @@ -158,13 +158,6 @@ class Rollback { */ @Nullable public final String mInstallerPackageName; - /** - * This array holds all of the rollback tokens associated with package sessions included in - * this rollback. - */ - @GuardedBy("mLock") - private final IntArray mTokens = new IntArray(); - /** * Session ids for all packages in the install. For multi-package sessions, this is the list * of child session ids. For normal sessions, this list is a single element with the normal @@ -768,26 +761,6 @@ class Rollback { } } - /** - * Adds a rollback token to be associated with this rollback. This may be used to - * identify which rollback should be removed in case {@link PackageManager} sends an - * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} intent. - */ - void addToken(int token) { - synchronized (mLock) { - mTokens.add(token); - } - } - - /** - * Returns true if this rollback is associated with the provided {@code token}. - */ - boolean hasToken(int token) { - synchronized (mLock) { - return mTokens.indexOf(token) != -1; - } - } - /** * Returns true if this rollback contains the provided {@code packageSessionId}. */ diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index f9981d0d9c968..42fada19672e4 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -20,7 +20,6 @@ import android.Manifest; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.AppOpsManager; import android.content.BroadcastReceiver; @@ -201,18 +200,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { if (Intent.ACTION_PACKAGE_ENABLE_ROLLBACK.equals(intent.getAction())) { int token = intent.getIntExtra( PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, -1); - int installFlags = intent.getIntExtra( - PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS, 0); - int user = intent.getIntExtra( - PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER, 0); - - File newPackageCodePath = new File(intent.getData().getPath()); + int sessionId = intent.getIntExtra( + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID, -1); queueSleepIfNeeded(); getHandler().post(() -> { - boolean success = - enableRollback(installFlags, newPackageCodePath, user, token); + boolean success = enableRollback(sessionId); int ret = PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED; if (!success) { ret = PackageManagerInternal.ENABLE_ROLLBACK_FAILED; @@ -238,19 +232,16 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_CANCEL_ENABLE_ROLLBACK.equals(intent.getAction())) { - int token = intent.getIntExtra( - PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, -1); + int sessionId = intent.getIntExtra( + PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID, -1); if (LOCAL_LOGV) { - Slog.v(TAG, "broadcast=ACTION_CANCEL_ENABLE_ROLLBACK token=" + token); + Slog.v(TAG, "broadcast=ACTION_CANCEL_ENABLE_ROLLBACK id=" + sessionId); } synchronized (mLock) { - for (int i = 0; i < mRollbacks.size(); ++i) { - Rollback rollback = mRollbacks.get(i); - if (rollback.hasToken(token) && rollback.isEnabling()) { - mRollbacks.remove(i); - rollback.delete(mAppDataRollbackHelper); - break; - } + Rollback rollback = getRollbackForSessionLocked(sessionId); + if (rollback != null && rollback.isEnabling()) { + mRollbacks.remove(rollback); + rollback.delete(mAppDataRollbackHelper); } } } @@ -684,24 +675,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { return mHandlerThread.getThreadHandler(); } - // Returns true if session has installFlags and code path - // matching the installFlags and new package code path given to - // enableRollback. - @WorkerThread - private boolean sessionMatchesForEnableRollback(PackageInstaller.SessionInfo session, - int installFlags, File newPackageCodePath) { - if (session == null || session.resolvedBaseCodePath == null) { - return false; - } - - File packageCodePath = new File(session.resolvedBaseCodePath).getParentFile(); - if (newPackageCodePath.equals(packageCodePath) && installFlags == session.installFlags) { - return true; - } - - return false; - } - @AnyThread private Context getContextAsUser(UserHandle user) { try { @@ -716,58 +689,26 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * staged for install with rollback enabled. Called before the package has * been installed. * - * @param installFlags information about what is being installed. - * @param newPackageCodePath path to the package about to be installed. - * @param user the user that owns the install session to enable rollback on. - * @param token the distinct rollback token sent by package manager. + * @param sessionId the id of the install session * @return true if enabling the rollback succeeds, false otherwise. */ @WorkerThread - private boolean enableRollback( - int installFlags, File newPackageCodePath, @UserIdInt int user, int token) { + private boolean enableRollback(int sessionId) { if (LOCAL_LOGV) { - Slog.v(TAG, "enableRollback user=" + user + " token=" + token - + " path=" + newPackageCodePath.getAbsolutePath()); + Slog.v(TAG, "enableRollback sessionId=" + sessionId); } - // Find the session id associated with this install. - // TODO: It would be nice if package manager or package installer told - // us the session directly, rather than have to search for it - // ourselves. - - // getAllSessions only returns sessions for the associated user. - // Create a context with the right user so we can find the matching - // session. - final Context context = getContextAsUser(UserHandle.of(user)); - if (context == null) { - Slog.e(TAG, "Unable to create context for install session user."); + PackageInstaller installer = mContext.getPackageManager().getPackageInstaller(); + PackageInstaller.SessionInfo packageSession = installer.getSessionInfo(sessionId); + if (packageSession == null) { + Slog.e(TAG, "Unable to find session for enabled rollback."); return false; } - PackageInstaller.SessionInfo parentSession = null; - PackageInstaller.SessionInfo packageSession = null; - PackageInstaller installer = context.getPackageManager().getPackageInstaller(); - for (PackageInstaller.SessionInfo info : installer.getAllSessions()) { - if (info.isMultiPackage()) { - for (int childId : info.getChildSessionIds()) { - PackageInstaller.SessionInfo child = installer.getSessionInfo(childId); - if (sessionMatchesForEnableRollback(child, installFlags, newPackageCodePath)) { - // TODO: Check we only have one matching session? - parentSession = info; - packageSession = child; - break; - } - } - } else if (sessionMatchesForEnableRollback(info, installFlags, newPackageCodePath)) { - // TODO: Check we only have one matching session? - parentSession = info; - packageSession = info; - break; - } - } - - if (parentSession == null || packageSession == null) { - Slog.e(TAG, "Unable to find session for enabled rollback."); + PackageInstaller.SessionInfo parentSession = packageSession.hasParentSessionId() + ? installer.getSessionInfo(packageSession.getParentSessionId()) : packageSession; + if (parentSession == null) { + Slog.e(TAG, "Unable to find parent session for enabled rollback."); return false; } @@ -804,7 +745,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { newRollback = createNewRollbackLocked(parentSession); } } - newRollback.addToken(token); return enableRollbackForPackageSession(newRollback, packageSession); }