• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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