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.PowerExemptionManager.REASON_LOCKED_BOOT_COMPLETED; 20 import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED; 21 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 22 import static android.os.Process.SYSTEM_UID; 23 import static android.safetylabel.SafetyLabelConstants.SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED; 24 25 import static com.android.server.pm.PackageManagerService.DEBUG_BACKUP; 26 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 27 import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; 28 import static com.android.server.pm.PackageManagerService.PACKAGE_SCHEME; 29 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; 30 import static com.android.server.pm.PackageManagerService.TAG; 31 32 import android.Manifest; 33 import android.annotation.AppIdInt; 34 import android.annotation.NonNull; 35 import android.annotation.Nullable; 36 import android.annotation.SuppressLint; 37 import android.app.ActivityManager; 38 import android.app.ActivityManagerInternal; 39 import android.app.BroadcastOptions; 40 import android.app.IActivityManager; 41 import android.content.ComponentName; 42 import android.content.Context; 43 import android.content.IIntentReceiver; 44 import android.content.Intent; 45 import android.content.pm.PackageInstaller; 46 import android.content.pm.PackageManager; 47 import android.content.pm.UserInfo; 48 import android.content.pm.UserProperties; 49 import android.multiuser.Flags; 50 import android.net.Uri; 51 import android.os.Bundle; 52 import android.os.Handler; 53 import android.os.PowerExemptionManager; 54 import android.os.Process; 55 import android.os.RemoteException; 56 import android.os.UserHandle; 57 import android.os.storage.StorageManager; 58 import android.os.storage.VolumeInfo; 59 import android.provider.DeviceConfig; 60 import android.stats.storage.StorageEnums; 61 import android.util.IntArray; 62 import android.util.Log; 63 import android.util.Pair; 64 import android.util.Slog; 65 import android.util.SparseArray; 66 67 import com.android.internal.util.ArrayUtils; 68 import com.android.internal.util.FrameworkStatsLog; 69 import com.android.server.pm.pkg.AndroidPackage; 70 import com.android.server.pm.pkg.PackageStateInternal; 71 import com.android.server.pm.pkg.PackageUserStateInternal; 72 73 import java.util.ArrayList; 74 import java.util.Arrays; 75 import java.util.Collections; 76 import java.util.function.BiFunction; 77 78 /** 79 * Helper class to send broadcasts for various situations. 80 */ 81 public final class BroadcastHelper { 82 private static final boolean DEBUG_BROADCASTS = false; 83 /** 84 * Permissions required in order to receive instant application lifecycle broadcasts. 85 */ 86 private static final String[] INSTANT_APP_BROADCAST_PERMISSION = 87 new String[]{android.Manifest.permission.ACCESS_INSTANT_APPS}; 88 89 private final UserManagerInternal mUmInternal; 90 private final ActivityManagerInternal mAmInternal; 91 private final Context mContext; 92 private final Handler mHandler; 93 private final PackageMonitorCallbackHelper mPackageMonitorCallbackHelper; 94 private final AppsFilterSnapshot mAppsFilter; 95 BroadcastHelper(PackageManagerServiceInjector injector)96 BroadcastHelper(PackageManagerServiceInjector injector) { 97 mUmInternal = injector.getUserManagerInternal(); 98 mAmInternal = injector.getActivityManagerInternal(); 99 mContext = injector.getContext(); 100 mHandler = injector.getHandler(); 101 mPackageMonitorCallbackHelper = injector.getPackageMonitorCallbackHelper(); 102 mAppsFilter = injector.getAppsFilter(); 103 } 104 105 /** 106 * Sends a broadcast to registered clients on userId for the given Intent. 107 */ sendPackageBroadcastWithIntent(Intent intent, int userId, boolean isInstantApp, @Intent.Flags int flags, int[] visibilityAllowList, final IIntentReceiver finishedReceiver, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, @Nullable Bundle bOptions)108 void sendPackageBroadcastWithIntent(Intent intent, int userId, boolean isInstantApp, 109 @Intent.Flags int flags, 110 int[] visibilityAllowList, 111 final IIntentReceiver finishedReceiver, 112 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, 113 @Nullable Bundle bOptions) { 114 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 115 SparseArray<int[]> broadcastAllowList = new SparseArray<>(); 116 broadcastAllowList.put(userId, visibilityAllowList); 117 broadcastIntent(intent, finishedReceiver, isInstantApp, userId, broadcastAllowList, 118 filterExtrasForReceiver, bOptions); 119 } 120 sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, @Nullable Bundle bOptions)121 void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 122 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 123 final int[] userIds, int[] instantUserIds, 124 @Nullable SparseArray<int[]> broadcastAllowList, 125 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, 126 @Nullable Bundle bOptions) { 127 try { 128 final IActivityManager am = ActivityManager.getService(); 129 if (am == null) return; 130 final int[] resolvedUserIds; 131 if (userIds == null) { 132 resolvedUserIds = am.getRunningUserIds(); 133 } else { 134 resolvedUserIds = userIds; 135 } 136 137 if (ArrayUtils.isEmpty(instantUserIds)) { 138 doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver, 139 resolvedUserIds, false /* isInstantApp */, broadcastAllowList, 140 filterExtrasForReceiver, bOptions); 141 } else { 142 // send restricted broadcasts for instant apps 143 doSendBroadcast(action, pkg, extras, flags, targetPkg, finishedReceiver, 144 instantUserIds, true /* isInstantApp */, null, 145 null /* filterExtrasForReceiver */, bOptions); 146 } 147 } catch (RemoteException ex) { 148 } 149 } 150 151 /** 152 * Sends a broadcast for the given action. 153 * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with 154 * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows 155 * the system and applications allowed to see instant applications to receive package 156 * lifecycle events for instant applications. 157 */ doSendBroadcast( @onNull String action, @Nullable String pkg, @Nullable Bundle extras, int flags, @Nullable String targetPkg, @Nullable IIntentReceiver finishedReceiver, @NonNull int[] userIds, boolean isInstantApp, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, @Nullable Bundle bOptions)158 private void doSendBroadcast( 159 @NonNull String action, 160 @Nullable String pkg, 161 @Nullable Bundle extras, 162 int flags, 163 @Nullable String targetPkg, 164 @Nullable IIntentReceiver finishedReceiver, 165 @NonNull int[] userIds, 166 boolean isInstantApp, 167 @Nullable SparseArray<int[]> broadcastAllowList, 168 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, 169 @Nullable Bundle bOptions) { 170 for (int userId : userIds) { 171 final Intent intent = new Intent(action, 172 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 173 if (extras != null) { 174 intent.putExtras(extras); 175 } 176 if (targetPkg != null) { 177 intent.setPackage(targetPkg); 178 } 179 // Modify the UID when posting to other users 180 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 181 if (uid >= 0 && UserHandle.getUserId(uid) != userId) { 182 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 183 intent.putExtra(Intent.EXTRA_UID, uid); 184 } 185 if (broadcastAllowList != null && PLATFORM_PACKAGE_NAME.equals(targetPkg)) { 186 intent.putExtra(Intent.EXTRA_VISIBILITY_ALLOW_LIST, 187 broadcastAllowList.get(userId)); 188 } 189 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 190 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 191 broadcastIntent(intent, finishedReceiver, isInstantApp, userId, broadcastAllowList, 192 filterExtrasForReceiver, bOptions); 193 } 194 } 195 196 broadcastIntent(Intent intent, IIntentReceiver finishedReceiver, boolean isInstantApp, int userId, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, @Nullable Bundle bOptions)197 private void broadcastIntent(Intent intent, IIntentReceiver finishedReceiver, 198 boolean isInstantApp, int userId, @Nullable SparseArray<int[]> broadcastAllowList, 199 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, 200 @Nullable Bundle bOptions) { 201 final String[] requiredPermissions = 202 isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null; 203 if (DEBUG_BROADCASTS) { 204 RuntimeException here = new RuntimeException("here"); 205 here.fillInStackTrace(); 206 Slog.d(TAG, "Sending to user " + userId + ": " 207 + intent.toShortString(false, true, false, false) 208 + " " + intent.getExtras(), here); 209 } 210 mAmInternal.broadcastIntentWithCallback( 211 intent, finishedReceiver, requiredPermissions, userId, 212 broadcastAllowList == null ? null : broadcastAllowList.get(userId), 213 filterExtrasForReceiver, bOptions); 214 } 215 sendResourcesChangedBroadcast(@onNull Computer snapshot, boolean mediaStatus, boolean replacing, @NonNull String[] pkgNames, @NonNull int[] uids)216 void sendResourcesChangedBroadcast(@NonNull Computer snapshot, 217 boolean mediaStatus, 218 boolean replacing, 219 @NonNull String[] pkgNames, 220 @NonNull int[] uids) { 221 if (ArrayUtils.isEmpty(pkgNames) || ArrayUtils.isEmpty(uids)) { 222 return; 223 } 224 Bundle extras = new Bundle(); 225 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgNames); 226 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uids); 227 if (replacing) { 228 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 229 } 230 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 231 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 232 sendPackageBroadcast(action, null /* pkg */, extras, 0 /* flags */, 233 null /* targetPkg */, null /* finishedReceiver */, null /* userIds */, 234 null /* instantUserIds */, null /* broadcastAllowList */, 235 (callingUid, intentExtras) -> filterExtrasChangedPackageList( 236 snapshot, callingUid, intentExtras), 237 null /* bOptions */); 238 } 239 240 /** 241 * The just-installed/enabled app is bundled on the system, so presumed to be able to run 242 * automatically without needing an explicit launch. 243 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones. 244 */ sendBootCompletedBroadcastToSystemApp(@onNull String packageName, boolean includeStopped, int userId)245 private void sendBootCompletedBroadcastToSystemApp(@NonNull String packageName, 246 boolean includeStopped, 247 int userId) { 248 // If user is not running, the app didn't miss any broadcast 249 if (!mUmInternal.isUserRunning(userId)) { 250 return; 251 } 252 final IActivityManager am = ActivityManager.getService(); 253 try { 254 // Deliver LOCKED_BOOT_COMPLETED first 255 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED) 256 .setPackage(packageName); 257 lockedBcIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 258 if (includeStopped) { 259 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 260 } 261 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; 262 final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions( 263 REASON_LOCKED_BOOT_COMPLETED); 264 am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null, 265 requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, 266 bOptions.toBundle(), false, false, userId); 267 268 // Deliver BOOT_COMPLETED only if user is unlocked 269 if (mUmInternal.isUserUnlockingOrUnlocked(userId)) { 270 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName); 271 bcIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 272 if (includeStopped) { 273 bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 274 } 275 am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null, 276 requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, 277 bOptions.toBundle(), false, false, userId); 278 } 279 } catch (RemoteException e) { 280 throw e.rethrowFromSystemServer(); 281 } 282 } 283 getTemporaryAppAllowlistBroadcastOptions( @owerExemptionManager.ReasonCode int reasonCode)284 private @NonNull BroadcastOptions getTemporaryAppAllowlistBroadcastOptions( 285 @PowerExemptionManager.ReasonCode int reasonCode) { 286 long duration = 10_000; 287 if (mAmInternal != null) { 288 duration = mAmInternal.getBootTimeTempAllowListDuration(); 289 } 290 final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); 291 bOptions.setTemporaryAppAllowlist(duration, 292 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 293 reasonCode, ""); 294 return bOptions; 295 } 296 sendPackageChangedBroadcast(@onNull String packageName, boolean dontKillApp, @NonNull ArrayList<String> componentNames, int packageUid, @Nullable String reason, @Nullable int[] userIds, @Nullable int[] instantUserIds, @Nullable SparseArray<int[]> broadcastAllowList)297 private void sendPackageChangedBroadcast(@NonNull String packageName, 298 boolean dontKillApp, 299 @NonNull ArrayList<String> componentNames, 300 int packageUid, 301 @Nullable String reason, 302 @Nullable int[] userIds, 303 @Nullable int[] instantUserIds, 304 @Nullable SparseArray<int[]> broadcastAllowList) { 305 if (DEBUG_INSTALL) { 306 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 307 + componentNames); 308 } 309 Bundle extras = new Bundle(4); 310 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 311 String[] nameList = new String[componentNames.size()]; 312 componentNames.toArray(nameList); 313 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 314 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp); 315 extras.putInt(Intent.EXTRA_UID, packageUid); 316 if (reason != null) { 317 extras.putString(Intent.EXTRA_REASON, reason); 318 } 319 // If this is not reporting a change of the overall package, then only send it 320 // to registered receivers. We don't want to launch a swath of apps for every 321 // little component state change. 322 final int flags = !componentNames.contains(packageName) 323 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 324 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 325 userIds, instantUserIds, broadcastAllowList, null /* filterExtrasForReceiver */, 326 null /* bOptions */); 327 } 328 sendDeviceCustomizationReadyBroadcast()329 static void sendDeviceCustomizationReadyBroadcast() { 330 final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY); 331 intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 332 final IActivityManager am = ActivityManager.getService(); 333 final String[] requiredPermissions = { 334 Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY, 335 }; 336 try { 337 am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null, 338 requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, null, false, 339 false, UserHandle.USER_ALL); 340 } catch (RemoteException e) { 341 throw e.rethrowFromSystemServer(); 342 } 343 } 344 sendSessionCommitBroadcast(@onNull Computer snapshot, @NonNull PackageInstaller.SessionInfo sessionInfo, int userId, @Nullable String appPredictionServicePackage)345 void sendSessionCommitBroadcast(@NonNull Computer snapshot, 346 @NonNull PackageInstaller.SessionInfo sessionInfo, 347 int userId, 348 @Nullable String appPredictionServicePackage) { 349 UserManagerService ums = UserManagerService.getInstance(); 350 if (ums == null || sessionInfo.isStaged()) { 351 return; 352 } 353 final UserInfo parent = ums.getProfileParent(userId); 354 final int launcherUserId = (parent != null) ? parent.id : userId; 355 final ComponentName launcherComponent = snapshot.getDefaultHomeActivity(launcherUserId); 356 if (launcherComponent != null && canLauncherAccessProfile(launcherComponent, userId)) { 357 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED) 358 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo) 359 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId)) 360 .setPackage(launcherComponent.getPackageName()); 361 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUserId)); 362 } 363 if (appPredictionServicePackage != null) { 364 Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED) 365 .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo) 366 .putExtra(Intent.EXTRA_USER, UserHandle.of(userId)) 367 .setPackage(appPredictionServicePackage); 368 mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUserId)); 369 } 370 } 371 372 /** 373 * A Profile is accessible to launcher in question if: 374 * - It's not hidden for API visibility. 375 * - Hidden, but launcher application has either 376 * {@link Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL} or 377 * {@link Manifest.permission.ACCESS_HIDDEN_PROFILES} 378 * granted. 379 */ canLauncherAccessProfile(ComponentName launcherComponent, int userId)380 boolean canLauncherAccessProfile(ComponentName launcherComponent, int userId) { 381 if (android.os.Flags.allowPrivateProfile() 382 && Flags.enablePermissionToAccessHiddenProfiles() 383 && Flags.enablePrivateSpaceFeatures()) { 384 if (mUmInternal.getUserProperties(userId).getProfileApiVisibility() 385 != UserProperties.PROFILE_API_VISIBILITY_HIDDEN) { 386 return true; 387 } 388 if (mContext.getPackageManager().checkPermission( 389 Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL, 390 launcherComponent.getPackageName()) 391 == PackageManager.PERMISSION_GRANTED) { 392 return true; 393 } 394 // TODO(b/122900055) Change/Remove this and replace with new permission role. 395 return mContext.getPackageManager().checkPermission( 396 Manifest.permission.ACCESS_HIDDEN_PROFILES, 397 launcherComponent.getPackageName()) 398 == PackageManager.PERMISSION_GRANTED; 399 } 400 return true; 401 } 402 sendPreferredActivityChangedBroadcast(int userId)403 void sendPreferredActivityChangedBroadcast(int userId) { 404 mHandler.post(() -> { 405 final IActivityManager am = ActivityManager.getService(); 406 if (am == null) { 407 return; 408 } 409 410 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 411 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 412 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 413 try { 414 am.broadcastIntentWithFeature(null, null, intent, null, null, 415 0, null, null, null, null, null, android.app.AppOpsManager.OP_NONE, 416 null, false, false, userId); 417 } catch (RemoteException e) { 418 } 419 }); 420 } 421 sendPostInstallBroadcasts(@onNull Computer snapshot, @NonNull InstallRequest request, @NonNull String packageName, @NonNull String requiredPermissionControllerPackage, @NonNull String[] requiredVerifierPackages, @NonNull String requiredInstallerPackage, @NonNull PackageSender packageSender, boolean isLaunchedForRestore, boolean isKillApp, boolean isUpdate, boolean isArchived)422 void sendPostInstallBroadcasts(@NonNull Computer snapshot, 423 @NonNull InstallRequest request, 424 @NonNull String packageName, 425 @NonNull String requiredPermissionControllerPackage, 426 @NonNull String[] requiredVerifierPackages, 427 @NonNull String requiredInstallerPackage, 428 @NonNull PackageSender packageSender, 429 boolean isLaunchedForRestore, 430 boolean isKillApp, 431 boolean isUpdate, 432 boolean isArchived) { 433 // Send the removed broadcasts 434 if (request.getRemovedInfo() != null) { 435 if (request.getRemovedInfo().mIsExternal) { 436 if (DEBUG_INSTALL) { 437 Slog.i(TAG, "upgrading pkg " + request.getRemovedInfo().mRemovedPackage 438 + " is ASEC-hosted -> UNAVAILABLE"); 439 } 440 final String[] pkgNames = new String[]{ 441 request.getRemovedInfo().mRemovedPackage}; 442 final int[] uids = new int[]{request.getRemovedInfo().mUid}; 443 notifyResourcesChanged( 444 false /* mediaStatus */, true /* replacing */, pkgNames, uids); 445 sendResourcesChangedBroadcast( 446 snapshot, false /* mediaStatus */, true /* replacing */, pkgNames, uids); 447 } 448 sendPackageRemovedBroadcasts( 449 request.getRemovedInfo(), packageSender, isKillApp, false /*removedBySystem*/, 450 false /*isArchived*/); 451 } 452 453 final int[] firstUserIds = request.getFirstTimeBroadcastUserIds(); 454 final int[] firstInstantUserIds = request.getFirstTimeBroadcastInstantUserIds(); 455 final int[] updateUserIds = request.getUpdateBroadcastUserIds(); 456 final int[] instantUserIds = request.getUpdateBroadcastInstantUserIds(); 457 458 final String installerPackageName = 459 request.getInstallerPackageName() != null 460 ? request.getInstallerPackageName() 461 : request.getRemovedInfo() != null 462 ? request.getRemovedInfo().mInstallerPackageName 463 : null; 464 465 Bundle extras = new Bundle(); 466 extras.putInt(Intent.EXTRA_UID, request.getAppId()); 467 if (isUpdate) { 468 extras.putBoolean(Intent.EXTRA_REPLACING, true); 469 } 470 if (isArchived) { 471 extras.putBoolean(Intent.EXTRA_ARCHIVAL, true); 472 } 473 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, request.getDataLoaderType()); 474 475 final String staticSharedLibraryName = request.getPkg().getStaticSharedLibraryName(); 476 // If a package is a static shared library, then only the installer of the package 477 // should get the broadcast. 478 if (installerPackageName != null && staticSharedLibraryName != null) { 479 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, packageName, 480 extras, 0 /*flags*/, 481 installerPackageName, null /*finishedReceiver*/, 482 request.getNewUsers(), null /* instantUserIds*/, 483 null /* broadcastAllowList */, null); 484 } 485 486 // Send installed broadcasts if the package is not a static shared lib. 487 if (staticSharedLibraryName == null) { 488 // Send PACKAGE_ADDED broadcast for users that see the package for the first time 489 // sendPackageAddedForNewUsers also deals with system apps 490 final int appId = UserHandle.getAppId(request.getAppId()); 491 final boolean isSystem = request.isInstallSystem(); 492 final boolean isVirtualPreload = 493 ((request.getInstallFlags() & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); 494 sendPackageAddedForNewUsers(snapshot, packageName, 495 isSystem || isVirtualPreload, 496 isVirtualPreload /*startReceiver*/, appId, 497 firstUserIds, firstInstantUserIds, isArchived, request.getDataLoaderType()); 498 499 // Send PACKAGE_ADDED broadcast for users that don't see 500 // the package for the first time 501 502 // Send to all running apps. 503 final SparseArray<int[]> newBroadcastAllowList = 504 mAppsFilter.getVisibilityAllowList(snapshot, 505 snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID), 506 updateUserIds, snapshot.getPackageStates()); 507 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, packageName, 508 extras, 0 /*flags*/, 509 null /*targetPackage*/, null /*finishedReceiver*/, 510 updateUserIds, instantUserIds, newBroadcastAllowList, null); 511 // Send to the installer, even if it's not running. 512 if (installerPackageName != null) { 513 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, packageName, 514 extras, 0 /*flags*/, 515 installerPackageName, null /*finishedReceiver*/, 516 updateUserIds, instantUserIds, null /* broadcastAllowList */, null); 517 } 518 // Send to PermissionController for all update users, even if it may not be running 519 // for some users 520 if (isPrivacySafetyLabelChangeNotificationsEnabled(mContext)) { 521 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, packageName, 522 extras, 0 /*flags*/, 523 requiredPermissionControllerPackage, null /*finishedReceiver*/, 524 updateUserIds, instantUserIds, null /* broadcastAllowList */, null); 525 } 526 // Notify required verifier(s) that are not the installer of record for the package. 527 for (String verifierPackageName : requiredVerifierPackages) { 528 if (verifierPackageName != null && !verifierPackageName.equals( 529 installerPackageName)) { 530 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, 531 packageName, 532 extras, 0 /*flags*/, 533 verifierPackageName, null /*finishedReceiver*/, 534 updateUserIds, instantUserIds, null /* broadcastAllowList */, 535 null); 536 } 537 } 538 // If package installer is defined, notify package installer about new 539 // app installed 540 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, packageName, 541 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/, 542 requiredInstallerPackage, null /*finishedReceiver*/, 543 firstUserIds, instantUserIds, null /* broadcastAllowList */, null); 544 545 // Send replaced for users that don't see the package for the first time 546 if (isUpdate) { 547 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REPLACED, 548 packageName, extras, 0 /*flags*/, 549 null /*targetPackage*/, null /*finishedReceiver*/, 550 updateUserIds, instantUserIds, 551 request.getRemovedInfo().mBroadcastAllowList, null); 552 if (installerPackageName != null) { 553 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REPLACED, packageName, 554 extras, 0 /*flags*/, 555 installerPackageName, null /*finishedReceiver*/, 556 updateUserIds, instantUserIds, null /*broadcastAllowList*/, 557 null); 558 } 559 for (String verifierPackageName : requiredVerifierPackages) { 560 if (verifierPackageName != null && !verifierPackageName.equals( 561 installerPackageName)) { 562 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REPLACED, 563 packageName, extras, 0 /*flags*/, verifierPackageName, 564 null /*finishedReceiver*/, updateUserIds, instantUserIds, 565 null /*broadcastAllowList*/, null); 566 } 567 } 568 sendPackageBroadcastAndNotify(Intent.ACTION_MY_PACKAGE_REPLACED, 569 null /*package*/, null /*extras*/, 0 /*flags*/, 570 packageName /*targetPackage*/, 571 null /*finishedReceiver*/, updateUserIds, instantUserIds, 572 null /*broadcastAllowList*/, 573 getTemporaryAppAllowlistBroadcastOptions( 574 REASON_PACKAGE_REPLACED).toBundle()); 575 } else if (isLaunchedForRestore && !request.isInstallSystem()) { 576 // First-install and we did a restore, so we're responsible for the 577 // first-launch broadcast. 578 if (DEBUG_BACKUP) { 579 Slog.i(TAG, "Post-restore of " + packageName 580 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds)); 581 } 582 sendFirstLaunchBroadcast(packageName, installerPackageName, 583 firstUserIds, firstInstantUserIds); 584 } 585 586 // Send broadcast package appeared if external for all users 587 if (request.getPkg().isExternalStorage()) { 588 if (!isUpdate) { 589 final StorageManager storage = mContext.getSystemService(StorageManager.class); 590 VolumeInfo volume = 591 storage.findVolumeByUuid( 592 StorageManager.convert( 593 request.getPkg().getVolumeUuid()).toString()); 594 int packageExternalStorageType = 595 PackageManagerServiceUtils.getPackageExternalStorageType(volume, 596 /* isExternalStorage */ true); 597 // If the package was installed externally, log it. 598 if (packageExternalStorageType != StorageEnums.UNKNOWN) { 599 FrameworkStatsLog.write( 600 FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED, 601 packageExternalStorageType, packageName); 602 } 603 } 604 if (DEBUG_INSTALL) { 605 Slog.i(TAG, "upgrading pkg " + packageName + " is external"); 606 } 607 if (!isArchived) { 608 final String[] pkgNames = new String[]{packageName}; 609 final int[] uids = new int[]{request.getPkg().getUid()}; 610 sendResourcesChangedBroadcast(snapshot, 611 true /* mediaStatus */, true /* replacing */, pkgNames, uids); 612 notifyResourcesChanged(true /* mediaStatus */, 613 true /* replacing */, pkgNames, uids); 614 } 615 } 616 } else { // if static shared lib 617 final ArrayList<AndroidPackage> libraryConsumers = request.getLibraryConsumers(); 618 if (!ArrayUtils.isEmpty(libraryConsumers)) { 619 // No need to kill consumers if it's installation of new version static shared lib. 620 final boolean dontKillApp = !isUpdate; 621 for (int i = 0; i < libraryConsumers.size(); i++) { 622 AndroidPackage pkg = libraryConsumers.get(i); 623 // send broadcast that all consumers of the static shared library have changed 624 sendPackageChangedBroadcast(snapshot, pkg.getPackageName(), 625 dontKillApp, 626 new ArrayList<>(Collections.singletonList(pkg.getPackageName())), 627 pkg.getUid(), null); 628 } 629 } 630 } 631 } 632 sendPackageAddedForNewUsers(@onNull Computer snapshot, @NonNull String packageName, boolean sendBootCompleted, boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds, boolean isArchived, int dataLoaderType)633 private void sendPackageAddedForNewUsers(@NonNull Computer snapshot, 634 @NonNull String packageName, 635 boolean sendBootCompleted, 636 boolean includeStopped, 637 @AppIdInt int appId, 638 int[] userIds, 639 int[] instantUserIds, 640 boolean isArchived, 641 int dataLoaderType) { 642 if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) { 643 return; 644 } 645 SparseArray<int[]> broadcastAllowList = mAppsFilter.getVisibilityAllowList(snapshot, 646 snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID), 647 userIds, snapshot.getPackageStates()); 648 mHandler.post( 649 () -> sendPackageAddedForNewUsers(packageName, appId, userIds, 650 instantUserIds, isArchived, dataLoaderType, broadcastAllowList)); 651 mPackageMonitorCallbackHelper.notifyPackageAddedForNewUsers(packageName, appId, userIds, 652 instantUserIds, isArchived, dataLoaderType, broadcastAllowList, mHandler); 653 if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) { 654 mHandler.post(() -> { 655 for (int userId : userIds) { 656 sendBootCompletedBroadcastToSystemApp( 657 packageName, includeStopped, userId); 658 } 659 } 660 ); 661 } 662 } 663 sendPackageAddedForNewUsers(@onNull String packageName, @AppIdInt int appId, int[] userIds, int[] instantUserIds, boolean isArchived, int dataLoaderType, @NonNull SparseArray<int[]> broadcastAllowlist)664 private void sendPackageAddedForNewUsers(@NonNull String packageName, 665 @AppIdInt int appId, 666 int[] userIds, 667 int[] instantUserIds, 668 boolean isArchived, 669 int dataLoaderType, 670 @NonNull SparseArray<int[]> broadcastAllowlist) { 671 Bundle extras = new Bundle(1); 672 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast 673 final int uid = UserHandle.getUid( 674 (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId); 675 extras.putInt(Intent.EXTRA_UID, uid); 676 if (isArchived) { 677 extras.putBoolean(Intent.EXTRA_ARCHIVAL, true); 678 } 679 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType); 680 681 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 682 packageName, extras, 0, null, null, userIds, instantUserIds, 683 broadcastAllowlist, null /* filterExtrasForReceiver */, null); 684 // Send to PermissionController for all new users, even if it may not be running for some 685 // users 686 if (isPrivacySafetyLabelChangeNotificationsEnabled(mContext)) { 687 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 688 packageName, extras, 0, 689 mContext.getPackageManager().getPermissionControllerPackageName(), 690 null, userIds, instantUserIds, 691 broadcastAllowlist, null /* filterExtrasForReceiver */, null); 692 } 693 } 694 sendPackageAddedForUser(@onNull Computer snapshot, @NonNull String packageName, @NonNull PackageStateInternal packageState, int userId, boolean isArchived, int dataLoaderType, @Nullable String appPredictionServicePackage)695 void sendPackageAddedForUser(@NonNull Computer snapshot, 696 @NonNull String packageName, 697 @NonNull PackageStateInternal packageState, 698 int userId, 699 boolean isArchived, 700 int dataLoaderType, 701 @Nullable String appPredictionServicePackage) { 702 final PackageUserStateInternal userState = packageState.getUserStateOrDefault(userId); 703 final boolean isSystem = packageState.isSystem(); 704 final boolean isInstantApp = userState.isInstantApp(); 705 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId }; 706 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY; 707 sendPackageAddedForNewUsers(snapshot, packageName, isSystem /*sendBootCompleted*/, 708 false /*startReceiver*/, packageState.getAppId(), userIds, instantUserIds, 709 isArchived, dataLoaderType); 710 711 // Send a session commit broadcast 712 final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo(); 713 info.installReason = userState.getInstallReason(); 714 info.appPackageName = packageName; 715 sendSessionCommitBroadcast(snapshot, info, userId, appPredictionServicePackage); 716 } 717 sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds, int[] instantUserIds)718 void sendFirstLaunchBroadcast(String pkgName, String installerPkg, 719 int[] userIds, int[] instantUserIds) { 720 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 721 installerPkg, null, userIds, instantUserIds, null /* broadcastAllowList */, 722 null /* filterExtrasForReceiver */, null); 723 } 724 725 /** 726 * Filter package names for the intent extras {@link Intent#EXTRA_CHANGED_PACKAGE_LIST} and 727 * {@link Intent#EXTRA_CHANGED_UID_LIST} by using the rules of the package visibility. 728 * 729 * @param callingUid The uid that is going to access the intent extras. 730 * @param extras The intent extras to filter 731 * @return An extras that have been filtered, or {@code null} if the given uid is unable to 732 * access all the packages in the extras. 733 */ 734 @Nullable filterExtrasChangedPackageList(@onNull Computer snapshot, int callingUid, @NonNull Bundle extras)735 private static Bundle filterExtrasChangedPackageList(@NonNull Computer snapshot, int callingUid, 736 @NonNull Bundle extras) { 737 if (UserHandle.isCore(callingUid)) { 738 // see all 739 return extras; 740 } 741 final String[] pkgs = extras.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST); 742 if (ArrayUtils.isEmpty(pkgs)) { 743 return extras; 744 } 745 final int userId = extras.getInt( 746 Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(callingUid)); 747 final int[] uids = extras.getIntArray(Intent.EXTRA_CHANGED_UID_LIST); 748 final Pair<String[], int[]> filteredPkgs = 749 filterPackages(snapshot, pkgs, uids, callingUid, userId); 750 if (ArrayUtils.isEmpty(filteredPkgs.first)) { 751 // caller is unable to access this intent 752 return null; 753 } 754 final Bundle filteredExtras = new Bundle(extras); 755 filteredExtras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, filteredPkgs.first); 756 filteredExtras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, filteredPkgs.second); 757 return filteredExtras; 758 } 759 760 /** Returns whether the Safety Label Change notification, a privacy feature, is enabled. */ isPrivacySafetyLabelChangeNotificationsEnabled(Context context)761 private static boolean isPrivacySafetyLabelChangeNotificationsEnabled(Context context) { 762 PackageManager packageManager = context.getPackageManager(); 763 return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, 764 SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED, true) 765 && !packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) 766 && !packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) 767 && !packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH); 768 } 769 770 @NonNull filterPackages(@onNull Computer snapshot, @NonNull String[] pkgs, @Nullable int[] uids, int callingUid, int userId)771 private static Pair<String[], int[]> filterPackages(@NonNull Computer snapshot, 772 @NonNull String[] pkgs, @Nullable int[] uids, int callingUid, int userId) { 773 final int pkgSize = pkgs.length; 774 final int uidSize = !ArrayUtils.isEmpty(uids) ? uids.length : 0; 775 776 final ArrayList<String> pkgList = new ArrayList<>(pkgSize); 777 final IntArray uidList = uidSize > 0 ? new IntArray(uidSize) : null; 778 for (int i = 0; i < pkgSize; i++) { 779 final String packageName = pkgs[i]; 780 if (snapshot.shouldFilterApplication( 781 snapshot.getPackageStateInternal(packageName), callingUid, userId)) { 782 continue; 783 } 784 pkgList.add(packageName); 785 if (uidList != null && i < uidSize) { 786 uidList.add(uids[i]); 787 } 788 } 789 return new Pair<>( 790 pkgList.size() > 0 ? pkgList.toArray(new String[pkgList.size()]) : null, 791 uidList != null && uidList.size() > 0 ? uidList.toArray() : null); 792 } 793 sendApplicationHiddenForUser(@onNull String packageName, @NonNull PackageStateInternal packageState, int userId, @NonNull PackageSender packageSender)794 void sendApplicationHiddenForUser(@NonNull String packageName, 795 @NonNull PackageStateInternal packageState, 796 int userId, 797 @NonNull PackageSender packageSender) { 798 final PackageRemovedInfo info = new PackageRemovedInfo(); 799 info.mRemovedPackage = packageName; 800 info.mInstallerPackageName = packageState.getInstallSource().mInstallerPackageName; 801 info.mRemovedUsers = new int[] {userId}; 802 info.mBroadcastUsers = new int[] {userId}; 803 info.mUid = UserHandle.getUid(userId, packageState.getAppId()); 804 info.mRemovedPackageVersionCode = packageState.getVersionCode(); 805 sendPackageRemovedBroadcasts(info, packageSender, true /*killApp*/, 806 false /*removedBySystem*/, false /*isArchived*/); 807 } 808 sendPackageChangedBroadcast(@onNull Computer snapshot, @NonNull String packageName, boolean dontKillApp, @NonNull ArrayList<String> componentNames, int packageUid, @NonNull String reason)809 void sendPackageChangedBroadcast(@NonNull Computer snapshot, 810 @NonNull String packageName, 811 boolean dontKillApp, 812 @NonNull ArrayList<String> componentNames, 813 int packageUid, 814 @NonNull String reason) { 815 PackageStateInternal setting = snapshot.getPackageStateInternal(packageName, 816 Process.SYSTEM_UID); 817 if (setting == null) { 818 return; 819 } 820 final int userId = UserHandle.getUserId(packageUid); 821 final boolean isInstantApp = 822 snapshot.isInstantAppInternal(packageName, userId, Process.SYSTEM_UID); 823 final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId }; 824 final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY; 825 final SparseArray<int[]> broadcastAllowList = 826 isInstantApp ? null : snapshot.getVisibilityAllowLists(packageName, userIds); 827 mHandler.post(() -> sendPackageChangedBroadcast( 828 packageName, dontKillApp, componentNames, packageUid, reason, userIds, 829 instantUserIds, broadcastAllowList)); 830 mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames, 831 packageUid, reason, userIds, instantUserIds, broadcastAllowList, mHandler); 832 } 833 sendPackageBroadcastAndNotify(@onNull String action, @NonNull String pkg, @NonNull Bundle extras, int flags, @Nullable String targetPkg, @Nullable IIntentReceiver finishedReceiver, @NonNull int[] userIds, @NonNull int[] instantUserIds, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable Bundle bOptions)834 private void sendPackageBroadcastAndNotify(@NonNull String action, 835 @NonNull String pkg, 836 @NonNull Bundle extras, 837 int flags, 838 @Nullable String targetPkg, 839 @Nullable IIntentReceiver finishedReceiver, 840 @NonNull int[] userIds, 841 @NonNull int[] instantUserIds, 842 @Nullable SparseArray<int[]> broadcastAllowList, 843 @Nullable Bundle bOptions) { 844 mHandler.post(() -> sendPackageBroadcast(action, pkg, extras, flags, 845 targetPkg, finishedReceiver, userIds, instantUserIds, broadcastAllowList, 846 null /* filterExtrasForReceiver */, bOptions)); 847 if (targetPkg == null) { 848 // For some broadcast action, e.g. ACTION_PACKAGE_ADDED, this method will be called 849 // many times to different targets, e.g. installer app, permission controller, other 850 // registered apps. We should filter it to avoid calling back many times for the same 851 // action. When the targetPkg is set, it sends the broadcast to specific app, e.g. 852 // installer app or null for registered apps. The callback only need to send back to the 853 // registered apps so we check the null condition here. 854 notifyPackageMonitor(action, pkg, extras, userIds, instantUserIds, broadcastAllowList, 855 null /* filterExtras */); 856 } 857 } 858 sendSystemPackageUpdatedBroadcasts(@onNull PackageRemovedInfo packageRemovedInfo)859 void sendSystemPackageUpdatedBroadcasts(@NonNull PackageRemovedInfo packageRemovedInfo) { 860 if (!packageRemovedInfo.mIsRemovedPackageSystemUpdate) { 861 return; 862 } 863 864 final String removedPackage = packageRemovedInfo.mRemovedPackage; 865 final String installerPackageName = packageRemovedInfo.mInstallerPackageName; 866 final SparseArray<int[]> broadcastAllowList = packageRemovedInfo.mBroadcastAllowList; 867 868 Bundle extras = new Bundle(2); 869 extras.putInt(Intent.EXTRA_UID, packageRemovedInfo.mUid); 870 extras.putBoolean(Intent.EXTRA_REPLACING, true); 871 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, removedPackage, extras, 872 0, null /*targetPackage*/, null, null, null, broadcastAllowList, null); 873 874 if (installerPackageName != null) { 875 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_ADDED, 876 removedPackage, extras, 0 /*flags*/, 877 installerPackageName, null, null, null, null /* broadcastAllowList */, 878 null); 879 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REPLACED, 880 removedPackage, extras, 0 /*flags*/, 881 installerPackageName, null, null, null, null /* broadcastAllowList */, 882 null); 883 } 884 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 885 extras, 0, null /*targetPackage*/, null, null, null, broadcastAllowList, null); 886 sendPackageBroadcastAndNotify(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0, 887 removedPackage, null, null, null, null /* broadcastAllowList */, 888 getTemporaryBroadcastOptionsForSystemPackageUpdate(REASON_PACKAGE_REPLACED) 889 .toBundle()); 890 } 891 892 @SuppressLint("AndroidFrameworkRequiresPermission") getTemporaryBroadcastOptionsForSystemPackageUpdate( @owerExemptionManager.ReasonCode int reasonCode)893 private @NonNull BroadcastOptions getTemporaryBroadcastOptionsForSystemPackageUpdate( 894 @PowerExemptionManager.ReasonCode int reasonCode) { 895 long duration = 10_000; 896 if (mAmInternal != null) { 897 duration = mAmInternal.getBootTimeTempAllowListDuration(); 898 } 899 final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); 900 bOptions.setTemporaryAppAllowlist(duration, 901 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 902 reasonCode, ""); 903 return bOptions; 904 } 905 906 sendPackageRemovedBroadcasts( @onNull PackageRemovedInfo packageRemovedInfo, @NonNull PackageSender packageSender, boolean killApp, boolean removedBySystem, boolean isArchived)907 void sendPackageRemovedBroadcasts( 908 @NonNull PackageRemovedInfo packageRemovedInfo, 909 @NonNull PackageSender packageSender, 910 boolean killApp, 911 boolean removedBySystem, 912 boolean isArchived) { 913 final String removedPackage = packageRemovedInfo.mRemovedPackage; 914 final String installerPackageName = packageRemovedInfo.mInstallerPackageName; 915 final int[] broadcastUserIds = packageRemovedInfo.mBroadcastUsers; 916 final int[] instantUserIds = packageRemovedInfo.mInstantUserIds; 917 final SparseArray<int[]> broadcastAllowList = packageRemovedInfo.mBroadcastAllowList; 918 final boolean dataRemoved = packageRemovedInfo.mDataRemoved; 919 final boolean isUpdate = packageRemovedInfo.mIsUpdate; 920 final boolean isRemovedPackageSystemUpdate = 921 packageRemovedInfo.mIsRemovedPackageSystemUpdate; 922 final boolean isRemovedForAllUsers = packageRemovedInfo.mRemovedForAllUsers; 923 final boolean isStaticSharedLib = packageRemovedInfo.mIsStaticSharedLib; 924 925 Bundle extras = new Bundle(); 926 extras.putInt(Intent.EXTRA_UID, packageRemovedInfo.mUid); 927 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 928 extras.putBoolean(Intent.EXTRA_SYSTEM_UPDATE_UNINSTALL, isRemovedPackageSystemUpdate); 929 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 930 extras.putBoolean(Intent.EXTRA_USER_INITIATED, !removedBySystem); 931 final boolean isReplace = isUpdate || isRemovedPackageSystemUpdate; 932 if (isReplace || isArchived) { 933 extras.putBoolean(Intent.EXTRA_REPLACING, true); 934 } 935 if (isArchived) { 936 extras.putBoolean(Intent.EXTRA_ARCHIVAL, true); 937 } 938 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, isRemovedForAllUsers); 939 940 // Send PACKAGE_REMOVED broadcast to the respective installer. 941 if (removedPackage != null && installerPackageName != null) { 942 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REMOVED, 943 removedPackage, extras, 0 /*flags*/, 944 installerPackageName, null, broadcastUserIds, instantUserIds, null, null); 945 } 946 if (isStaticSharedLib) { 947 // When uninstalling static shared libraries, only the package's installer needs to be 948 // sent a PACKAGE_REMOVED broadcast. There are no other intended recipients. 949 return; 950 } 951 if (removedPackage != null) { 952 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REMOVED, 953 removedPackage, extras, 0, null /*targetPackage*/, null, 954 broadcastUserIds, instantUserIds, broadcastAllowList, null); 955 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_REMOVED_INTERNAL, 956 removedPackage, extras, 0 /*flags*/, PLATFORM_PACKAGE_NAME, 957 null /*finishedReceiver*/, broadcastUserIds, instantUserIds, 958 broadcastAllowList, null /*bOptions*/); 959 if (dataRemoved && !isRemovedPackageSystemUpdate) { 960 sendPackageBroadcastAndNotify(Intent.ACTION_PACKAGE_FULLY_REMOVED, 961 removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, 962 null, broadcastUserIds, instantUserIds, broadcastAllowList, null); 963 packageSender.notifyPackageRemoved(removedPackage, packageRemovedInfo.mUid); 964 } 965 } 966 if (packageRemovedInfo.mIsAppIdRemoved) { 967 // If a system app's updates are uninstalled the UID is not actually removed. Some 968 // services need to know the package name affected. 969 // 970 // When setting Intent.EXTRA_REPLACING is true for isReplace or isArchived above, 971 // the system triggers AppOpsService#resetAllModes in 972 // ActivityManagerService#broadcastIntentLockedTraced when the action is 973 // ACTION_UID_REMOVED. Add Intent.EXTRA_PACKAGE_NAME for isReplace or isArchived too. 974 // Because AppOpsService#resetAllModes needs the packageName to define which uid to be 975 // reset. If there is no package name, it resets the all appOps for all uids. 976 if (isReplace || isArchived) { 977 extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage); 978 } 979 980 sendPackageBroadcastAndNotify(Intent.ACTION_UID_REMOVED, 981 null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, 982 null, null, broadcastUserIds, instantUserIds, broadcastAllowList, null); 983 } 984 } 985 986 /** 987 * Send broadcast intents for packages suspension changes. 988 * 989 * @param intent The action name of the suspension intent. 990 * @param pkgList The names of packages which have suspension changes. 991 * @param uidList The uids of packages which have suspension changes. 992 * @param userId The user where packages reside. 993 */ sendPackagesSuspendedOrUnsuspendedForUser(@onNull Computer snapshot, @NonNull String intent, @NonNull String[] pkgList, @NonNull int[] uidList, boolean quarantined, int userId)994 void sendPackagesSuspendedOrUnsuspendedForUser(@NonNull Computer snapshot, 995 @NonNull String intent, 996 @NonNull String[] pkgList, 997 @NonNull int[] uidList, 998 boolean quarantined, 999 int userId) { 1000 final Bundle extras = new Bundle(3); 1001 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 1002 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); 1003 if (quarantined) { 1004 extras.putBoolean(Intent.EXTRA_QUARANTINED, true); 1005 } 1006 final int flags = Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND; 1007 final Bundle options = new BroadcastOptions() 1008 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE) 1009 .toBundle(); 1010 BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver = 1011 (callingUid, intentExtras) -> BroadcastHelper.filterExtrasChangedPackageList( 1012 snapshot, callingUid, intentExtras); 1013 mHandler.post(() -> sendPackageBroadcast(intent, null /* pkg */, 1014 extras, flags, null /* targetPkg */, null /* finishedReceiver */, 1015 new int[]{userId}, null /* instantUserIds */, null /* broadcastAllowList */, 1016 filterExtrasForReceiver, 1017 options)); 1018 notifyPackageMonitor(intent, null /* pkg */, extras, new int[]{userId}, 1019 null /* instantUserIds */, null /* broadcastAllowList */, filterExtrasForReceiver); 1020 } 1021 sendMyPackageSuspendedOrUnsuspended(@onNull Computer snapshot, @NonNull String[] affectedPackages, boolean suspended, int userId)1022 void sendMyPackageSuspendedOrUnsuspended(@NonNull Computer snapshot, 1023 @NonNull String[] affectedPackages, 1024 boolean suspended, 1025 int userId) { 1026 final String action = suspended 1027 ? Intent.ACTION_MY_PACKAGE_SUSPENDED 1028 : Intent.ACTION_MY_PACKAGE_UNSUSPENDED; 1029 mHandler.post(() -> { 1030 final IActivityManager am = ActivityManager.getService(); 1031 if (am == null) { 1032 Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ " 1033 + (suspended ? "" : "UN") + "SUSPENDED broadcasts"); 1034 return; 1035 } 1036 final int[] targetUserIds = new int[] {userId}; 1037 for (String packageName : affectedPackages) { 1038 final Bundle appExtras = suspended 1039 ? SuspendPackageHelper.getSuspendedPackageAppExtras( 1040 snapshot, packageName, userId, SYSTEM_UID) 1041 : null; 1042 final Bundle intentExtras; 1043 if (appExtras != null) { 1044 intentExtras = new Bundle(1); 1045 intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras); 1046 } else { 1047 intentExtras = null; 1048 } 1049 doSendBroadcast(action, null, intentExtras, 1050 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null, 1051 targetUserIds, false, null, null, null); 1052 } 1053 }); 1054 } 1055 1056 /** 1057 * Send broadcast intents for packages distracting changes. 1058 * 1059 * @param pkgList The names of packages which have suspension changes. 1060 * @param uidList The uids of packages which have suspension changes. 1061 * @param userId The user where packages reside. 1062 */ sendDistractingPackagesChanged(@onNull Computer snapshot, @NonNull String[] pkgList, @NonNull int[] uidList, int userId, int distractionFlags)1063 void sendDistractingPackagesChanged(@NonNull Computer snapshot, 1064 @NonNull String[] pkgList, 1065 @NonNull int[] uidList, 1066 int userId, 1067 int distractionFlags) { 1068 final Bundle extras = new Bundle(); 1069 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 1070 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); 1071 extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); 1072 1073 mHandler.post(() -> sendPackageBroadcast( 1074 Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, 1075 extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, 1076 null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */, 1077 null /* broadcastAllowList */, 1078 (callingUid, intentExtras) -> filterExtrasChangedPackageList( 1079 snapshot, callingUid, intentExtras), 1080 null /* bOptions */)); 1081 } 1082 sendResourcesChangedBroadcastAndNotify(@onNull Computer snapshot, boolean mediaStatus, boolean replacing, @NonNull ArrayList<AndroidPackage> packages)1083 void sendResourcesChangedBroadcastAndNotify(@NonNull Computer snapshot, 1084 boolean mediaStatus, 1085 boolean replacing, 1086 @NonNull ArrayList<AndroidPackage> packages) { 1087 final int size = packages.size(); 1088 final String[] packageNames = new String[size]; 1089 final int[] packageUids = new int[size]; 1090 for (int i = 0; i < size; i++) { 1091 final AndroidPackage pkg = packages.get(i); 1092 packageNames[i] = pkg.getPackageName(); 1093 packageUids[i] = pkg.getUid(); 1094 } 1095 sendResourcesChangedBroadcast(snapshot, mediaStatus, 1096 replacing, packageNames, packageUids); 1097 notifyResourcesChanged(mediaStatus, replacing, packageNames, packageUids); 1098 } 1099 notifyPackageMonitor(@onNull String action, @NonNull String pkg, @Nullable Bundle extras, @NonNull int[] userIds, @NonNull int[] instantUserIds, @Nullable SparseArray<int[]> broadcastAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtras)1100 private void notifyPackageMonitor(@NonNull String action, 1101 @NonNull String pkg, 1102 @Nullable Bundle extras, 1103 @NonNull int[] userIds, 1104 @NonNull int[] instantUserIds, 1105 @Nullable SparseArray<int[]> broadcastAllowList, 1106 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtras) { 1107 mPackageMonitorCallbackHelper.notifyPackageMonitor(action, pkg, extras, userIds, 1108 instantUserIds, broadcastAllowList, mHandler, filterExtras); 1109 } 1110 notifyResourcesChanged(boolean mediaStatus, boolean replacing, @NonNull String[] pkgNames, @NonNull int[] uids)1111 private void notifyResourcesChanged(boolean mediaStatus, 1112 boolean replacing, 1113 @NonNull String[] pkgNames, 1114 @NonNull int[] uids) { 1115 mPackageMonitorCallbackHelper.notifyResourcesChanged(mediaStatus, replacing, pkgNames, 1116 uids, mHandler); 1117 } 1118 } 1119