[pm] Split VerificationParams and InstallParams

+ Remove unnecessary layer of abstraction
+ Remove unnecessary message code INIT_COPY
+ Rename VerificationParams -> VerifyingSession
+ Rename InstallParams -> InstallingSession

BUG: 215734888
Test: builds
Change-Id: Ie9ea722344f73faffd8602f2e5117527f0b812c8
This commit is contained in:
Songchun Fan
2022-06-10 16:33:18 -07:00
parent 724530ce37
commit 3ececd877f
14 changed files with 366 additions and 337 deletions

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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<InstallRequest> 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<InstallParams> children)
public void installStage(List<InstallingSession> 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<InstallParams> mChildParams;
private final Map<InstallArgs, Integer> mCurrentState;
MultiPackageInstallParams(InstallParams parent, List<InstallParams> 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<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
for (Map.Entry<InstallArgs, Integer> 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;
}
}

View File

@@ -37,7 +37,7 @@ final class MoveInstallArgs extends InstallArgs {
private File mCodeFile;
/** New install */
MoveInstallArgs(InstallParams params) {
MoveInstallArgs(InstallingSession params) {
super(params);
}

View File

@@ -291,10 +291,10 @@ public final class MovePackageHelper {
final ParseResult<PackageLite> 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();
}
/**

View File

@@ -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<InstallingSession> mChildInstallingSessions;
private final Map<InstallArgs, Integer> mCurrentState;
@NonNull
final PackageManagerService mPm;
final UserHandle mUser;
MultiPackageInstallingSession(UserHandle user, List<InstallingSession> 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<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
for (Map.Entry<InstallArgs, Integer> 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))
+ "}";
}
}

View File

@@ -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<VerifyingSession> mChildVerifyingSessions;
private final Set<VerifyingSession> mVerificationState;
private final UserHandle mUser;
MultiPackageVerifyingSession(VerifyingSession parent, List<VerifyingSession> 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))
+ "}";
}
}

View File

@@ -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);

View File

@@ -2386,21 +2386,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
List<CompletableFuture<InstallResult>> futures = new ArrayList<>();
CompletableFuture<InstallResult> future = new CompletableFuture<>();
futures.add(future);
final InstallParams installingSession = makeInstallParams(future);
final InstallingSession installingSession = createInstallingSession(future);
if (isMultiPackage()) {
final List<PackageInstallerSession> childSessions = getChildSessions();
List<InstallParams> installingChildSessions = new ArrayList<>(childSessions.size());
List<InstallingSession> 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<InstallResult> future)
private InstallingSession createInstallingSession(CompletableFuture<InstallResult> 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);
}
}

View File

@@ -752,7 +752,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
* List of packages waiting for rollback to be enabled.
* Handler thread only!
*/
final SparseArray<VerificationParams> mPendingEnableRollback = new SparseArray<>();
final SparseArray<VerifyingSession> 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;

View File

@@ -186,12 +186,12 @@ final class PackageSessionVerifier {
}
}
};
final VerificationParams verifyingSession = makeVerificationParams(session, observer);
final VerifyingSession verifyingSession = createVerifyingSession(session, observer);
if (session.isMultiPackage()) {
final List<PackageInstallerSession> childSessions = session.getChildSessions();
List<VerificationParams> verifyingChildSessions = new ArrayList<>(childSessions.size());
List<VerifyingSession> 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);
}

View File

@@ -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. */

View File

@@ -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<VerificationParams> children)
public void verifyStage(List<VerifyingSession> 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<VerificationParams> mChildParams;
private final Set<VerificationParams> mVerificationState;
MultiPackageVerificationParams(VerificationParams parent, List<VerificationParams> 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;
}
}