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