1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 20 21 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 22 import static com.android.server.pm.PackageManagerService.TAG; 23 24 import android.content.pm.IPackageInstallObserver2; 25 import android.content.pm.PackageManager; 26 import android.os.Bundle; 27 import android.os.RemoteException; 28 import android.os.Trace; 29 import android.os.UserHandle; 30 import android.util.ArraySet; 31 import android.util.Slog; 32 33 import java.util.List; 34 import java.util.Set; 35 36 /** 37 * Container for a multi-package verifying session which refers to all verifying sessions and args 38 * being committed together. 39 */ 40 final class MultiPackageVerifyingSession { 41 private final IPackageInstallObserver2 mObserver; 42 private final List<VerifyingSession> mChildVerifyingSessions; 43 private final Set<VerifyingSession> mVerificationState; 44 private final UserHandle mUser; 45 MultiPackageVerifyingSession(VerifyingSession parent, List<VerifyingSession> children)46 MultiPackageVerifyingSession(VerifyingSession parent, List<VerifyingSession> children) 47 throws PackageManagerException { 48 mUser = parent.getUser(); 49 if (children.size() == 0) { 50 throw PackageManagerException.ofInternalError("No child sessions found!", 51 PackageManagerException.INTERNAL_ERROR_VERIFY_MISSING_CHILD_SESSIONS); 52 } 53 mChildVerifyingSessions = children; 54 // Provide every child with reference to this object as parent 55 for (int i = 0; i < children.size(); i++) { 56 final VerifyingSession childVerifyingSession = children.get(i); 57 childVerifyingSession.mParentVerifyingSession = this; 58 } 59 mVerificationState = new ArraySet<>(mChildVerifyingSessions.size()); 60 mObserver = parent.mObserver; 61 } 62 start()63 public void start() { 64 if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this); 65 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueVerify", 66 System.identityHashCode(this)); 67 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startVerify"); 68 for (VerifyingSession childVerifyingSession : mChildVerifyingSessions) { 69 childVerifyingSession.handleStartVerify(); 70 } 71 for (VerifyingSession childVerifyingSession : mChildVerifyingSessions) { 72 childVerifyingSession.handleReturnCode(); 73 } 74 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 75 } 76 trySendVerificationCompleteNotification(VerifyingSession child)77 public void trySendVerificationCompleteNotification(VerifyingSession child) { 78 mVerificationState.add(child); 79 if (mVerificationState.size() != mChildVerifyingSessions.size()) { 80 return; 81 } 82 int completeStatus = PackageManager.INSTALL_SUCCEEDED; 83 String errorMsg = null; 84 for (VerifyingSession childVerifyingSession : mVerificationState) { 85 int status = childVerifyingSession.getRet(); 86 if (status != PackageManager.INSTALL_SUCCEEDED) { 87 completeStatus = status; 88 errorMsg = childVerifyingSession.getErrorMessage(); 89 break; 90 } 91 } 92 try { 93 mObserver.onPackageInstalled(null, completeStatus, 94 errorMsg, new Bundle()); 95 } catch (RemoteException e) { 96 Slog.i(TAG, "Observer no longer exists."); 97 } 98 } 99 100 @Override toString()101 public String toString() { 102 return "MultiPackageVerifyingSession{" + Integer.toHexString(System.identityHashCode(this)) 103 + "}"; 104 } 105 } 106