diff --git a/services/core/java/com/android/server/pm/FileInstallArgs.java b/services/core/java/com/android/server/pm/FileInstallArgs.java index 85c3cc91ecf06..4d9e2a311ce23 100644 --- a/services/core/java/com/android/server/pm/FileInstallArgs.java +++ b/services/core/java/com/android/server/pm/FileInstallArgs.java @@ -68,7 +68,7 @@ class FileInstallArgs extends InstallArgs { // /data/app/com.example/dalvik/arm/base.apk@classes.dex /** New install */ - FileInstallArgs(InstallParams params) { + FileInstallArgs(InstallingSession params) { super(params); } diff --git a/services/core/java/com/android/server/pm/HandlerParams.java b/services/core/java/com/android/server/pm/HandlerParams.java deleted file mode 100644 index 57a8a7abe6e80..0000000000000 --- a/services/core/java/com/android/server/pm/HandlerParams.java +++ /dev/null @@ -1,64 +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.DEBUG_INSTALL; -import static com.android.server.pm.PackageManagerService.TAG; - -import android.annotation.NonNull; -import android.os.UserHandle; -import android.util.Slog; - -abstract class HandlerParams { - /** User handle for the user requesting the information or installation. */ - private final UserHandle mUser; - String mTraceMethod; - int mTraceCookie; - @NonNull - final PackageManagerService mPm; - final InstallPackageHelper mInstallPackageHelper; - - // TODO(b/198166813): remove PMS dependency - HandlerParams(UserHandle user, PackageManagerService pm) { - mUser = user; - mPm = pm; - mInstallPackageHelper = new InstallPackageHelper(mPm); - } - - UserHandle getUser() { - return mUser; - } - - HandlerParams setTraceMethod(String traceMethod) { - mTraceMethod = traceMethod; - return this; - } - - HandlerParams setTraceCookie(int traceCookie) { - mTraceCookie = traceCookie; - return this; - } - - final void startCopy() { - if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); - handleStartCopy(); - handleReturnCode(); - } - - abstract void handleStartCopy(); - abstract void handleReturnCode(); -} diff --git a/services/core/java/com/android/server/pm/InstallArgs.java b/services/core/java/com/android/server/pm/InstallArgs.java index 03c68d9f64b0b..fa8a9756c179c 100644 --- a/services/core/java/com/android/server/pm/InstallArgs.java +++ b/services/core/java/com/android/server/pm/InstallArgs.java @@ -29,9 +29,9 @@ import com.android.server.pm.parsing.pkg.ParsedPackage; import java.util.List; abstract class InstallArgs { - /** @see InstallParams#mOriginInfo */ + /** @see InstallingSession#mOriginInfo */ final OriginInfo mOriginInfo; - /** @see InstallParams#mMoveInfo */ + /** @see InstallingSession#mMoveInfo */ final MoveInfo mMoveInfo; final IPackageInstallObserver2 mObserver; @@ -97,7 +97,7 @@ abstract class InstallArgs { } /** New install */ - InstallArgs(InstallParams params) { + InstallArgs(InstallingSession params) { this(params.mOriginInfo, params.mMoveInfo, params.mObserver, params.mInstallFlags, params.mInstallSource, params.mVolumeUuid, params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride, @@ -125,24 +125,6 @@ abstract class InstallArgs { abstract void cleanUpResourcesLI(); abstract boolean doPostDeleteLI(boolean delete); - /** - * Called before the source arguments are copied. This is used mostly - * for MoveParams when it needs to read the source file to put it in the - * destination. - */ - int doPreCopy() { - return PackageManager.INSTALL_SUCCEEDED; - } - - /** - * Called after the source arguments are copied. This is used mostly for - * MoveParams when it needs to read the source file to put it in the - * destination. - */ - int doPostCopy(int uid) { - return PackageManager.INSTALL_SUCCEEDED; - } - protected boolean isEphemeral() { return (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0; } diff --git a/services/core/java/com/android/server/pm/InstallParams.java b/services/core/java/com/android/server/pm/InstallingSession.java similarity index 74% rename from services/core/java/com/android/server/pm/InstallParams.java rename to services/core/java/com/android/server/pm/InstallingSession.java index fb189fb6d02cb..b3e039e5374bc 100644 --- a/services/core/java/com/android/server/pm/InstallParams.java +++ b/services/core/java/com/android/server/pm/InstallingSession.java @@ -22,8 +22,8 @@ import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; +import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; import static com.android.server.pm.PackageManagerService.DEBUG_INSTANT; -import static com.android.server.pm.PackageManagerService.INIT_COPY; import static com.android.server.pm.PackageManagerService.TAG; import android.annotation.NonNull; @@ -35,10 +35,8 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.SigningDetails; import android.content.pm.parsing.PackageLite; -import android.os.Message; import android.os.Trace; import android.os.UserHandle; -import android.util.ArrayMap; import android.util.Pair; import android.util.Slog; @@ -48,12 +46,10 @@ import com.android.internal.util.Preconditions; import com.android.server.pm.parsing.pkg.AndroidPackage; import java.io.File; -import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; -final class InstallParams extends HandlerParams { +class InstallingSession { final OriginInfo mOriginInfo; final MoveInfo mMoveInfo; final IPackageInstallObserver2 mObserver; @@ -70,18 +66,27 @@ final class InstallParams extends HandlerParams { final int mInstallReason; final int mInstallScenario; @Nullable - MultiPackageInstallParams mParentInstallParams; + MultiPackageInstallingSession mParentInstallingSession; final boolean mForceQueryableOverride; final int mDataLoaderType; final long mRequiredInstalledVersionCode; final int mPackageSource; final PackageLite mPackageLite; + String mTraceMethod; + int mTraceCookie; + /** User handle for the user requesting the information or installation. */ + private final UserHandle mUser; + @NonNull + final PackageManagerService mPm; + final InstallPackageHelper mInstallPackageHelper; - InstallParams(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer, + InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, UserHandle user, String packageAbiOverride, int packageSource, PackageLite packageLite, PackageManagerService pm) { - super(user, pm); + mPm = pm; + mUser = user; + mInstallPackageHelper = new InstallPackageHelper(mPm); mOriginInfo = originInfo; mMoveInfo = moveInfo; mObserver = observer; @@ -103,11 +108,13 @@ final class InstallParams extends HandlerParams { mPackageLite = packageLite; } - InstallParams(File stagedDir, IPackageInstallObserver2 observer, + InstallingSession(File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, UserHandle user, SigningDetails signingDetails, int installerUid, PackageLite packageLite, PackageManagerService pm) { - super(user, pm); + mPm = pm; + mUser = user; + mInstallPackageHelper = new InstallPackageHelper(mPm); mOriginInfo = OriginInfo.fromStagedFile(stagedDir); mMoveInfo = null; mInstallReason = fixUpInstallReason( @@ -132,7 +139,7 @@ final class InstallParams extends HandlerParams { @Override public String toString() { - return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) + return "InstallingSession{" + Integer.toHexString(System.identityHashCode(this)) + " file=" + mOriginInfo.mFile + "}"; } @@ -225,7 +232,6 @@ final class InstallParams extends HandlerParams { pkgLite.installLocation); } - @Override void handleReturnCode() { processPendingInstall(); } @@ -239,32 +245,25 @@ final class InstallParams extends HandlerParams { F2fsUtils.releaseCompressedBlocks( mPm.mContext.getContentResolver(), new File(args.getCodePath())); } - if (mParentInstallParams != null) { - mParentInstallParams.tryProcessInstallRequest(args, mRet); + if (mParentInstallingSession != null) { + mParentInstallingSession.tryProcessInstallRequest(args, mRet); } else { PackageInstalledInfo res = new PackageInstalledInfo(mRet); - processInstallRequestsAsync( - res.mReturnCode == PackageManager.INSTALL_SUCCEEDED, - Collections.singletonList(new InstallRequest(args, res))); + // Queue up an async operation since the package installation may take a little while. + mPm.mHandler.post(() -> mInstallPackageHelper.processInstallRequests( + res.mReturnCode == PackageManager.INSTALL_SUCCEEDED /* success */, + Collections.singletonList(new InstallRequest(args, res)))); } } - private InstallArgs createInstallArgs(InstallParams params) { - if (params.mMoveInfo != null) { - return new MoveInstallArgs(params); + private InstallArgs createInstallArgs(InstallingSession installingSession) { + if (installingSession.mMoveInfo != null) { + return new MoveInstallArgs(installingSession); } else { - return new FileInstallArgs(params); + return new FileInstallArgs(installingSession); } } - // Queue up an async operation since the package installation may take a little while. - private void processInstallRequestsAsync(boolean success, - List installRequests) { - mPm.mHandler.post(() -> { - mInstallPackageHelper.processInstallRequests(success, installRequests); - }); - } - /** * Ensure that the install reason matches what we know about the package installer (e.g. whether * it is acting on behalf on an enterprise or the user). @@ -316,107 +315,57 @@ final class InstallParams extends HandlerParams { } public void installStage() { - final Message msg = mPm.mHandler.obtainMessage(INIT_COPY); setTraceMethod("installStage").setTraceCookie(System.identityHashCode(this)); - msg.obj = this; - Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", - System.identityHashCode(msg.obj)); + System.identityHashCode(this)); Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", - System.identityHashCode(msg.obj)); - - mPm.mHandler.sendMessage(msg); + System.identityHashCode(this)); + mPm.mHandler.post(this::start); } - public void installStage(List children) + public void installStage(List children) throws PackageManagerException { - final Message msg = mPm.mHandler.obtainMessage(INIT_COPY); - final MultiPackageInstallParams params = - new MultiPackageInstallParams(this, children, mPm); - params.setTraceMethod("installStageMultiPackage") - .setTraceCookie(System.identityHashCode(params)); - msg.obj = params; + final MultiPackageInstallingSession installingSession = + new MultiPackageInstallingSession(getUser(), children, mPm); + setTraceMethod("installStageMultiPackage").setTraceCookie(System.identityHashCode( + installingSession)); Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage", - System.identityHashCode(msg.obj)); + System.identityHashCode(installingSession)); Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", - System.identityHashCode(msg.obj)); - mPm.mHandler.sendMessage(msg); + System.identityHashCode(installingSession)); + mPm.mHandler.post(installingSession::start); } public void movePackage() { - final Message msg = mPm.mHandler.obtainMessage(INIT_COPY); setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(this)); - msg.obj = this; - Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", - System.identityHashCode(msg.obj)); + System.identityHashCode(this)); Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", - System.identityHashCode(msg.obj)); - mPm.mHandler.sendMessage(msg); + System.identityHashCode(this)); + mPm.mHandler.post(this::start); } - /** - * Container for a multi-package install which refers to all install sessions and args being - * committed together. - */ - final class MultiPackageInstallParams extends HandlerParams { - private final List mChildParams; - private final Map mCurrentState; - - MultiPackageInstallParams(InstallParams parent, List childParams, - PackageManagerService pm) - throws PackageManagerException { - super(parent.getUser(), pm); - if (childParams.size() == 0) { - throw new PackageManagerException("No child sessions found!"); - } - mChildParams = childParams; - for (int i = 0; i < childParams.size(); i++) { - final InstallParams childParam = childParams.get(i); - childParam.mParentInstallParams = this; - } - this.mCurrentState = new ArrayMap<>(mChildParams.size()); - } - - @Override - void handleStartCopy() { - for (InstallParams params : mChildParams) { - params.handleStartCopy(); - } - } - - @Override - void handleReturnCode() { - for (InstallParams params : mChildParams) { - params.handleReturnCode(); - } - } - - void tryProcessInstallRequest(InstallArgs args, int currentStatus) { - mCurrentState.put(args, currentStatus); - if (mCurrentState.size() != mChildParams.size()) { - return; - } - int completeStatus = PackageManager.INSTALL_SUCCEEDED; - for (Integer status : mCurrentState.values()) { - if (status == PackageManager.INSTALL_UNKNOWN) { - return; - } else if (status != PackageManager.INSTALL_SUCCEEDED) { - completeStatus = status; - break; - } - } - final List installRequests = new ArrayList<>(mCurrentState.size()); - for (Map.Entry entry : mCurrentState.entrySet()) { - installRequests.add(new InstallRequest(entry.getKey(), - new PackageInstalledInfo(completeStatus))); - } - processInstallRequestsAsync( - completeStatus == PackageManager.INSTALL_SUCCEEDED, - installRequests); - } + public UserHandle getUser() { + return mUser; } + private void start() { + if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this); + Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", + System.identityHashCode(this)); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startInstall"); + handleStartCopy(); + handleReturnCode(); + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + private InstallingSession setTraceMethod(String traceMethod) { + mTraceMethod = traceMethod; + return this; + } + + private void setTraceCookie(int traceCookie) { + mTraceCookie = traceCookie; + } } diff --git a/services/core/java/com/android/server/pm/MoveInstallArgs.java b/services/core/java/com/android/server/pm/MoveInstallArgs.java index 424707f3f8491..1f167ce2ec9a6 100644 --- a/services/core/java/com/android/server/pm/MoveInstallArgs.java +++ b/services/core/java/com/android/server/pm/MoveInstallArgs.java @@ -37,7 +37,7 @@ final class MoveInstallArgs extends InstallArgs { private File mCodeFile; /** New install */ - MoveInstallArgs(InstallParams params) { + MoveInstallArgs(InstallingSession params) { super(params); } diff --git a/services/core/java/com/android/server/pm/MovePackageHelper.java b/services/core/java/com/android/server/pm/MovePackageHelper.java index 05f84e37499d4..a0fbf173cfdce 100644 --- a/services/core/java/com/android/server/pm/MovePackageHelper.java +++ b/services/core/java/com/android/server/pm/MovePackageHelper.java @@ -291,10 +291,10 @@ public final class MovePackageHelper { final ParseResult ret = ApkLiteParseUtils.parsePackageLite(input, new File(origin.mResolvedPath), /* flags */ 0); final PackageLite lite = ret.isSuccess() ? ret.getResult() : null; - final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, - installSource, volumeUuid, user, packageAbiOverride, + final InstallingSession installingSession = new InstallingSession(origin, move, + installObserver, installFlags, installSource, volumeUuid, user, packageAbiOverride, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, lite, mPm); - params.movePackage(); + installingSession.movePackage(); } /** diff --git a/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java b/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java new file mode 100644 index 0000000000000..e5ed5d8a5f5b6 --- /dev/null +++ b/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2022 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 android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; + +import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; +import static com.android.server.pm.PackageManagerService.TAG; + +import android.annotation.NonNull; +import android.content.pm.PackageManager; +import android.os.Trace; +import android.os.UserHandle; +import android.util.ArrayMap; +import android.util.Slog; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Container for a multi-package install which refers to all install sessions and args being + * committed together. + */ +final class MultiPackageInstallingSession { + private final List mChildInstallingSessions; + private final Map mCurrentState; + @NonNull + final PackageManagerService mPm; + final UserHandle mUser; + + MultiPackageInstallingSession(UserHandle user, List childInstallingSessions, + PackageManagerService pm) + throws PackageManagerException { + if (childInstallingSessions.size() == 0) { + throw new PackageManagerException("No child sessions found!"); + } + mPm = pm; + mUser = user; + mChildInstallingSessions = childInstallingSessions; + for (int i = 0; i < childInstallingSessions.size(); i++) { + final InstallingSession childInstallingSession = childInstallingSessions.get(i); + childInstallingSession.mParentInstallingSession = this; + } + this.mCurrentState = new ArrayMap<>(mChildInstallingSessions.size()); + } + + public void start() { + if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this); + Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", + System.identityHashCode(this)); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start"); + for (InstallingSession childInstallingSession : mChildInstallingSessions) { + childInstallingSession.handleStartCopy(); + } + for (InstallingSession childInstallingSession : mChildInstallingSessions) { + childInstallingSession.handleReturnCode(); + } + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + + public void tryProcessInstallRequest(InstallArgs args, int currentStatus) { + mCurrentState.put(args, currentStatus); + if (mCurrentState.size() != mChildInstallingSessions.size()) { + return; + } + int completeStatus = PackageManager.INSTALL_SUCCEEDED; + for (Integer status : mCurrentState.values()) { + if (status == PackageManager.INSTALL_UNKNOWN) { + return; + } else if (status != PackageManager.INSTALL_SUCCEEDED) { + completeStatus = status; + break; + } + } + final List installRequests = new ArrayList<>(mCurrentState.size()); + for (Map.Entry entry : mCurrentState.entrySet()) { + installRequests.add(new InstallRequest(entry.getKey(), + new PackageInstalledInfo(completeStatus))); + } + int finalCompleteStatus = completeStatus; + final InstallPackageHelper installPackageHelper = new InstallPackageHelper(mPm); + mPm.mHandler.post(() -> installPackageHelper.processInstallRequests( + finalCompleteStatus == PackageManager.INSTALL_SUCCEEDED /* success */, + installRequests)); + } + + @Override + public String toString() { + return "MultiPackageInstallingSession{" + Integer.toHexString(System.identityHashCode(this)) + + "}"; + } +} diff --git a/services/core/java/com/android/server/pm/MultiPackageVerifyingSession.java b/services/core/java/com/android/server/pm/MultiPackageVerifyingSession.java new file mode 100644 index 0000000000000..06e5497148868 --- /dev/null +++ b/services/core/java/com/android/server/pm/MultiPackageVerifyingSession.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2022 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 android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; + +import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; +import static com.android.server.pm.PackageManagerService.TAG; + +import android.content.pm.IPackageInstallObserver2; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.RemoteException; +import android.os.Trace; +import android.os.UserHandle; +import android.util.ArraySet; +import android.util.Slog; + +import java.util.List; +import java.util.Set; + +/** + * Container for a multi-package verifying session which refers to all verifying sessions and args + * being committed together. + */ +final class MultiPackageVerifyingSession { + private final IPackageInstallObserver2 mObserver; + private final List mChildVerifyingSessions; + private final Set mVerificationState; + private final UserHandle mUser; + + MultiPackageVerifyingSession(VerifyingSession parent, List children) + throws PackageManagerException { + mUser = parent.getUser(); + if (children.size() == 0) { + throw new PackageManagerException("No child sessions found!"); + } + mChildVerifyingSessions = children; + // Provide every child with reference to this object as parent + for (int i = 0; i < children.size(); i++) { + final VerifyingSession childVerifyingSession = children.get(i); + childVerifyingSession.mParentVerifyingSession = this; + } + mVerificationState = new ArraySet<>(mChildVerifyingSessions.size()); + mObserver = parent.mObserver; + } + + public void start() { + if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this); + Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueVerify", + System.identityHashCode(this)); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startVerify"); + for (VerifyingSession childVerifyingSession : mChildVerifyingSessions) { + childVerifyingSession.handleStartVerify(); + } + for (VerifyingSession childVerifyingSession : mChildVerifyingSessions) { + childVerifyingSession.handleReturnCode(); + } + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + + public void trySendVerificationCompleteNotification(VerifyingSession child) { + mVerificationState.add(child); + if (mVerificationState.size() != mChildVerifyingSessions.size()) { + return; + } + int completeStatus = PackageManager.INSTALL_SUCCEEDED; + String errorMsg = null; + for (VerifyingSession childVerifyingSession : mVerificationState) { + int status = childVerifyingSession.getRet(); + if (status != PackageManager.INSTALL_SUCCEEDED) { + completeStatus = status; + errorMsg = childVerifyingSession.getErrorMessage(); + break; + } + } + try { + mObserver.onPackageInstalled(null, completeStatus, + errorMsg, new Bundle()); + } catch (RemoteException e) { + Slog.i(TAG, "Observer no longer exists."); + } + } + + @Override + public String toString() { + return "MultiPackageVerifyingSession{" + Integer.toHexString(System.identityHashCode(this)) + + "}"; + } +} diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java index 0dfa31c5f1fc3..c950dcfc30bd8 100644 --- a/services/core/java/com/android/server/pm/PackageHandler.java +++ b/services/core/java/com/android/server/pm/PackageHandler.java @@ -28,7 +28,6 @@ import static com.android.server.pm.PackageManagerService.DEFERRED_PENDING_KILL_ import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION; import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS; import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT; -import static com.android.server.pm.PackageManagerService.INIT_COPY; import static com.android.server.pm.PackageManagerService.INSTANT_APP_RESOLUTION_PHASE_TWO; import static com.android.server.pm.PackageManagerService.INTEGRITY_VERIFICATION_COMPLETE; import static com.android.server.pm.PackageManagerService.PACKAGE_VERIFIED; @@ -81,18 +80,6 @@ final class PackageHandler extends Handler { void doHandleMessage(Message msg) { switch (msg.what) { - case INIT_COPY: { - HandlerParams params = (HandlerParams) msg.obj; - if (params != null) { - if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params); - Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", - System.identityHashCode(params)); - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); - params.startCopy(); - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - break; - } case SEND_PENDING_BROADCAST: { mInstallPackageHelper.sendPendingBroadcasts(); break; @@ -160,24 +147,24 @@ final class PackageHandler extends Handler { final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; - final VerificationParams params = state.getVerificationParams(); - final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); + final VerifyingSession verifyingSession = state.getVerifyingSession(); + final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile); String errorMsg = "Verification timed out for " + originUri; Slog.i(TAG, errorMsg); - final UserHandle user = params.getUser(); + final UserHandle user = verifyingSession.getUser(); if (response.code != PackageManager.VERIFICATION_REJECT) { Slog.i(TAG, "Continuing with installation of " + originUri); state.setVerifierResponse(response.callerUid, response.code); VerificationUtils.broadcastPackageVerified(verificationId, originUri, - PackageManager.VERIFICATION_ALLOW, null, params.mDataLoaderType, - user, mPm.mContext); + PackageManager.VERIFICATION_ALLOW, null, + verifyingSession.mDataLoaderType, user, mPm.mContext); } else { VerificationUtils.broadcastPackageVerified(verificationId, originUri, PackageManager.VERIFICATION_REJECT, null, - params.mDataLoaderType, user, mPm.mContext); - params.setReturnCode( + verifyingSession.mDataLoaderType, user, mPm.mContext); + verifyingSession.setReturnCode( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMsg); state.setVerifierResponse(response.callerUid, response.code); } @@ -189,7 +176,7 @@ final class PackageHandler extends Handler { Trace.asyncTraceEnd( TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); - params.handleVerificationFinished(); + verifyingSession.handleVerificationFinished(); break; } case CHECK_PENDING_INTEGRITY_VERIFICATION: { @@ -197,8 +184,8 @@ final class PackageHandler extends Handler { final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); if (state != null && !state.isIntegrityVerificationComplete()) { - final VerificationParams params = state.getVerificationParams(); - final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); + final VerifyingSession verifyingSession = state.getVerifyingSession(); + final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile); String errorMsg = "Integrity verification timed out for " + originUri; Slog.i(TAG, errorMsg); @@ -210,7 +197,7 @@ final class PackageHandler extends Handler { == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) { Slog.i(TAG, "Integrity check times out, continuing with " + originUri); } else { - params.setReturnCode( + verifyingSession.setReturnCode( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMsg); } @@ -224,7 +211,7 @@ final class PackageHandler extends Handler { "integrity_verification", verificationId); - params.handleIntegrityVerificationFinished(); + verifyingSession.handleIntegrityVerificationFinished(); } break; } @@ -247,15 +234,15 @@ final class PackageHandler extends Handler { state.setVerifierResponse(response.callerUid, response.code); if (state.isVerificationComplete()) { - final VerificationParams params = state.getVerificationParams(); - final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); + final VerifyingSession verifyingSession = state.getVerifyingSession(); + final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile); if (state.isInstallAllowed()) { VerificationUtils.broadcastPackageVerified(verificationId, originUri, - response.code, null, params.mDataLoaderType, params.getUser(), - mPm.mContext); + response.code, null, verifyingSession.mDataLoaderType, + verifyingSession.getUser(), mPm.mContext); } else { - params.setReturnCode( + verifyingSession.setReturnCode( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Install not allowed"); } @@ -267,7 +254,7 @@ final class PackageHandler extends Handler { Trace.asyncTraceEnd( TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); - params.handleVerificationFinished(); + verifyingSession.handleVerificationFinished(); } break; @@ -283,15 +270,15 @@ final class PackageHandler extends Handler { } final int response = (Integer) msg.obj; - final VerificationParams params = state.getVerificationParams(); - final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); + final VerifyingSession verifyingSession = state.getVerifyingSession(); + final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile); state.setIntegrityVerificationResult(response); if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) { Slog.i(TAG, "Integrity check passed for " + originUri); } else { - params.setReturnCode( + verifyingSession.setReturnCode( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Integrity check failed for " + originUri); } @@ -305,7 +292,7 @@ final class PackageHandler extends Handler { "integrity_verification", verificationId); - params.handleIntegrityVerificationFinished(); + verifyingSession.handleIntegrityVerificationFinished(); break; } case INSTANT_APP_RESOLUTION_PHASE_TWO: { @@ -321,7 +308,7 @@ final class PackageHandler extends Handler { case ENABLE_ROLLBACK_STATUS: { final int enableRollbackToken = msg.arg1; final int enableRollbackCode = msg.arg2; - final VerificationParams params = + final VerifyingSession params = mPm.mPendingEnableRollback.get(enableRollbackToken); if (params == null) { Slog.w(TAG, "Invalid rollback enabled token " @@ -346,7 +333,7 @@ final class PackageHandler extends Handler { case ENABLE_ROLLBACK_TIMEOUT: { final int enableRollbackToken = msg.arg1; final int sessionId = msg.arg2; - final VerificationParams params = + final VerifyingSession params = mPm.mPendingEnableRollback.get(enableRollbackToken); if (params != null) { final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 47eff4975a1d4..df02fe17f47ba 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2386,21 +2386,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { List> futures = new ArrayList<>(); CompletableFuture future = new CompletableFuture<>(); futures.add(future); - final InstallParams installingSession = makeInstallParams(future); + final InstallingSession installingSession = createInstallingSession(future); if (isMultiPackage()) { final List childSessions = getChildSessions(); - List installingChildSessions = new ArrayList<>(childSessions.size()); + List installingChildSessions = + new ArrayList<>(childSessions.size()); for (int i = 0; i < childSessions.size(); ++i) { final PackageInstallerSession session = childSessions.get(i); future = new CompletableFuture<>(); futures.add(future); - final InstallParams installingChildSession = session.makeInstallParams(future); + final InstallingSession installingChildSession = + session.createInstallingSession(future); if (installingChildSession != null) { installingChildSessions.add(installingChildSession); } } if (!installingChildSessions.isEmpty()) { - installingSession.installStage(installingChildSessions); + Objects.requireNonNull(installingSession).installStage(installingChildSessions); } } else if (installingSession != null) { installingSession.installStage(); @@ -2437,12 +2439,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /** * Stages this session for install and returns a - * {@link InstallParams} representing this new staged state. + * {@link InstallingSession} representing this new staged state. * * @param future a future that will be completed when this session is completed. */ @Nullable - private InstallParams makeInstallParams(CompletableFuture future) + private InstallingSession createInstallingSession(CompletableFuture future) throws PackageManagerException { synchronized (mLock) { if (!mSealed) { @@ -2500,7 +2502,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } synchronized (mLock) { - return new InstallParams(stageDir, localObserver, params, mInstallSource, user, + return new InstallingSession(stageDir, localObserver, params, mInstallSource, user, mSigningDetails, mInstallerUid, mPackageLite, mPm); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ebce22716644b..7e47001e5bd1e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -752,7 +752,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService * List of packages waiting for rollback to be enabled. * Handler thread only! */ - final SparseArray mPendingEnableRollback = new SparseArray<>(); + final SparseArray mPendingEnableRollback = new SparseArray<>(); final PackageInstallerService mInstallerService; @@ -857,7 +857,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService final PendingPackageBroadcasts mPendingBroadcasts; static final int SEND_PENDING_BROADCAST = 1; - static final int INIT_COPY = 5; + // public static final int UNUSED = 5; static final int POST_INSTALL = 9; static final int WRITE_SETTINGS = 13; static final int WRITE_PACKAGE_RESTRICTIONS = 14; diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java index 975a272416d90..731a1a53260d2 100644 --- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java +++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java @@ -186,12 +186,12 @@ final class PackageSessionVerifier { } } }; - final VerificationParams verifyingSession = makeVerificationParams(session, observer); + final VerifyingSession verifyingSession = createVerifyingSession(session, observer); if (session.isMultiPackage()) { final List childSessions = session.getChildSessions(); - List verifyingChildSessions = new ArrayList<>(childSessions.size()); + List verifyingChildSessions = new ArrayList<>(childSessions.size()); for (PackageInstallerSession child : childSessions) { - verifyingChildSessions.add(makeVerificationParams(child, null)); + verifyingChildSessions.add(createVerifyingSession(child, null)); } verifyingSession.verifyStage(verifyingChildSessions); } else { @@ -199,7 +199,7 @@ final class PackageSessionVerifier { } } - private VerificationParams makeVerificationParams( + private VerifyingSession createVerifyingSession( PackageInstallerSession session, IPackageInstallObserver2 observer) { final UserHandle user; if ((session.params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { @@ -207,7 +207,7 @@ final class PackageSessionVerifier { } else { user = new UserHandle(session.userId); } - return new VerificationParams(user, session.stageDir, observer, session.params, + return new VerifyingSession(user, session.stageDir, observer, session.params, session.getInstallSource(), session.getInstallerUid(), session.getSigningDetails(), session.sessionId, session.getPackageLite(), session.getUserActionRequired(), mPm); } diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java index a652d1c843eb4..445b3a4145ddb 100644 --- a/services/core/java/com/android/server/pm/PackageVerificationState.java +++ b/services/core/java/com/android/server/pm/PackageVerificationState.java @@ -26,7 +26,7 @@ import android.util.SparseBooleanArray; * sufficient verifiers, then package verification is considered complete. */ class PackageVerificationState { - private final VerificationParams mParams; + private final VerifyingSession mVerifyingSession; private final SparseBooleanArray mSufficientVerifierUids; @@ -48,14 +48,14 @@ 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(VerificationParams params) { - mParams = params; + PackageVerificationState(VerifyingSession verifyingSession) { + mVerifyingSession = verifyingSession; mSufficientVerifierUids = new SparseBooleanArray(); mExtendedTimeout = false; } - VerificationParams getVerificationParams() { - return mParams; + VerifyingSession getVerifyingSession() { + return mVerifyingSession; } /** Sets the user ID of the required package verifier. */ diff --git a/services/core/java/com/android/server/pm/VerificationParams.java b/services/core/java/com/android/server/pm/VerifyingSession.java similarity index 90% rename from services/core/java/com/android/server/pm/VerificationParams.java rename to services/core/java/com/android/server/pm/VerifyingSession.java index 0e8b3997da2c7..726bfba11f008 100644 --- a/services/core/java/com/android/server/pm/VerificationParams.java +++ b/services/core/java/com/android/server/pm/VerifyingSession.java @@ -29,6 +29,7 @@ import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static com.android.server.pm.PackageManagerService.CHECK_PENDING_INTEGRITY_VERIFICATION; import static com.android.server.pm.PackageManagerService.CHECK_PENDING_VERIFICATION; +import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY; import static com.android.server.pm.PackageManagerService.DEFAULT_VERIFICATION_RESPONSE; import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT; @@ -67,7 +68,6 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.Settings; import android.text.TextUtils; -import android.util.ArraySet; import android.util.Pair; import android.util.Slog; @@ -77,9 +77,8 @@ import com.android.server.sdksandbox.SdkSandboxManagerLocal; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Set; -final class VerificationParams extends HandlerParams { +final class VerifyingSession { /** * Whether verification is enabled by default. */ @@ -119,7 +118,7 @@ final class VerificationParams extends HandlerParams { final VerificationInfo mVerificationInfo; final SigningDetails mSigningDetails; @Nullable - MultiPackageVerificationParams mParentVerificationParams; + MultiPackageVerifyingSession mParentVerifyingSession; final long mRequiredInstalledVersionCode; final int mDataLoaderType; final int mSessionId; @@ -132,12 +131,18 @@ final class VerificationParams extends HandlerParams { private String mErrorMessage = null; final PackageLite mPackageLite; + private final UserHandle mUser; + @NonNull + final PackageManagerService mPm; + final InstallPackageHelper mInstallPackageHelper; - VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer, + VerifyingSession(UserHandle user, File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite, boolean userActionRequired, PackageManagerService pm) { - super(user, pm); + mPm = pm; + mUser = user; + mInstallPackageHelper = new InstallPackageHelper(mPm); mOriginInfo = OriginInfo.fromStagedFile(stagedDir); mObserver = observer; mInstallFlags = sessionParams.installFlags; @@ -160,11 +165,11 @@ final class VerificationParams extends HandlerParams { @Override public String toString() { - return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) + return "VerifyingSession{" + Integer.toHexString(System.identityHashCode(this)) + " file=" + mOriginInfo.mFile + "}"; } - public void handleStartCopy() { + public void handleStartVerify() { PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mPm.mContext, mPackageLite, mOriginInfo.mResolvedPath, mInstallFlags, mPackageAbiOverride); @@ -744,7 +749,6 @@ final class VerificationParams extends HandlerParams { handleReturnCode(); } - void handleRollbackEnabled() { // TODO(b/112431924): Consider halting the install if we // couldn't enable rollback. @@ -752,7 +756,6 @@ final class VerificationParams extends HandlerParams { handleReturnCode(); } - @Override void handleReturnCode() { if (mWaitForVerificationToComplete || mWaitForIntegrityVerificationToComplete || mWaitForEnableRollbackToComplete) { @@ -762,8 +765,8 @@ final class VerificationParams extends HandlerParams { } private void sendVerificationCompleteNotification() { - if (mParentVerificationParams != null) { - mParentVerificationParams.trySendVerificationCompleteNotification(this); + if (mParentVerifyingSession != null) { + mParentVerifyingSession.trySendVerificationCompleteNotification(this); } else { try { mObserver.onPackageInstalled(null, mRet, mErrorMessage, @@ -774,77 +777,36 @@ final class VerificationParams extends HandlerParams { } } + private void start() { + if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this); + Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueVerify", + System.identityHashCode(this)); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start"); + handleStartVerify(); + handleReturnCode(); + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + public void verifyStage() { - mPm.mHandler.post(this::startCopy); + Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueVerify", + System.identityHashCode(this)); + mPm.mHandler.post(this::start); } - public void verifyStage(List children) + public void verifyStage(List children) throws PackageManagerException { - final MultiPackageVerificationParams params = - new MultiPackageVerificationParams(this, children, mPm); - mPm.mHandler.post(params::startCopy); + final MultiPackageVerifyingSession multiPackageVerifyingSession = + new MultiPackageVerifyingSession(this, children); + mPm.mHandler.post(multiPackageVerifyingSession::start); } - /** - * Container for a multi-package install which refers to all install sessions and args being - * committed together. - */ - static final class MultiPackageVerificationParams extends HandlerParams { - private final IPackageInstallObserver2 mObserver; - private final List mChildParams; - private final Set mVerificationState; - - MultiPackageVerificationParams(VerificationParams parent, List children, - PackageManagerService pm) throws PackageManagerException { - super(parent.getUser(), pm); - if (children.size() == 0) { - throw new PackageManagerException("No child sessions found!"); - } - mChildParams = children; - // Provide every child with reference to this object as parent - for (int i = 0; i < children.size(); i++) { - final VerificationParams childParams = children.get(i); - childParams.mParentVerificationParams = this; - } - mVerificationState = new ArraySet<>(mChildParams.size()); - mObserver = parent.mObserver; - } - - @Override - void handleStartCopy() { - for (VerificationParams params : mChildParams) { - params.handleStartCopy(); - } - } - - @Override - void handleReturnCode() { - for (VerificationParams params : mChildParams) { - params.handleReturnCode(); - } - } - - void trySendVerificationCompleteNotification(VerificationParams child) { - mVerificationState.add(child); - if (mVerificationState.size() != mChildParams.size()) { - return; - } - int completeStatus = PackageManager.INSTALL_SUCCEEDED; - String errorMsg = null; - for (VerificationParams params : mVerificationState) { - int status = params.mRet; - if (status != PackageManager.INSTALL_SUCCEEDED) { - completeStatus = status; - errorMsg = params.mErrorMessage; - break; - } - } - try { - mObserver.onPackageInstalled(null, completeStatus, - errorMsg, new Bundle()); - } catch (RemoteException e) { - Slog.i(TAG, "Observer no longer exists."); - } - } + public int getRet() { + return mRet; + } + public String getErrorMessage() { + return mErrorMessage; + } + public UserHandle getUser() { + return mUser; } }