1 /* 2 * Copyright (C) 2021 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.CHECK_PENDING_VERIFICATION; 22 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 23 import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD; 24 import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER; 25 import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE; 26 import static com.android.server.pm.PackageManagerService.DEFERRED_PENDING_KILL_INSTALL_OBSERVER; 27 import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION; 28 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS; 29 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT; 30 import static com.android.server.pm.PackageManagerService.INSTANT_APP_RESOLUTION_PHASE_TWO; 31 import static com.android.server.pm.PackageManagerService.PACKAGE_VERIFIED; 32 import static com.android.server.pm.PackageManagerService.POST_INSTALL; 33 import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SHARED_LIBRARIES; 34 import static com.android.server.pm.PackageManagerService.SEND_PENDING_BROADCAST; 35 import static com.android.server.pm.PackageManagerService.TAG; 36 import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_LIST; 37 import static com.android.server.pm.PackageManagerService.WRITE_SETTINGS; 38 39 import android.content.Intent; 40 import android.content.pm.InstantAppRequest; 41 import android.content.pm.PackageManager; 42 import android.content.pm.PackageManagerInternal; 43 import android.net.Uri; 44 import android.os.Handler; 45 import android.os.Looper; 46 import android.os.Message; 47 import android.os.Process; 48 import android.os.Trace; 49 import android.os.UserHandle; 50 import android.provider.Settings; 51 import android.util.Log; 52 import android.util.Slog; 53 54 import java.io.IOException; 55 56 /** 57 * Part of PackageManagerService that handles events. 58 */ 59 final class PackageHandler extends Handler { 60 private final PackageManagerService mPm; 61 PackageHandler(Looper looper, PackageManagerService pm)62 PackageHandler(Looper looper, PackageManagerService pm) { 63 super(looper); 64 mPm = pm; 65 } 66 67 @Override handleMessage(Message msg)68 public void handleMessage(Message msg) { 69 try { 70 doHandleMessage(msg); 71 } finally { 72 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 73 } 74 } 75 doHandleMessage(Message msg)76 void doHandleMessage(Message msg) { 77 switch (msg.what) { 78 case SEND_PENDING_BROADCAST: { 79 mPm.sendPendingBroadcasts((String) msg.obj, msg.arg1); 80 break; 81 } 82 case POST_INSTALL: { 83 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 84 85 final InstallRequest request; 86 final int token; 87 final boolean didRestore; 88 synchronized (mPm.mRunningInstalls) { 89 request= mPm.mRunningInstalls.get(msg.arg1); 90 token = msg.arg1; 91 didRestore = (msg.arg2 != 0); 92 mPm.mRunningInstalls.delete(token); 93 } 94 95 if (request == null) { 96 if (DEBUG_INSTALL) { 97 Slog.i(TAG, "InstallRequest is null. Nothing to do for post-install " 98 + "token " + token); 99 } 100 break; 101 } 102 request.onRestoreFinished(); 103 request.closeFreezer(); 104 request.onInstallCompleted(); 105 request.runPostInstallRunnable(); 106 if (!request.isInstallExistingForUser()) { 107 mPm.handlePackagePostInstall(request, didRestore); 108 } else if (DEBUG_INSTALL) { 109 // No post-install when we run restore from installExistingPackageForUser 110 Slog.i(TAG, "Nothing to do for post-install token " + token); 111 } 112 113 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 114 } break; 115 case DEFERRED_NO_KILL_POST_DELETE: { 116 CleanUpArgs args = (CleanUpArgs) msg.obj; 117 if (args != null) { 118 mPm.cleanUpResources(args.getPackageName(), args.getCodeFile(), 119 args.getInstructionSets()); 120 } 121 } break; 122 case DEFERRED_NO_KILL_INSTALL_OBSERVER: 123 case DEFERRED_PENDING_KILL_INSTALL_OBSERVER: { 124 final String packageName = (String) msg.obj; 125 if (packageName != null) { 126 final boolean killApp = msg.what == DEFERRED_PENDING_KILL_INSTALL_OBSERVER; 127 mPm.notifyInstallObserver(packageName, killApp); 128 } 129 } break; 130 case WRITE_SETTINGS: { 131 mPm.writeSettings(/*sync=*/false); 132 } break; 133 case WRITE_PACKAGE_LIST: { 134 mPm.writePackageList(msg.arg1); 135 } break; 136 case CHECK_PENDING_VERIFICATION: { 137 final int verificationId = msg.arg1; 138 final boolean streaming = msg.arg2 != 0; 139 final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); 140 141 if (state == null || state.isVerificationComplete()) { 142 // Not found or complete. 143 break; 144 } 145 146 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 147 if (!streaming && state.timeoutExtended(response.callerUid)) { 148 // Timeout extended. 149 break; 150 } 151 152 VerificationUtils.processVerificationResponseOnTimeout(verificationId, state, 153 response, mPm); 154 155 break; 156 } 157 case PACKAGE_VERIFIED: { 158 final int verificationId = msg.arg1; 159 160 final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); 161 if (state == null) { 162 Slog.w(TAG, "Verification with id " + verificationId 163 + " not found." 164 + " It may be invalid or overridden by integrity verification"); 165 break; 166 } 167 if (state.isVerificationComplete()) { 168 Slog.w(TAG, "Verification with id " + verificationId + " already complete."); 169 break; 170 } 171 172 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 173 VerificationUtils.processVerificationResponse(verificationId, state, response, mPm); 174 175 break; 176 } 177 case INSTANT_APP_RESOLUTION_PHASE_TWO: { 178 InstantAppResolver.doInstantAppResolutionPhaseTwo(mPm.mContext, 179 mPm.snapshotComputer(), 180 mPm.mUserManager, 181 mPm.mInstantAppResolverConnection, 182 (InstantAppRequest) msg.obj, 183 mPm.mInstantAppInstallerActivity, 184 mPm.mHandler); 185 break; 186 } 187 case ENABLE_ROLLBACK_STATUS: { 188 final int enableRollbackToken = msg.arg1; 189 final int enableRollbackCode = msg.arg2; 190 final VerifyingSession params = 191 mPm.mPendingEnableRollback.get(enableRollbackToken); 192 if (params == null) { 193 Slog.w(TAG, "Invalid rollback enabled token " 194 + enableRollbackToken + " received"); 195 break; 196 } 197 198 mPm.mPendingEnableRollback.remove(enableRollbackToken); 199 200 if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) { 201 final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); 202 Slog.w(TAG, "Failed to enable rollback for " + originUri); 203 Slog.w(TAG, "Continuing with installation of " + originUri); 204 } 205 206 Trace.asyncTraceEnd( 207 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); 208 209 params.handleRollbackEnabled(); 210 break; 211 } 212 case ENABLE_ROLLBACK_TIMEOUT: { 213 final int enableRollbackToken = msg.arg1; 214 final int sessionId = msg.arg2; 215 final VerifyingSession params = 216 mPm.mPendingEnableRollback.get(enableRollbackToken); 217 if (params != null) { 218 final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); 219 220 Slog.w(TAG, "Enable rollback timed out for " + originUri); 221 mPm.mPendingEnableRollback.remove(enableRollbackToken); 222 223 Slog.w(TAG, "Continuing with installation of " + originUri); 224 Trace.asyncTraceEnd( 225 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); 226 params.handleRollbackEnabled(); 227 Intent rollbackTimeoutIntent = new Intent( 228 Intent.ACTION_CANCEL_ENABLE_ROLLBACK); 229 rollbackTimeoutIntent.putExtra( 230 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID, 231 sessionId); 232 rollbackTimeoutIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 233 | Intent.FLAG_RECEIVER_FOREGROUND); 234 mPm.mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM, 235 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT); 236 } 237 break; 238 } 239 case DOMAIN_VERIFICATION: { 240 int messageCode = msg.arg1; 241 Object object = msg.obj; 242 mPm.mDomainVerificationManager.runMessage(messageCode, object); 243 break; 244 } 245 case PRUNE_UNUSED_STATIC_SHARED_LIBRARIES: { 246 try { 247 mPm.mInjector.getSharedLibrariesImpl().pruneUnusedStaticSharedLibraries( 248 mPm.snapshotComputer(), 249 Long.MAX_VALUE, 250 Settings.Global.getLong(mPm.mContext.getContentResolver(), 251 Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD, 252 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD)); 253 } catch (IOException e) { 254 Log.w(TAG, "Failed to prune unused static shared libraries :" 255 + e.getMessage()); 256 } 257 break; 258 } 259 } 260 } 261 262 /** 263 * Get the default integrity verification response code. 264 */ getDefaultIntegrityVerificationResponse()265 private int getDefaultIntegrityVerificationResponse() { 266 // We are not exposing this as a user-configurable setting because we don't want to provide 267 // an easy way to get around the integrity check. 268 return PackageManager.VERIFICATION_REJECT; 269 } 270 } 271