• 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.permission;
18 
19 import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
20 import static android.Manifest.permission.POST_NOTIFICATIONS;
21 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
22 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
23 import static android.app.AppOpsManager.MODE_ALLOWED;
24 import static android.app.AppOpsManager.MODE_ERRORED;
25 import static android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DEFAULT;
26 import static android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED;
27 import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
31 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
35 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
36 import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
37 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
38 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
39 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
40 import static android.content.pm.PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;
41 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
42 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
43 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
44 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
45 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
46 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
47 import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
48 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
49 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
50 import static android.os.Process.INVALID_UID;
51 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
52 import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
53 import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
54 
55 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
56 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
57 import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
58 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
59 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
60 
61 import static java.util.concurrent.TimeUnit.SECONDS;
62 
63 import android.Manifest;
64 import android.annotation.AppIdInt;
65 import android.annotation.IntDef;
66 import android.annotation.NonNull;
67 import android.annotation.Nullable;
68 import android.annotation.SpecialUsers.CanBeALL;
69 import android.annotation.UserIdInt;
70 import android.app.ActivityManager;
71 import android.app.AppOpsManager;
72 import android.app.IActivityManager;
73 import android.app.admin.DevicePolicyManagerInternal;
74 import android.companion.virtual.VirtualDeviceManager;
75 import android.compat.annotation.ChangeId;
76 import android.compat.annotation.EnabledAfter;
77 import android.content.Context;
78 import android.content.pm.ApplicationInfo;
79 import android.content.pm.FeatureInfo;
80 import android.content.pm.PackageManager;
81 import android.content.pm.PackageManagerInternal;
82 import android.content.pm.PermissionGroupInfo;
83 import android.content.pm.PermissionInfo;
84 import android.content.pm.SigningDetails;
85 import android.content.pm.permission.SplitPermissionInfoParcelable;
86 import android.metrics.LogMaker;
87 import android.os.AsyncTask;
88 import android.os.Binder;
89 import android.os.Build;
90 import android.os.Debug;
91 import android.os.Handler;
92 import android.os.HandlerThread;
93 import android.os.Looper;
94 import android.os.Message;
95 import android.os.Process;
96 import android.os.RemoteCallbackList;
97 import android.os.RemoteException;
98 import android.os.ServiceManager;
99 import android.os.SystemProperties;
100 import android.os.Trace;
101 import android.os.UserHandle;
102 import android.os.UserManager;
103 import android.os.storage.StorageManager;
104 import android.permission.IOnPermissionsChangeListener;
105 import android.permission.PermissionControllerManager;
106 import android.permission.PermissionManager;
107 import android.provider.Settings;
108 import android.text.TextUtils;
109 import android.util.ArrayMap;
110 import android.util.ArraySet;
111 import android.util.DebugUtils;
112 import android.util.EventLog;
113 import android.util.Log;
114 import android.util.Pair;
115 import android.util.Slog;
116 import android.util.SparseArray;
117 import android.util.SparseBooleanArray;
118 
119 import com.android.internal.annotations.GuardedBy;
120 import com.android.internal.compat.IPlatformCompat;
121 import com.android.internal.logging.MetricsLogger;
122 import com.android.internal.logging.nano.MetricsProto;
123 import com.android.internal.os.RoSystemProperties;
124 import com.android.internal.pm.permission.CompatibilityPermissionInfo;
125 import com.android.internal.pm.pkg.component.ComponentMutateUtils;
126 import com.android.internal.pm.pkg.component.ParsedPermission;
127 import com.android.internal.pm.pkg.component.ParsedPermissionGroup;
128 import com.android.internal.pm.pkg.component.ParsedPermissionUtils;
129 import com.android.internal.util.ArrayUtils;
130 import com.android.internal.util.CollectionUtils;
131 import com.android.internal.util.IntPair;
132 import com.android.internal.util.Preconditions;
133 import com.android.server.FgThread;
134 import com.android.server.LocalServices;
135 import com.android.server.PermissionThread;
136 import com.android.server.ServiceThread;
137 import com.android.server.SystemConfig;
138 import com.android.server.Watchdog;
139 import com.android.server.pm.ApexManager;
140 import com.android.server.pm.KnownPackages;
141 import com.android.server.pm.PackageInstallerService;
142 import com.android.server.pm.PackageManagerTracedLock;
143 import com.android.server.pm.UserManagerInternal;
144 import com.android.server.pm.UserManagerService;
145 import com.android.server.pm.parsing.PackageInfoUtils;
146 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
147 import com.android.server.pm.pkg.AndroidPackage;
148 import com.android.server.pm.pkg.PackageState;
149 import com.android.server.pm.pkg.PackageStateInternal;
150 import com.android.server.pm.pkg.SharedUserApi;
151 import com.android.server.policy.PermissionPolicyInternal;
152 import com.android.server.policy.SoftRestrictedPermissionPolicy;
153 
154 import libcore.util.EmptyArray;
155 
156 import java.io.FileDescriptor;
157 import java.io.PrintWriter;
158 import java.lang.annotation.Retention;
159 import java.lang.annotation.RetentionPolicy;
160 import java.util.ArrayList;
161 import java.util.Arrays;
162 import java.util.Collection;
163 import java.util.Collections;
164 import java.util.HashMap;
165 import java.util.Iterator;
166 import java.util.List;
167 import java.util.Map;
168 import java.util.Objects;
169 import java.util.Optional;
170 import java.util.Set;
171 import java.util.concurrent.CompletableFuture;
172 import java.util.concurrent.ExecutionException;
173 import java.util.concurrent.TimeUnit;
174 import java.util.concurrent.TimeoutException;
175 
176 /**
177  * PermissionManagerServiceImpl.
178  */
179 public class PermissionManagerServiceImpl implements PermissionManagerServiceInterface {
180 
181     private static final String TAG = "PermissionManager";
182     private static final String LOG_TAG = PermissionManagerServiceImpl.class.getSimpleName();
183 
184     private static final String SKIP_KILL_APP_REASON_NOTIFICATION_TEST = "skip permission revoke "
185             + "app kill for notification test";
186 
187 
188     private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
189 
190     /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
191     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
192     /** Empty array to avoid allocations */
193     private static final int[] EMPTY_INT_ARRAY = new int[0];
194 
195     /**
196      * When these flags are set, the system should not automatically modify the permission grant
197      * state.
198      */
199     private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
200             | FLAG_PERMISSION_POLICY_FIXED
201             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
202 
203     /** Permission flags set by the user */
204     private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
205             | FLAG_PERMISSION_USER_FIXED;
206 
207     /** All storage permissions */
208     private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>();
209 
210     private static final Set<String> READ_MEDIA_AURAL_PERMISSIONS = new ArraySet<>();
211 
212     private static final Set<String> READ_MEDIA_VISUAL_PERMISSIONS = new ArraySet<>();
213 
214     /** All nearby devices permissions */
215     private static final List<String> NEARBY_DEVICES_PERMISSIONS = new ArrayList<>();
216 
217     /**
218      * All notification permissions.
219      * Notification permission state is treated differently from other permissions. Notification
220      * permission get the REVIEW_REQUIRED flag set for S- apps, or for T+ apps on updating to T or
221      * restoring a pre-T backup. The permission and app op remain denied. The flag will be read by
222      * the notification system, and allow apps to send notifications, until cleared.
223      * The flag is cleared for S- apps by the system showing a permission request prompt, and the
224      * user clicking "allow" or "deny" in the dialog. For T+ apps, the flag is cleared upon the
225      * first activity launch.
226      *
227      * @see PermissionPolicyInternal#showNotificationPromptIfNeeded(String, int, int)
228      */
229     private static final List<String> NOTIFICATION_PERMISSIONS = new ArrayList<>();
230 
231     /** If the permission of the value is granted, so is the key */
232     private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
233 
234     static {
FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)235         FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
236                 Manifest.permission.ACCESS_FINE_LOCATION);
FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS, Manifest.permission.INTERACT_ACROSS_USERS_FULL)237         FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
238                 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
239         STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
240         STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
241         READ_MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
242         READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
243         READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
244         READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
245         READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED);
246         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_ADVERTISE);
247         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
248         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
249         NOTIFICATION_PERMISSIONS.add(Manifest.permission.POST_NOTIFICATIONS);
250     }
251 
252     @NonNull private final ApexManager mApexManager;
253 
254     /** Set of source package names for Privileged Permission Allowlist */
255     private final ArraySet<String> mPrivilegedPermissionAllowlistSourcePackageNames =
256             new ArraySet<>();
257 
258     /** Lock to protect internal data access */
259     private final PackageManagerTracedLock mLock = new PackageManagerTracedLock();
260 
261     /** Internal connection to the package manager */
262     private final PackageManagerInternal mPackageManagerInt;
263 
264     /** Internal connection to the user manager */
265     private final UserManagerInternal mUserManagerInt;
266 
267     @GuardedBy("mLock")
268     @NonNull
269     private final DevicePermissionState mState = new DevicePermissionState();
270 
271     /** Permission controller: User space permission management */
272     private PermissionControllerManager mPermissionControllerManager;
273 
274     /**
275      * Built-in permissions. Read from system configuration files. Mapping is from
276      * UID to permission name.
277      */
278     private final SparseArray<ArraySet<String>> mSystemPermissions;
279 
280     /** Built-in group IDs given to all packages. Read from system configuration files. */
281     @NonNull
282     private final int[] mGlobalGids;
283 
284     private final Handler mHandler;
285     private final Context mContext;
286     private final MetricsLogger mMetricsLogger = new MetricsLogger();
287     private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
288             ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
289 
290     /** Internal storage for permissions and related settings */
291     @GuardedBy("mLock")
292     @NonNull
293     private final PermissionRegistry mRegistry = new PermissionRegistry();
294 
295     @GuardedBy("mLock")
296     @Nullable
297     private ArraySet<String> mPrivappPermissionsViolations;
298 
299     @GuardedBy("mLock")
300     private boolean mSystemReady;
301 
302     @GuardedBy("mLock")
303     private PermissionPolicyInternal mPermissionPolicyInternal;
304 
305     /**
306      * A permission backup might contain apps that are not installed. In this case we delay the
307      * restoration until the app is installed.
308      *
309      * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
310      * there is <u>no more</u> delayed backup left.
311      */
312     @GuardedBy("mLock")
313     private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
314 
315     private final boolean mIsLeanback;
316 
317     @NonNull
318     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
319 
320     // TODO: Take a look at the methods defined in the callback.
321     // The callback was initially created to support the split between permission
322     // manager and the package manager. However, it's started to be used for other
323     // purposes. It may make sense to keep as an abstraction, but, the methods
324     // necessary to be overridden may be different than what was initially needed
325     // for the split.
326     private final PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
327         @Override
328         public void onGidsChanged(int appId, int userId) {
329             mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
330         }
331         @Override
332         public void onPermissionGranted(int uid, int userId) {
333             mOnPermissionChangeListeners.onPermissionsChanged(uid);
334 
335             // Not critical; if this is lost, the application has to request again.
336             mPackageManagerInt.writeSettings(true);
337         }
338         @Override
339         public void onInstallPermissionGranted() {
340             mPackageManagerInt.writeSettings(true);
341         }
342         @Override
343         public void onPermissionRevoked(int uid, int userId, String reason, boolean overrideKill,
344                 @Nullable String permissionName) {
345             mOnPermissionChangeListeners.onPermissionsChanged(uid);
346 
347             // Critical; after this call the application should never have the permission
348             mPackageManagerInt.writeSettings(false);
349             if (overrideKill) {
350                 return;
351             }
352 
353             mHandler.post(() -> {
354                 if (POST_NOTIFICATIONS.equals(permissionName)
355                         && isAppBackupAndRestoreRunning(uid)) {
356                     return;
357                 }
358 
359                 final int appId = UserHandle.getAppId(uid);
360                 if (reason == null) {
361                     killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
362                 } else {
363                     killUid(appId, userId, reason);
364                 }
365             });
366         }
367 
368         private boolean isAppBackupAndRestoreRunning(int uid) {
369             if (checkUidPermission(uid, Manifest.permission.BACKUP) != PERMISSION_GRANTED) {
370                 return false;
371             }
372 
373             int userId = UserHandle.getUserId(uid);
374 
375             boolean isInSetup =
376                     getSecureInt(Settings.Secure.USER_SETUP_COMPLETE, userId)
377                              .map(setupState -> setupState == 0)
378                              .orElse(false);
379             if (isInSetup) {
380                 return true;
381             }
382 
383             boolean isInDeferredSetup =
384                     getSecureInt(Settings.Secure.USER_SETUP_PERSONALIZATION_STATE, userId)
385                             .map(state ->
386                                     state == Settings.Secure.USER_SETUP_PERSONALIZATION_STARTED)
387                             .orElse(false);
388             return isInDeferredSetup;
389         }
390 
391         private Optional<Integer> getSecureInt(String settingName, int userId) {
392             try {
393                 return Optional.of(
394                         Settings.Secure.getIntForUser(
395                                 mContext.getContentResolver(), settingName, userId));
396             } catch (Settings.SettingNotFoundException e) {
397                 Slog.i(LOG_TAG, "Setting " + settingName + " not found", e);
398                 return Optional.empty();
399             }
400         }
401 
402         @Override
403         public void onInstallPermissionRevoked() {
404             mPackageManagerInt.writeSettings(true);
405         }
406         @Override
407         public void onPermissionUpdated(int[] userIds, boolean sync, int appId) {
408             for (int i = 0; i < userIds.length; i++) {
409                 int uid = UserHandle.getUid(userIds[i], appId);
410                 mOnPermissionChangeListeners.onPermissionsChanged(uid);
411             }
412             mPackageManagerInt.writePermissionSettings(userIds, !sync);
413         }
414         @Override
415         public void onInstallPermissionUpdated() {
416             mPackageManagerInt.writeSettings(true);
417         }
418         @Override
419         public void onPermissionRemoved() {
420             mPackageManagerInt.writeSettings(false);
421         }
422     };
423 
PermissionManagerServiceImpl(@onNull Context context, @NonNull ArrayMap<String, FeatureInfo> availableFeatures)424     public PermissionManagerServiceImpl(@NonNull Context context,
425             @NonNull ArrayMap<String, FeatureInfo> availableFeatures) {
426         // The package info cache is the cache for package and permission information.
427         // Disable the package info and package permission caches locally but leave the
428         // checkPermission cache active.
429         PackageManager.invalidatePackageInfoCache();
430         PermissionManager.disablePackageNamePermissionCache();
431 
432         mContext = context;
433         mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
434         mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
435         mIsLeanback = availableFeatures.containsKey(PackageManager.FEATURE_LEANBACK);
436         mApexManager = ApexManager.getInstance();
437 
438         mPrivilegedPermissionAllowlistSourcePackageNames.add(PLATFORM_PACKAGE_NAME);
439         // PackageManager.hasSystemFeature() is not used here because PackageManagerService
440         // isn't ready yet.
441         if (availableFeatures.containsKey(PackageManager.FEATURE_AUTOMOTIVE)) {
442             // The property defined in car api surface, so use the string directly.
443             String carServicePackage = SystemProperties.get("ro.android.car.carservice.package",
444                     null);
445             if (carServicePackage != null) {
446                 mPrivilegedPermissionAllowlistSourcePackageNames.add(carServicePackage);
447             }
448         }
449 
450         HandlerThread handlerThread = new ServiceThread(TAG,
451                 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
452         handlerThread.start();
453         mHandler = new Handler(handlerThread.getLooper());
454         Watchdog.getInstance().addThread(mHandler);
455 
456         SystemConfig systemConfig = SystemConfig.getInstance();
457         mSystemPermissions = systemConfig.getSystemPermissions();
458         mGlobalGids = systemConfig.getGlobalGids();
459         mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
460 
461         // propagate permission configuration
462         final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
463                 SystemConfig.getInstance().getPermissions();
464         synchronized (mLock) {
465             for (int i = 0; i < permConfig.size(); i++) {
466                 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
467                 Permission bp = mRegistry.getPermission(perm.name);
468                 if (bp == null) {
469                     bp = new Permission(perm.name, "android", Permission.TYPE_CONFIG);
470                     mRegistry.addPermission(bp);
471                 }
472                 if (perm.gids != null) {
473                     bp.setGids(perm.gids, perm.perUser);
474                 }
475             }
476         }
477     }
478 
479     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)480     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {}
481 
482     /**
483      * This method should typically only be used when granting or revoking
484      * permissions, since the app may immediately restart after this call.
485      * <p>
486      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
487      * guard your work against the app being relaunched.
488      */
killUid(int appId, int userId, String reason)489     private static void killUid(int appId, int userId, String reason) {
490         final long identity = Binder.clearCallingIdentity();
491         try {
492             IActivityManager am = ActivityManager.getService();
493             if (am != null) {
494                 try {
495                     am.killUidForPermissionChange(appId, userId, reason);
496                 } catch (RemoteException e) {
497                     /* ignore - same process */
498                 }
499             }
500         } finally {
501             Binder.restoreCallingIdentity(identity);
502         }
503     }
504 
505     @NonNull
getAppOpPermissionPackagesInternal(@onNull String permissionName)506     private String[] getAppOpPermissionPackagesInternal(@NonNull String permissionName) {
507         synchronized (mLock) {
508             final ArraySet<String> packageNames = mRegistry.getAppOpPermissionPackages(
509                     permissionName);
510             if (packageNames == null) {
511                 return EmptyArray.STRING;
512             }
513             return packageNames.toArray(new String[0]);
514         }
515     }
516 
517     @Override
518     @NonNull
getAllPermissionGroups( @ackageManager.PermissionGroupInfoFlags int flags)519     public List<PermissionGroupInfo> getAllPermissionGroups(
520             @PackageManager.PermissionGroupInfoFlags int flags) {
521         final int callingUid = Binder.getCallingUid();
522         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
523             return Collections.emptyList();
524         }
525 
526         final List<PermissionGroupInfo> out = new ArrayList<>();
527         synchronized (mLock) {
528             for (ParsedPermissionGroup pg : mRegistry.getPermissionGroups()) {
529                 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
530             }
531         }
532 
533         final int callingUserId = UserHandle.getUserId(callingUid);
534         out.removeIf(it -> mPackageManagerInt.filterAppAccess(it.packageName, callingUid,
535                 callingUserId, false /* filterUninstalled */));
536         return out;
537     }
538 
539     @Override
540     @Nullable
getPermissionGroupInfo(String groupName, @PackageManager.PermissionGroupInfoFlags int flags)541     public PermissionGroupInfo getPermissionGroupInfo(String groupName,
542             @PackageManager.PermissionGroupInfoFlags int flags) {
543         final int callingUid = Binder.getCallingUid();
544         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
545             return null;
546         }
547 
548         final PermissionGroupInfo permissionGroupInfo;
549         synchronized (mLock) {
550             final ParsedPermissionGroup permissionGroup = mRegistry.getPermissionGroup(groupName);
551             if (permissionGroup == null) {
552                 return null;
553             }
554             permissionGroupInfo = PackageInfoUtils.generatePermissionGroupInfo(permissionGroup,
555                     flags);
556         }
557 
558         final int callingUserId = UserHandle.getUserId(callingUid);
559         if (mPackageManagerInt.filterAppAccess(permissionGroupInfo.packageName, callingUid,
560                 callingUserId, false /* filterUninstalled */)) {
561             EventLog.writeEvent(0x534e4554, "186113473", callingUid, groupName);
562             return null;
563         }
564         return permissionGroupInfo;
565     }
566 
567     @Override
568     @Nullable
getPermissionInfo(@onNull String permName, @PackageManager.PermissionInfoFlags int flags, @NonNull String opPackageName)569     public PermissionInfo getPermissionInfo(@NonNull String permName,
570             @PackageManager.PermissionInfoFlags int flags, @NonNull String opPackageName) {
571         final int callingUid = Binder.getCallingUid();
572         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
573             return null;
574         }
575 
576         final AndroidPackage opPackage = mPackageManagerInt.getPackage(opPackageName);
577         final int targetSdkVersion = getPermissionInfoCallingTargetSdkVersion(opPackage,
578                 callingUid);
579         final PermissionInfo permissionInfo;
580         synchronized (mLock) {
581             final Permission bp = mRegistry.getPermission(permName);
582             if (bp == null) {
583                 return null;
584             }
585             permissionInfo = bp.generatePermissionInfo(flags, targetSdkVersion);
586         }
587 
588         final int callingUserId = UserHandle.getUserId(callingUid);
589         if (mPackageManagerInt.filterAppAccess(permissionInfo.packageName, callingUid,
590                 callingUserId, false /* filterUninstalled */)) {
591             EventLog.writeEvent(0x534e4554, "183122164", callingUid, permName);
592             return null;
593         }
594         return permissionInfo;
595     }
596 
getPermissionInfoCallingTargetSdkVersion(@ullable AndroidPackage pkg, int uid)597     private int getPermissionInfoCallingTargetSdkVersion(@Nullable AndroidPackage pkg, int uid) {
598         final int appId = UserHandle.getAppId(uid);
599         if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID
600                 || appId == Process.SHELL_UID) {
601             // System sees all flags.
602             return Build.VERSION_CODES.CUR_DEVELOPMENT;
603         }
604         if (pkg == null) {
605             return Build.VERSION_CODES.CUR_DEVELOPMENT;
606         }
607         return pkg.getTargetSdkVersion();
608     }
609 
610     @Override
611     @Nullable
queryPermissionsByGroup(String groupName, @PackageManager.PermissionInfoFlags int flags)612     public List<PermissionInfo> queryPermissionsByGroup(String groupName,
613             @PackageManager.PermissionInfoFlags int flags) {
614         final int callingUid = Binder.getCallingUid();
615         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
616             return null;
617         }
618 
619         final ParsedPermissionGroup permissionGroup;
620         final List<PermissionInfo> out = new ArrayList<>(10);
621         synchronized (mLock) {
622             permissionGroup = mRegistry.getPermissionGroup(groupName);
623             if (groupName != null && permissionGroup == null) {
624                 return null;
625             }
626             for (Permission bp : mRegistry.getPermissions()) {
627                 if (Objects.equals(bp.getGroup(), groupName)) {
628                     out.add(bp.generatePermissionInfo(flags));
629                 }
630             }
631         }
632 
633         final int callingUserId = UserHandle.getUserId(callingUid);
634         if (permissionGroup != null && mPackageManagerInt.filterAppAccess(
635                 permissionGroup.getPackageName(), callingUid, callingUserId,
636                 false /* filterUninstalled */)) {
637             return null;
638         }
639         out.removeIf(it -> mPackageManagerInt.filterAppAccess(it.packageName, callingUid,
640                 callingUserId, false /* filterUninstalled */));
641         return out;
642     }
643 
644     @Override
addPermission(PermissionInfo info, boolean async)645     public boolean addPermission(PermissionInfo info, boolean async) {
646         final int callingUid = Binder.getCallingUid();
647         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
648             throw new SecurityException("Instant apps can't add permissions");
649         }
650         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
651             throw new SecurityException("Label must be specified in permission");
652         }
653         final boolean added;
654         final boolean changed;
655         synchronized (mLock) {
656             final Permission tree = mRegistry.enforcePermissionTree(info.name, callingUid);
657             Permission bp = mRegistry.getPermission(info.name);
658             added = bp == null;
659             int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
660             enforcePermissionCapLocked(info, tree);
661             if (added) {
662                 bp = new Permission(info.name, tree.getPackageName(), Permission.TYPE_DYNAMIC);
663             } else if (!bp.isDynamic()) {
664                 throw new SecurityException("Not allowed to modify non-dynamic permission "
665                         + info.name);
666             }
667             changed = bp.addToTree(fixedLevel, info, tree);
668             if (added) {
669                 mRegistry.addPermission(bp);
670             }
671         }
672         if (changed) {
673             mPackageManagerInt.writeSettings(async);
674         }
675         return added;
676     }
677 
678     @Override
removePermission(String permName)679     public void removePermission(String permName) {
680         final int callingUid = Binder.getCallingUid();
681         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
682             throw new SecurityException("Instant applications don't have access to this method");
683         }
684         synchronized (mLock) {
685             mRegistry.enforcePermissionTree(permName, callingUid);
686             final Permission bp = mRegistry.getPermission(permName);
687             if (bp == null) {
688                 return;
689             }
690             if (!bp.isDynamic()) {
691                 // TODO: switch this back to SecurityException
692                 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
693                         + permName);
694                 return;
695             }
696             mRegistry.removePermission(permName);
697         }
698         mPackageManagerInt.writeSettings(false);
699     }
700 
701     @Override
getPermissionFlags(String packageName, String permName, String deviceId, int userId)702     public int getPermissionFlags(String packageName, String permName, String deviceId,
703             int userId) {
704         final int callingUid = Binder.getCallingUid();
705         return getPermissionFlagsInternal(packageName, permName, callingUid, userId);
706     }
707 
getPermissionFlagsInternal( String packageName, String permName, int callingUid, int userId)708     private int getPermissionFlagsInternal(
709             String packageName, String permName, int callingUid, int userId) {
710         if (!mUserManagerInt.exists(userId)) {
711             return 0;
712         }
713 
714         enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
715         enforceCrossUserPermission(callingUid, userId,
716                 true,  // requireFullPermission
717                 false, // checkShell
718                 "getPermissionFlags");
719 
720         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
721         if (pkg == null) {
722             return 0;
723         }
724         if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
725                 false /* filterUninstalled */)) {
726             return 0;
727         }
728 
729         synchronized (mLock) {
730             if (mRegistry.getPermission(permName) == null) {
731                 return 0;
732             }
733 
734             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
735             if (uidState == null) {
736                 Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId);
737                 return 0;
738             }
739 
740             return uidState.getPermissionFlags(permName);
741         }
742     }
743 
744     @Override
updatePermissionFlags(String packageName, String permName, int flagMask, int flagValues, boolean checkAdjustPolicyFlagPermission, String deviceId, int userId)745     public void updatePermissionFlags(String packageName, String permName, int flagMask,
746             int flagValues, boolean checkAdjustPolicyFlagPermission, String deviceId, int userId) {
747         final int callingUid = Binder.getCallingUid();
748         boolean overridePolicy = false;
749 
750         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
751             if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
752                 if (checkAdjustPolicyFlagPermission) {
753                     mContext.enforceCallingOrSelfPermission(
754                             Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
755                             "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
756                                     + " to change policy flags");
757                 } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid)
758                         >= Build.VERSION_CODES.Q) {
759                     throw new IllegalArgumentException(
760                             Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
761                                     + " to be checked for packages targeting "
762                                     + Build.VERSION_CODES.Q + " or later when changing policy "
763                                     + "flags");
764                 }
765                 overridePolicy = true;
766             }
767         }
768 
769         updatePermissionFlagsInternal(
770                 packageName, permName, flagMask, flagValues, callingUid, userId,
771                 overridePolicy, mDefaultPermissionCallback);
772     }
773 
updatePermissionFlagsInternal(String packageName, String permName, int flagMask, int flagValues, int callingUid, int userId, boolean overridePolicy, PermissionCallback callback)774     private void updatePermissionFlagsInternal(String packageName, String permName, int flagMask,
775             int flagValues, int callingUid, int userId, boolean overridePolicy,
776             PermissionCallback callback) {
777         if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
778                 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
779             Log.i(TAG, "System is updating flags for " + packageName + " "
780                             + permName + " for user " + userId  + " "
781                             + DebugUtils.flagsToString(
782                                     PackageManager.class, "FLAG_PERMISSION_", flagMask)
783                             + " := "
784                             + DebugUtils.flagsToString(
785                                     PackageManager.class, "FLAG_PERMISSION_", flagValues)
786                             + " on behalf of uid " + callingUid
787                             + " " + mPackageManagerInt.getNameForUid(callingUid),
788                     new RuntimeException());
789         }
790 
791         if (!mUserManagerInt.exists(userId)) {
792             return;
793         }
794 
795         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
796 
797         enforceCrossUserPermission(callingUid, userId,
798                 true,  // requireFullPermission
799                 true,  // checkShell
800                 "updatePermissionFlags");
801 
802         if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
803             throw new SecurityException("updatePermissionFlags requires "
804                     + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
805         }
806 
807         // Only the system can change these flags and nothing else.
808         if (callingUid != Process.SYSTEM_UID) {
809             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
810             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
811             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
812             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
813             flagValues &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
814             flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
815             flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
816             flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
817         }
818 
819         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
820         if (pkg == null) {
821             Log.e(TAG, "Unknown package: " + packageName);
822             return;
823         }
824         if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
825                 false /* filterUninstalled */)) {
826             throw new IllegalArgumentException("Unknown package: " + packageName);
827         }
828 
829         boolean isRequested = false;
830         // Fast path, the current package has requested the permission.
831         if (pkg.getRequestedPermissions().contains(permName)) {
832             isRequested = true;
833         }
834         if (!isRequested) {
835             // Slow path, go through all shared user packages.
836             String[] sharedUserPackageNames =
837                     mPackageManagerInt.getSharedUserPackagesForPackage(packageName, userId);
838             for (String sharedUserPackageName : sharedUserPackageNames) {
839                 AndroidPackage sharedUserPkg = mPackageManagerInt.getPackage(
840                         sharedUserPackageName);
841                 if (sharedUserPkg != null
842                         && sharedUserPkg.getRequestedPermissions().contains(permName)) {
843                     isRequested = true;
844                     break;
845                 }
846             }
847         }
848 
849         final boolean isRuntimePermission;
850         final boolean permissionUpdated;
851         synchronized (mLock) {
852             final Permission bp = mRegistry.getPermission(permName);
853             if (bp == null) {
854                 throw new IllegalArgumentException("Unknown permission: " + permName);
855             }
856 
857             isRuntimePermission = bp.isRuntime();
858 
859             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
860             if (uidState == null) {
861                 Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId);
862                 return;
863             }
864 
865             if (!uidState.hasPermissionState(permName) && !isRequested) {
866                 Log.e(TAG, "Permission " + permName + " isn't requested by package " + packageName);
867                 return;
868             }
869 
870             permissionUpdated = uidState.updatePermissionFlags(bp, flagMask, flagValues);
871         }
872 
873         if (permissionUpdated && callback != null) {
874             // Install and runtime permissions are stored in different places,
875             // so figure out what permission changed and persist the change.
876             if (!isRuntimePermission) {
877                 callback.onInstallPermissionUpdated();
878             } else {
879                 callback.onPermissionUpdated(new int[]{ userId }, false, pkg.getUid());
880             }
881         }
882     }
883 
884     /**
885      * Update the permission flags for all packages and runtime permissions of a user in order
886      * to allow device or profile owner to remove POLICY_FIXED.
887      */
888     @Override
updatePermissionFlagsForAllApps(int flagMask, int flagValues, final int userId)889     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
890             final int userId) {
891         final int callingUid = Binder.getCallingUid();
892         if (!mUserManagerInt.exists(userId)) {
893             return;
894         }
895 
896         enforceGrantRevokeRuntimePermissionPermissions(
897                 "updatePermissionFlagsForAllApps");
898         enforceCrossUserPermission(callingUid, userId,
899                 true,  // requireFullPermission
900                 true,  // checkShell
901                 "updatePermissionFlagsForAllApps");
902 
903         // Only the system can change system fixed flags.
904         final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
905                 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
906         final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
907                 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
908 
909         final boolean[] changed = new boolean[1];
910         mPackageManagerInt.forEachPackage(pkg -> {
911             synchronized (mLock) {
912                 final UidPermissionState uidState = getUidStateLocked(pkg, userId);
913                 if (uidState == null) {
914                     Slog.e(TAG,
915                             "Missing permissions state for " + pkg.getPackageName() + " and user "
916                                     + userId);
917                     return;
918                 }
919                 changed[0] |= uidState.updatePermissionFlagsForAllPermissions(
920                         effectiveFlagMask, effectiveFlagValues);
921             }
922             mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
923         });
924 
925         if (changed[0]) {
926             mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
927         }
928     }
929 
checkPermission(String pkgName, String permName, int userId)930     private int checkPermission(String pkgName, String permName, int userId) {
931         return checkPermission(pkgName, permName, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
932                 userId);
933     }
934 
935     @Override
checkPermission(String pkgName, String permName, String deviceId, int userId)936     public int checkPermission(String pkgName, String permName, String deviceId, int userId) {
937         if (!mUserManagerInt.exists(userId)) {
938             return PackageManager.PERMISSION_DENIED;
939         }
940 
941         final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName);
942         if (pkg == null) {
943             return PackageManager.PERMISSION_DENIED;
944         }
945         return checkPermissionInternal(pkg, true, permName, userId);
946     }
947 
checkPermissionInternal(@onNull AndroidPackage pkg, boolean isPackageExplicit, @NonNull String permissionName, @UserIdInt int userId)948     private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
949             @NonNull String permissionName, @UserIdInt int userId) {
950         final int callingUid = Binder.getCallingUid();
951         if (isPackageExplicit || pkg.getSharedUserId() == null) {
952             if (mPackageManagerInt.filterAppAccess(pkg.getPackageName(), callingUid, userId,
953                     false /* filterUninstalled */)) {
954                 return PackageManager.PERMISSION_DENIED;
955             }
956         } else {
957             if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
958                 return PackageManager.PERMISSION_DENIED;
959             }
960         }
961 
962         final int uid = UserHandle.getUid(userId, pkg.getUid());
963         final boolean isInstantApp = mPackageManagerInt.getInstantAppPackageName(uid) != null;
964 
965         synchronized (mLock) {
966             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
967             if (uidState == null) {
968                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
969                         + userId);
970                 return PackageManager.PERMISSION_DENIED;
971             }
972 
973             if (checkSinglePermissionInternalLocked(uidState, permissionName, isInstantApp)) {
974                 return PackageManager.PERMISSION_GRANTED;
975             }
976 
977             final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
978             if (fullerPermissionName != null && checkSinglePermissionInternalLocked(uidState,
979                     fullerPermissionName, isInstantApp)) {
980                 return PackageManager.PERMISSION_GRANTED;
981             }
982         }
983 
984         return PackageManager.PERMISSION_DENIED;
985     }
986 
987     @GuardedBy("mLock")
checkSinglePermissionInternalLocked(@onNull UidPermissionState uidState, @NonNull String permissionName, boolean isInstantApp)988     private boolean checkSinglePermissionInternalLocked(@NonNull UidPermissionState uidState,
989             @NonNull String permissionName, boolean isInstantApp) {
990         if (!uidState.isPermissionGranted(permissionName)) {
991             return false;
992         }
993 
994         if (isInstantApp) {
995             final Permission permission = mRegistry.getPermission(permissionName);
996             return permission != null && permission.isInstant();
997         }
998 
999         return true;
1000     }
1001 
checkUidPermission(int uid, String permName)1002     private int checkUidPermission(int uid, String permName) {
1003         return checkUidPermission(uid, permName, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
1004     }
1005 
1006     @Override
checkUidPermission(int uid, String permName, String deviceId)1007     public int checkUidPermission(int uid, String permName, String deviceId) {
1008         final int userId = UserHandle.getUserId(uid);
1009         if (!mUserManagerInt.exists(userId)) {
1010             return PackageManager.PERMISSION_DENIED;
1011         }
1012 
1013         final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
1014         return checkUidPermissionInternal(pkg, uid, permName);
1015     }
1016 
1017     @Override
getPermissionRequestState(String packageName, String permName, int deviceId, String persistentDeviceId)1018     public int getPermissionRequestState(String packageName, String permName, int deviceId,
1019             String persistentDeviceId) {
1020         throw new IllegalStateException("getPermissionRequestState is not supported.");
1021     }
1022 
1023     @Override
getAllPermissionStates( @onNull String packageName, @NonNull String deviceId, int userId)1024     public Map<String, PermissionManager.PermissionState> getAllPermissionStates(
1025             @NonNull String packageName, @NonNull String deviceId, int userId) {
1026         throw new UnsupportedOperationException(
1027                 "This method is supported in newer implementation only");
1028     }
1029 
1030     /**
1031      * Checks whether or not the given package has been granted the specified
1032      * permission. If the given package is {@code null}, we instead check the
1033      * system permissions for the given UID.
1034      *
1035      * @see SystemConfig#getSystemPermissions()
1036      */
checkUidPermissionInternal(@ullable AndroidPackage pkg, int uid, @NonNull String permissionName)1037     private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid,
1038             @NonNull String permissionName) {
1039         if (pkg != null) {
1040             final int userId = UserHandle.getUserId(uid);
1041             return checkPermissionInternal(pkg, false, permissionName, userId);
1042         }
1043 
1044         synchronized (mLock) {
1045             if (checkSingleUidPermissionInternalLocked(uid, permissionName)) {
1046                 return PackageManager.PERMISSION_GRANTED;
1047             }
1048 
1049             final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
1050             if (fullerPermissionName != null
1051                     && checkSingleUidPermissionInternalLocked(uid, fullerPermissionName)) {
1052                 return PackageManager.PERMISSION_GRANTED;
1053             }
1054         }
1055 
1056         return PackageManager.PERMISSION_DENIED;
1057     }
1058 
1059     @GuardedBy("mLock")
checkSingleUidPermissionInternalLocked(int uid, @NonNull String permissionName)1060     private boolean checkSingleUidPermissionInternalLocked(int uid,
1061             @NonNull String permissionName) {
1062         ArraySet<String> permissions = mSystemPermissions.get(uid);
1063         return permissions != null && permissions.contains(permissionName);
1064     }
1065 
1066     @Override
addOnPermissionsChangeListener(IOnPermissionsChangeListener listener)1067     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1068         mContext.enforceCallingOrSelfPermission(
1069                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
1070                 "addOnPermissionsChangeListener");
1071 
1072         mOnPermissionChangeListeners.addListener(listener);
1073     }
1074 
1075     @Override
removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener)1076     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1077         if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1078             throw new SecurityException("Instant applications don't have access to this method");
1079         }
1080         mOnPermissionChangeListeners.removeListener(listener);
1081     }
1082 
1083     @Nullable
1084     @Override
getAllowlistedRestrictedPermissions(@onNull String packageName, @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId)1085     public List<String> getAllowlistedRestrictedPermissions(@NonNull String packageName,
1086             @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId) {
1087         Objects.requireNonNull(packageName);
1088         Preconditions.checkFlagsArgument(flags,
1089                 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1090                         | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1091                         | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1092         Preconditions.checkArgumentNonNegative(userId, null);
1093 
1094         if (UserHandle.getCallingUserId() != userId) {
1095             mContext.enforceCallingOrSelfPermission(
1096                     android.Manifest.permission.INTERACT_ACROSS_USERS,
1097                     "getAllowlistedRestrictedPermissions for user " + userId);
1098         }
1099 
1100         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1101         if (pkg == null) {
1102             return null;
1103         }
1104 
1105         final int callingUid = Binder.getCallingUid();
1106         if (mPackageManagerInt.filterAppAccess(packageName, callingUid,
1107                 UserHandle.getCallingUserId(), false /* filterUninstalled */)) {
1108             return null;
1109         }
1110         final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1111                 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1112                         == PackageManager.PERMISSION_GRANTED;
1113         final boolean isCallerInstallerOnRecord =
1114                 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1115 
1116         if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1117                 && !isCallerPrivileged) {
1118             throw new SecurityException("Querying system allowlist requires "
1119                     + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1120         }
1121 
1122         if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1123                 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
1124             if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1125                 throw new SecurityException("Querying upgrade or installer allowlist"
1126                         + " requires being installer on record or "
1127                         + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1128             }
1129         }
1130 
1131         final long identity = Binder.clearCallingIdentity();
1132         try {
1133             return getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId);
1134         } finally {
1135             Binder.restoreCallingIdentity(identity);
1136         }
1137     }
1138 
1139     @Nullable
getAllowlistedRestrictedPermissionsInternal(@onNull AndroidPackage pkg, @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId)1140     private List<String> getAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
1141             @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId) {
1142         synchronized (mLock) {
1143             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
1144             if (uidState == null) {
1145                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
1146                         + userId);
1147                 return null;
1148             }
1149 
1150             int queryFlags = 0;
1151             if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
1152                 queryFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
1153             }
1154             if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1155                 queryFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
1156             }
1157             if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1158                 queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
1159             }
1160 
1161             ArrayList<String> allowlistedPermissions = null;
1162 
1163             for (final String permissionName : pkg.getRequestedPermissions()) {
1164                 final int currentFlags =
1165                         uidState.getPermissionFlags(permissionName);
1166                 if ((currentFlags & queryFlags) != 0) {
1167                     if (allowlistedPermissions == null) {
1168                         allowlistedPermissions = new ArrayList<>();
1169                     }
1170                     allowlistedPermissions.add(permissionName);
1171                 }
1172             }
1173 
1174             return allowlistedPermissions;
1175         }
1176     }
1177 
1178     @Override
addAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId)1179     public boolean addAllowlistedRestrictedPermission(@NonNull String packageName,
1180             @NonNull String permName, @PackageManager.PermissionWhitelistFlags int flags,
1181             @UserIdInt int userId) {
1182         // Other argument checks are done in get/setAllowlistedRestrictedPermissions
1183         Objects.requireNonNull(permName);
1184 
1185         if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1186             return false;
1187         }
1188 
1189         List<String> permissions =
1190                 getAllowlistedRestrictedPermissions(packageName, flags, userId);
1191         if (permissions == null) {
1192             permissions = new ArrayList<>(1);
1193         }
1194         if (permissions.indexOf(permName) < 0) {
1195             permissions.add(permName);
1196             return setAllowlistedRestrictedPermissions(packageName, permissions,
1197                     flags, userId);
1198         }
1199         return false;
1200     }
1201 
checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission( @onNull String permName)1202     private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
1203             @NonNull String permName) {
1204         final String permissionPackageName;
1205         final boolean isImmutablyRestrictedPermission;
1206         synchronized (mLock) {
1207             final Permission bp = mRegistry.getPermission(permName);
1208             if (bp == null) {
1209                 Slog.w(TAG, "No such permissions: " + permName);
1210                 return false;
1211             }
1212             permissionPackageName = bp.getPackageName();
1213             isImmutablyRestrictedPermission = bp.isHardOrSoftRestricted()
1214                     && bp.isImmutablyRestricted();
1215         }
1216 
1217         final int callingUid = Binder.getCallingUid();
1218         final int callingUserId = UserHandle.getUserId(callingUid);
1219         if (mPackageManagerInt.filterAppAccess(permissionPackageName, callingUid, callingUserId,
1220                 false /* filterUninstalled */)) {
1221             EventLog.writeEvent(0x534e4554, "186404356", callingUid, permName);
1222             return false;
1223         }
1224 
1225         if (isImmutablyRestrictedPermission && mContext.checkCallingOrSelfPermission(
1226                 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1227                 != PackageManager.PERMISSION_GRANTED) {
1228             throw new SecurityException("Cannot modify allowlisting of an immutably "
1229                     + "restricted permission: " + permName);
1230         }
1231 
1232         return true;
1233     }
1234 
1235     @Override
removeAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId)1236     public boolean removeAllowlistedRestrictedPermission(@NonNull String packageName,
1237             @NonNull String permName, @PackageManager.PermissionWhitelistFlags int flags,
1238             @UserIdInt int userId) {
1239         // Other argument checks are done in get/setAllowlistedRestrictedPermissions
1240         Objects.requireNonNull(permName);
1241 
1242         if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1243             return false;
1244         }
1245 
1246         final List<String> permissions =
1247                 getAllowlistedRestrictedPermissions(packageName, flags, userId);
1248         if (permissions != null && permissions.remove(permName)) {
1249             return setAllowlistedRestrictedPermissions(packageName, permissions,
1250                     flags, userId);
1251         }
1252         return false;
1253     }
1254 
setAllowlistedRestrictedPermissions(@onNull String packageName, @Nullable List<String> permissions, @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId)1255     private boolean setAllowlistedRestrictedPermissions(@NonNull String packageName,
1256             @Nullable List<String> permissions, @PackageManager.PermissionWhitelistFlags int flags,
1257             @UserIdInt int userId) {
1258         Objects.requireNonNull(packageName);
1259         Preconditions.checkFlagsArgument(flags,
1260                 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1261                         | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1262                         | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1263         Preconditions.checkArgument(Integer.bitCount(flags) == 1);
1264         Preconditions.checkArgumentNonNegative(userId, null);
1265 
1266         if (UserHandle.getCallingUserId() != userId) {
1267             mContext.enforceCallingOrSelfPermission(
1268                     Manifest.permission.INTERACT_ACROSS_USERS,
1269                     "setAllowlistedRestrictedPermissions for user " + userId);
1270         }
1271 
1272         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1273         if (pkg == null) {
1274             return false;
1275         }
1276 
1277         final int callingUid = Binder.getCallingUid();
1278         if (mPackageManagerInt.filterAppAccess(packageName, callingUid,
1279                 UserHandle.getCallingUserId(), false /* filterUninstalled */)) {
1280             return false;
1281         }
1282 
1283         final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1284                 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1285                         == PackageManager.PERMISSION_GRANTED;
1286         final boolean isCallerInstallerOnRecord =
1287                 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1288 
1289         if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0 && !isCallerPrivileged) {
1290             throw new SecurityException("Modifying system allowlist requires "
1291                     + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1292         }
1293 
1294         if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1295             if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1296                 throw new SecurityException("Modifying upgrade allowlist requires"
1297                         + " being installer on record or "
1298                         + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1299             }
1300             final List<String> allowlistedPermissions =
1301                     getAllowlistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
1302             if (permissions == null || permissions.isEmpty()) {
1303                 if (allowlistedPermissions == null || allowlistedPermissions.isEmpty()) {
1304                     return true;
1305                 }
1306             } else {
1307                 // Only the system can add and remove while the installer can only remove.
1308                 final int permissionCount = permissions.size();
1309                 for (int i = 0; i < permissionCount; i++) {
1310                     if ((allowlistedPermissions == null
1311                             || !allowlistedPermissions.contains(permissions.get(i)))
1312                             && !isCallerPrivileged) {
1313                         throw new SecurityException("Adding to upgrade allowlist requires"
1314                                 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1315                     }
1316                 }
1317             }
1318         }
1319 
1320         if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1321             if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1322                 throw new SecurityException("Modifying installer allowlist requires"
1323                         + " being installer on record or "
1324                         + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1325             }
1326         }
1327 
1328         final long identity = Binder.clearCallingIdentity();
1329         try {
1330             setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId);
1331         } finally {
1332             Binder.restoreCallingIdentity(identity);
1333         }
1334 
1335         return true;
1336     }
1337 
1338     @Override
grantRuntimePermission(String packageName, String permName, String deviceId, int userId)1339     public void grantRuntimePermission(String packageName, String permName, String deviceId,
1340             int userId) {
1341         final int callingUid = Binder.getCallingUid();
1342         final boolean overridePolicy =
1343                 checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY)
1344                         == PackageManager.PERMISSION_GRANTED;
1345 
1346         grantRuntimePermissionInternal(packageName, permName, overridePolicy,
1347                 callingUid, userId, mDefaultPermissionCallback);
1348     }
1349 
grantRuntimePermissionInternal(String packageName, String permName, boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback)1350     private void grantRuntimePermissionInternal(String packageName, String permName,
1351             boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1352         if (PermissionManager.DEBUG_TRACE_GRANTS
1353                 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
1354             Log.i(PermissionManager.LOG_TAG_TRACE_GRANTS, "System is granting " + packageName + " "
1355                     + permName + " for user " + userId + " on behalf of uid " + callingUid
1356                     + " " + mPackageManagerInt.getNameForUid(callingUid),
1357                     new RuntimeException());
1358         }
1359         if (!mUserManagerInt.exists(userId)) {
1360             Log.e(TAG, "No such user:" + userId);
1361             return;
1362         }
1363 
1364         mContext.enforceCallingOrSelfPermission(
1365                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1366                 "grantRuntimePermission");
1367 
1368         enforceCrossUserPermission(callingUid, userId,
1369                 true,  // requireFullPermission
1370                 true,  // checkShell
1371                 "grantRuntimePermission");
1372 
1373         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1374         final PackageStateInternal ps = mPackageManagerInt.getPackageStateInternal(packageName);
1375         if (pkg == null || ps == null) {
1376             Log.e(TAG, "Unknown package: " + packageName);
1377             return;
1378         }
1379         if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
1380                 false /* filterUninstalled */)) {
1381             throw new IllegalArgumentException("Unknown package: " + packageName);
1382         }
1383 
1384         final boolean isRolePermission;
1385         final boolean isSoftRestrictedPermission;
1386         synchronized (mLock) {
1387             final Permission permission = mRegistry.getPermission(permName);
1388             if (permission == null) {
1389                 throw new IllegalArgumentException("Unknown permission: " + permName);
1390             }
1391             isRolePermission = permission.isRole();
1392             isSoftRestrictedPermission = permission.isSoftRestricted();
1393         }
1394         final boolean mayGrantRolePermission = isRolePermission
1395                 && mayManageRolePermission(callingUid);
1396         final boolean mayGrantSoftRestrictedPermission = isSoftRestrictedPermission
1397                 && SoftRestrictedPermissionPolicy.forPermission(mContext,
1398                         AndroidPackageUtils.generateAppInfoWithoutState(pkg), pkg,
1399                         UserHandle.of(userId), permName)
1400                         .mayGrantPermission();
1401 
1402         final boolean isRuntimePermission;
1403         final boolean permissionHasGids;
1404         synchronized (mLock) {
1405             final Permission bp = mRegistry.getPermission(permName);
1406             if (bp == null) {
1407                 throw new IllegalArgumentException("Unknown permission: " + permName);
1408             }
1409 
1410             isRuntimePermission = bp.isRuntime();
1411             permissionHasGids = bp.hasGids();
1412             if (isRuntimePermission || bp.isDevelopment()) {
1413                 // Good.
1414             } else if (bp.isRole()) {
1415                 if (!mayGrantRolePermission) {
1416                     throw new SecurityException("Permission " + permName + " is managed by role");
1417                 }
1418             } else {
1419                 throw new SecurityException("Permission " + permName + " requested by "
1420                         + pkg.getPackageName() + " is not a changeable permission type");
1421             }
1422 
1423             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
1424             if (uidState == null) {
1425                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
1426                         + userId);
1427                 return;
1428             }
1429 
1430             if (!(uidState.hasPermissionState(permName)
1431                     || pkg.getRequestedPermissions().contains(permName))) {
1432                 throw new SecurityException("Package " + pkg.getPackageName()
1433                         + " has not requested permission " + permName);
1434             }
1435 
1436             // If a permission review is required for legacy apps we represent
1437             // their permissions as always granted runtime ones since we need
1438             // to keep the review required permission flag per user while an
1439             // install permission's state is shared across all users.
1440             if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
1441                 return;
1442             }
1443 
1444             final int flags = uidState.getPermissionFlags(permName);
1445             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1446                 Log.e(TAG, "Cannot grant system fixed permission "
1447                         + permName + " for package " + packageName);
1448                 return;
1449             }
1450             if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1451                 Log.e(TAG, "Cannot grant policy fixed permission "
1452                         + permName + " for package " + packageName);
1453                 return;
1454             }
1455 
1456             if (bp.isHardRestricted()
1457                     && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1458                 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
1459                         + permName + " for package " + packageName);
1460                 return;
1461             }
1462 
1463             if (bp.isSoftRestricted() && !mayGrantSoftRestrictedPermission) {
1464                 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
1465                         + packageName);
1466                 return;
1467             }
1468 
1469             if (bp.isDevelopment() || bp.isRole()) {
1470                 // Development permissions must be handled specially, since they are not
1471                 // normal runtime permissions.  For now they apply to all users.
1472                 // TODO(zhanghai): We are breaking the behavior above by making all permission state
1473                 //  per-user. It isn't documented behavior and relatively rarely used anyway.
1474                 if (!uidState.grantPermission(bp)) {
1475                     return;
1476                 }
1477             } else {
1478                 if (ps.getUserStateOrDefault(userId).isInstantApp() && !bp.isInstant()) {
1479                     throw new SecurityException("Cannot grant non-ephemeral permission " + permName
1480                             + " for package " + packageName);
1481                 }
1482 
1483                 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
1484                     Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1485                     return;
1486                 }
1487 
1488                 if (!uidState.grantPermission(bp)) {
1489                     return;
1490                 }
1491             }
1492         }
1493 
1494         if (isRuntimePermission) {
1495             logPermission(MetricsProto.MetricsEvent.ACTION_PERMISSION_GRANTED,
1496                     permName, packageName);
1497         }
1498 
1499         final int uid = UserHandle.getUid(userId, pkg.getUid());
1500         if (callback != null) {
1501             if (isRuntimePermission) {
1502                 callback.onPermissionGranted(uid, userId);
1503             } else {
1504                 callback.onInstallPermissionGranted();
1505             }
1506             if (permissionHasGids) {
1507                 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
1508             }
1509         }
1510     }
1511 
1512     @Override
revokeRuntimePermission(String packageName, String permName, String deviceId, int userId, String reason)1513     public void revokeRuntimePermission(String packageName, String permName, String deviceId,
1514             int userId, String reason) {
1515         final int callingUid = Binder.getCallingUid();
1516         final boolean overridePolicy =
1517                 checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY,
1518                         VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)
1519                         == PackageManager.PERMISSION_GRANTED;
1520 
1521         revokeRuntimePermissionInternal(packageName, permName, overridePolicy, callingUid, userId,
1522                 reason, mDefaultPermissionCallback);
1523     }
1524 
1525     @Override
revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId)1526     public void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId) {
1527         final int callingUid = Binder.getCallingUid();
1528         final boolean overridePolicy =
1529                 checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY)
1530                         == PackageManager.PERMISSION_GRANTED;
1531         mContext.enforceCallingPermission(
1532                 android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL, "");
1533         revokeRuntimePermissionInternal(packageName, Manifest.permission.POST_NOTIFICATIONS,
1534                 overridePolicy, true, callingUid, userId,
1535                 SKIP_KILL_APP_REASON_NOTIFICATION_TEST, mDefaultPermissionCallback);
1536     }
1537 
revokeRuntimePermissionInternal(String packageName, String permName, boolean overridePolicy, int callingUid, final int userId, String reason, PermissionCallback callback)1538     private void revokeRuntimePermissionInternal(String packageName, String permName,
1539             boolean overridePolicy, int callingUid, final int userId,
1540             String reason, PermissionCallback callback) {
1541         revokeRuntimePermissionInternal(packageName, permName, overridePolicy, false, callingUid,
1542                 userId, reason, callback);
1543     }
1544 
revokeRuntimePermissionInternal(String packageName, String permName, boolean overridePolicy, boolean overrideKill, int callingUid, final int userId, String reason, PermissionCallback callback)1545     private void revokeRuntimePermissionInternal(String packageName, String permName,
1546             boolean overridePolicy, boolean overrideKill, int callingUid, final int userId,
1547             String reason, PermissionCallback callback) {
1548         if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
1549                 && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
1550             Log.i(TAG, "System is revoking " + packageName + " "
1551                             + permName + " for user " + userId + " on behalf of uid " + callingUid
1552                             + " " + mPackageManagerInt.getNameForUid(callingUid),
1553                     new RuntimeException());
1554         }
1555         if (!mUserManagerInt.exists(userId)) {
1556             Log.e(TAG, "No such user:" + userId);
1557             return;
1558         }
1559 
1560         mContext.enforceCallingOrSelfPermission(
1561                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1562                 "revokeRuntimePermission");
1563 
1564         enforceCrossUserPermission(callingUid, userId,
1565                 true,  // requireFullPermission
1566                 true,  // checkShell
1567                 "revokeRuntimePermission");
1568 
1569         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1570         if (pkg == null) {
1571             Log.e(TAG, "Unknown package: " + packageName);
1572             return;
1573         }
1574         if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
1575                 false /* filterUninstalled */)) {
1576             throw new IllegalArgumentException("Unknown package: " + packageName);
1577         }
1578 
1579         final boolean isRolePermission;
1580         synchronized (mLock) {
1581             final Permission permission = mRegistry.getPermission(permName);
1582             if (permission == null) {
1583                 throw new IllegalArgumentException("Unknown permission: " + permName);
1584             }
1585             isRolePermission = permission.isRole();
1586         }
1587         final boolean mayRevokeRolePermission = isRolePermission
1588                 // Allow ourselves to revoke role permissions due to definition changes.
1589                 && (callingUid == Process.myUid() || mayManageRolePermission(callingUid));
1590 
1591         final boolean isRuntimePermission;
1592         synchronized (mLock) {
1593             final Permission bp = mRegistry.getPermission(permName);
1594             if (bp == null) {
1595                 throw new IllegalArgumentException("Unknown permission: " + permName);
1596             }
1597 
1598             isRuntimePermission = bp.isRuntime();
1599             if (isRuntimePermission || bp.isDevelopment()) {
1600                 // Good.
1601             } else if (bp.isRole()) {
1602                 if (!mayRevokeRolePermission) {
1603                     throw new SecurityException("Permission " + permName + " is managed by role");
1604                 }
1605             } else {
1606                 throw new SecurityException("Permission " + permName + " requested by "
1607                         + pkg.getPackageName() + " is not a changeable permission type");
1608             }
1609 
1610             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
1611             if (uidState == null) {
1612                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
1613                         + userId);
1614                 return;
1615             }
1616 
1617             if (!(uidState.hasPermissionState(permName)
1618                     || pkg.getRequestedPermissions().contains(permName))) {
1619                 throw new SecurityException("Package " + pkg.getPackageName()
1620                         + " has not requested permission " + permName);
1621             }
1622 
1623             // If a permission review is required for legacy apps we represent
1624             // their permissions as always granted runtime ones since we need
1625             // to keep the review required permission flag per user while an
1626             // install permission's state is shared across all users.
1627             if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
1628                 return;
1629             }
1630 
1631             final int flags = uidState.getPermissionFlags(permName);
1632             // Only the system may revoke SYSTEM_FIXED permissions.
1633             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1634                     && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1635                 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1636                         + permName + " for package " + packageName);
1637             }
1638             if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1639                 throw new SecurityException("Cannot revoke policy fixed permission "
1640                         + permName + " for package " + packageName);
1641             }
1642 
1643             // Development permissions must be handled specially, since they are not
1644             // normal runtime permissions.  For now they apply to all users.
1645             // TODO(zhanghai): We are breaking the behavior above by making all permission state
1646             //  per-user. It isn't documented behavior and relatively rarely used anyway.
1647             if (!uidState.revokePermission(bp)) {
1648                 return;
1649             }
1650         }
1651 
1652         if (isRuntimePermission) {
1653             logPermission(MetricsProto.MetricsEvent.ACTION_PERMISSION_REVOKED,
1654                     permName, packageName);
1655         }
1656 
1657         if (callback != null) {
1658             if (isRuntimePermission) {
1659                 callback.onPermissionRevoked(UserHandle.getUid(userId, pkg.getUid()), userId,
1660                         reason, overrideKill, permName);
1661             } else {
1662                 mDefaultPermissionCallback.onInstallPermissionRevoked();
1663             }
1664         }
1665     }
1666 
mayManageRolePermission(int uid)1667     private boolean mayManageRolePermission(int uid) {
1668         final PackageManager packageManager = mContext.getPackageManager();
1669         final String[] packageNames = packageManager.getPackagesForUid(uid);
1670         if (packageNames == null) {
1671             return false;
1672         }
1673         final String permissionControllerPackageName =
1674                 packageManager.getPermissionControllerPackageName();
1675         return Arrays.asList(packageNames).contains(permissionControllerPackageName);
1676     }
1677 
1678     /**
1679      * Reverts user permission state changes (permissions and flags).
1680      *
1681      * @param filterPkg The package for which to reset, or {@code null} for all packages.
1682      * @param userId The device user for which to do a reset.
1683      */
resetRuntimePermissionsInternal(@ullable AndroidPackage filterPkg, @UserIdInt int userId)1684     private void resetRuntimePermissionsInternal(@Nullable AndroidPackage filterPkg,
1685             @UserIdInt int userId) {
1686         // Delay and combine non-async permission callbacks
1687         final boolean[] permissionRemoved = new boolean[1];
1688         final ArraySet<Long> revokedPermissions = new ArraySet<>();
1689         final ArraySet<Integer> syncUpdatedUsers = new ArraySet<>();
1690         final ArraySet<Integer> asyncUpdatedUsers = new ArraySet<>();
1691 
1692         PermissionCallback delayingPermCallback = new PermissionCallback() {
1693             public void onGidsChanged(int appId, int userId) {
1694                 mDefaultPermissionCallback.onGidsChanged(appId, userId);
1695             }
1696 
1697             public void onPermissionChanged() {
1698                 mDefaultPermissionCallback.onPermissionChanged();
1699             }
1700 
1701             public void onPermissionGranted(int uid, int userId) {
1702                 mDefaultPermissionCallback.onPermissionGranted(uid, userId);
1703             }
1704 
1705             public void onInstallPermissionGranted() {
1706                 mDefaultPermissionCallback.onInstallPermissionGranted();
1707             }
1708 
1709             public void onPermissionRevoked(int uid, int userId, String reason,
1710                     boolean overrideKill, @Nullable String permissionName) {
1711                 revokedPermissions.add(IntPair.of(uid, userId));
1712 
1713                 syncUpdatedUsers.add(userId);
1714             }
1715 
1716             public void onInstallPermissionRevoked() {
1717                 mDefaultPermissionCallback.onInstallPermissionRevoked();
1718             }
1719 
1720             public void onPermissionUpdated(int[] userIds, boolean sync, int appId) {
1721                 mOnPermissionChangeListeners.onPermissionsChanged(appId);
1722                 for (int userId : userIds) {
1723                     if (sync) {
1724                         syncUpdatedUsers.add(userId);
1725                         asyncUpdatedUsers.remove(userId);
1726                     } else {
1727                         // Don't override sync=true by sync=false
1728                         if (syncUpdatedUsers.indexOf(userId) == -1) {
1729                             asyncUpdatedUsers.add(userId);
1730                         }
1731                     }
1732                 }
1733             }
1734 
1735             public void onPermissionRemoved() {
1736                 permissionRemoved[0] = true;
1737             }
1738 
1739             public void onInstallPermissionUpdated() {
1740                 mDefaultPermissionCallback.onInstallPermissionUpdated();
1741             }
1742         };
1743 
1744         if (filterPkg != null) {
1745             resetRuntimePermissionsInternal(filterPkg, userId, delayingPermCallback);
1746         } else {
1747             mPackageManagerInt.forEachPackage(pkg ->
1748                     resetRuntimePermissionsInternal(pkg, userId, delayingPermCallback));
1749         }
1750 
1751         // Execute delayed callbacks
1752         if (permissionRemoved[0]) {
1753             mDefaultPermissionCallback.onPermissionRemoved();
1754         }
1755 
1756         // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
1757         // kill uid while holding mPackages-lock
1758         if (!revokedPermissions.isEmpty()) {
1759             int numRevokedPermissions = revokedPermissions.size();
1760             for (int i = 0; i < numRevokedPermissions; i++) {
1761                 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
1762                 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
1763 
1764                 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
1765 
1766                 // Kill app later as we are holding mPackages
1767                 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
1768                         KILL_APP_REASON_PERMISSIONS_REVOKED));
1769             }
1770         }
1771 
1772         mPackageManagerInt.writePermissionSettings(ArrayUtils.convertToIntArray(syncUpdatedUsers),
1773                 false);
1774         mPackageManagerInt.writePermissionSettings(ArrayUtils.convertToIntArray(asyncUpdatedUsers),
1775                 true);
1776     }
1777 
resetRuntimePermissionsInternal(@onNull AndroidPackage pkg, @UserIdInt int userId, @NonNull PermissionCallback delayingPermCallback)1778     private void resetRuntimePermissionsInternal(@NonNull AndroidPackage pkg,
1779             @UserIdInt int userId, @NonNull PermissionCallback delayingPermCallback) {
1780         // These are flags that can change base on user actions.
1781         final int userSettableMask = FLAG_PERMISSION_USER_SET
1782                 | FLAG_PERMISSION_USER_FIXED
1783                 | FLAG_PERMISSION_REVOKED_COMPAT
1784                 | FLAG_PERMISSION_REVIEW_REQUIRED
1785                 | FLAG_PERMISSION_ONE_TIME
1786                 | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;
1787 
1788         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
1789                 | FLAG_PERMISSION_POLICY_FIXED;
1790 
1791         final String packageName = pkg.getPackageName();
1792         for (final String permName : pkg.getRequestedPermissions()) {
1793             if (mIsLeanback && NOTIFICATION_PERMISSIONS.contains(permName)) {
1794                 // Do not reset the Notification permissions on TV
1795                 continue;
1796             }
1797             final boolean isRuntimePermission;
1798             synchronized (mLock) {
1799                 final Permission permission = mRegistry.getPermission(permName);
1800                 if (permission == null) {
1801                     continue;
1802                 }
1803 
1804                 if (permission.isRemoved()) {
1805                     continue;
1806                 }
1807                 isRuntimePermission = permission.isRuntime();
1808             }
1809 
1810             // If shared user we just reset the state to which only this app contributed.
1811             final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
1812                     pkg.getPackageName(), userId);
1813             if (pkgNames.length > 0) {
1814                 boolean used = false;
1815                 for (String sharedPkgName : pkgNames) {
1816                     final AndroidPackage sharedPkg =
1817                             mPackageManagerInt.getPackage(sharedPkgName);
1818                     if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
1819                             && sharedPkg.getRequestedPermissions().contains(permName)) {
1820                         used = true;
1821                         break;
1822                     }
1823                 }
1824                 if (used) {
1825                     continue;
1826                 }
1827             }
1828 
1829             final int oldFlags =
1830                     getPermissionFlagsInternal(packageName, permName, Process.SYSTEM_UID, userId);
1831 
1832             // Always clear the user settable flags.
1833             // If permission review is enabled and this is a legacy app, mark the
1834             // permission as requiring a review as this is the initial state.
1835             final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
1836             final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
1837             final int flags = (targetSdk < Build.VERSION_CODES.M && isRuntimePermission)
1838                     ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
1839                     : 0;
1840 
1841             updatePermissionFlagsInternal(
1842                     packageName, permName, userSettableMask, flags, Process.SYSTEM_UID, userId,
1843                     false, delayingPermCallback);
1844 
1845             // Below is only runtime permission handling.
1846             if (!isRuntimePermission) {
1847                 continue;
1848             }
1849 
1850             // Never clobber system or policy.
1851             if ((oldFlags & policyOrSystemFlags) != 0) {
1852                 continue;
1853             }
1854 
1855             // If this permission was granted by default or role, make sure it is.
1856             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
1857                     || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0) {
1858                 // PermissionPolicyService will handle the app op for runtime permissions later.
1859                 grantRuntimePermissionInternal(packageName, permName, false,
1860                         Process.SYSTEM_UID, userId, delayingPermCallback);
1861             // In certain cases we should leave the state unchanged:
1862             // -- If permission review is enabled the permissions for a legacy apps
1863             // are represented as constantly granted runtime ones
1864             // -- If the permission was split from a non-runtime permission
1865             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
1866                     && !isPermissionSplitFromNonRuntime(permName, targetSdk)) {
1867                 // Otherwise, reset the permission.
1868                 revokeRuntimePermissionInternal(packageName, permName, false, Process.SYSTEM_UID,
1869                         userId, null, delayingPermCallback);
1870             }
1871         }
1872     }
1873 
1874     /**
1875      * Determine if the given permission should be treated as split from a
1876      * non-runtime permission for an application targeting the given SDK level.
1877      */
isPermissionSplitFromNonRuntime(String permName, int targetSdk)1878     private boolean isPermissionSplitFromNonRuntime(String permName, int targetSdk) {
1879         final List<PermissionManager.SplitPermissionInfo> splitPerms = getSplitPermissionInfos();
1880         final int size = splitPerms.size();
1881         for (int i = 0; i < size; i++) {
1882             final PermissionManager.SplitPermissionInfo splitPerm = splitPerms.get(i);
1883             if (targetSdk < splitPerm.getTargetSdk()
1884                     && splitPerm.getNewPermissions().contains(permName)) {
1885                 synchronized (mLock) {
1886                     final Permission perm =
1887                             mRegistry.getPermission(splitPerm.getSplitPermission());
1888                     return perm != null && !perm.isRuntime();
1889                 }
1890             }
1891         }
1892         return false;
1893     }
1894 
1895     /**
1896      * This change makes it so that apps are told to show rationale for asking for background
1897      * location access every time they request.
1898      */
1899     @ChangeId
1900     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
1901     private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L;
1902 
1903     @Override
shouldShowRequestPermissionRationale(String packageName, String permName, String deviceId, @UserIdInt int userId)1904     public boolean shouldShowRequestPermissionRationale(String packageName, String permName,
1905             String deviceId, @UserIdInt int userId) {
1906         final int callingUid = Binder.getCallingUid();
1907         if (UserHandle.getCallingUserId() != userId) {
1908             mContext.enforceCallingPermission(
1909                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1910                     "canShowRequestPermissionRationale for user " + userId);
1911         }
1912 
1913         final int uid =
1914                 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
1915         if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
1916             return false;
1917         }
1918 
1919         if (checkPermission(packageName, permName, userId) == PackageManager.PERMISSION_GRANTED) {
1920             return false;
1921         }
1922 
1923         final int flags;
1924 
1925         final long identity = Binder.clearCallingIdentity();
1926         try {
1927             flags = getPermissionFlagsInternal(packageName, permName, callingUid, userId);
1928         } finally {
1929             Binder.restoreCallingIdentity(identity);
1930         }
1931 
1932         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1933                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
1934                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
1935 
1936         if ((flags & fixedFlags) != 0) {
1937             return false;
1938         }
1939 
1940         synchronized (mLock) {
1941             final Permission permission = mRegistry.getPermission(permName);
1942             if (permission == null) {
1943                 return false;
1944             }
1945             if (permission.isHardRestricted()
1946                     && (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1947                 return false;
1948             }
1949         }
1950 
1951         final long token = Binder.clearCallingIdentity();
1952         try {
1953             if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
1954                     && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID,
1955                     packageName, userId)) {
1956                 return true;
1957             }
1958         } catch (RemoteException e) {
1959             Log.e(TAG, "Unable to check if compatibility change is enabled.", e);
1960         } finally {
1961             Binder.restoreCallingIdentity(token);
1962         }
1963 
1964         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
1965     }
1966 
1967     @Override
isPermissionRevokedByPolicy(String packageName, String permName, String deviceId, int userId)1968     public boolean isPermissionRevokedByPolicy(String packageName, String permName, String deviceId,
1969             int userId) {
1970         if (UserHandle.getCallingUserId() != userId) {
1971             mContext.enforceCallingPermission(
1972                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1973                     "isPermissionRevokedByPolicy for user " + userId);
1974         }
1975 
1976         if (checkPermission(packageName, permName, userId) == PackageManager.PERMISSION_GRANTED) {
1977             return false;
1978         }
1979 
1980         final int callingUid = Binder.getCallingUid();
1981         if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
1982                 false /* filterUninstalled */)) {
1983             return false;
1984         }
1985 
1986         final long identity = Binder.clearCallingIdentity();
1987         try {
1988             final int flags = getPermissionFlagsInternal(packageName, permName, callingUid, userId);
1989             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
1990         } finally {
1991             Binder.restoreCallingIdentity(identity);
1992         }
1993     }
1994 
1995     /**
1996      * Get the state of the runtime permissions as xml file.
1997      *
1998      * <p>Can not be called on main thread.
1999      *
2000      * @param userId The user ID the data should be extracted for
2001      *
2002      * @return The state as a xml file
2003      */
2004     @Nullable
2005     @Override
backupRuntimePermissions(@serIdInt int userId)2006     public byte[] backupRuntimePermissions(@UserIdInt int userId) {
2007         Preconditions.checkArgumentNonNegative(userId, "userId");
2008         CompletableFuture<byte[]> backup = new CompletableFuture<>();
2009         mPermissionControllerManager.getRuntimePermissionBackup(UserHandle.of(userId),
2010                 PermissionThread.getExecutor(), backup::complete);
2011 
2012         try {
2013             return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
2014         } catch (InterruptedException | ExecutionException | TimeoutException e) {
2015             Slog.e(TAG, "Cannot create permission backup for user " + userId, e);
2016             return null;
2017         }
2018     }
2019 
2020     /**
2021      * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
2022      *
2023      * <p>If not all state can be restored, the un-appliable state will be delayed and can be
2024      * applied via {@link #restoreDelayedRuntimePermissions}.
2025      *
2026      * @param backup The state as an xml file
2027      * @param userId The user ID the data should be restored for
2028      */
2029     @Override
restoreRuntimePermissions(@onNull byte[] backup, @UserIdInt int userId)2030     public void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId) {
2031         Objects.requireNonNull(backup, "backup");
2032         Preconditions.checkArgumentNonNegative(userId, "userId");
2033         synchronized (mLock) {
2034             mHasNoDelayedPermBackup.delete(userId);
2035         }
2036         mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup,
2037                 UserHandle.of(userId));
2038     }
2039 
2040     /**
2041      * Try to apply permission backup that was previously not applied.
2042      *
2043      * <p>Can not be called on main thread.
2044      *
2045      * @param packageName The package that is newly installed
2046      * @param userId The user ID the package is installed for
2047      *
2048      * @see #restoreRuntimePermissions
2049      */
2050     @Override
restoreDelayedRuntimePermissions(@onNull String packageName, @UserIdInt int userId)2051     public void restoreDelayedRuntimePermissions(@NonNull String packageName,
2052             @UserIdInt int userId) {
2053         Objects.requireNonNull(packageName, "packageName");
2054         Preconditions.checkArgumentNonNegative(userId, "userId");
2055         synchronized (mLock) {
2056             if (mHasNoDelayedPermBackup.get(userId, false)) {
2057                 return;
2058             }
2059         }
2060         mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName,
2061                 UserHandle.of(userId), PermissionThread.getExecutor(), (hasMoreBackup) -> {
2062                     if (hasMoreBackup) {
2063                         return;
2064                     }
2065                     synchronized (mLock) {
2066                         mHasNoDelayedPermBackup.put(userId, true);
2067                     }
2068                 });
2069     }
2070 
2071     /**
2072      * If the app is updated, and has scoped storage permissions, then it is possible that the
2073      * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
2074      * @param newPackage The new package that was installed
2075      * @param oldPackage The old package that was updated
2076      */
revokeStoragePermissionsIfScopeExpandedInternal( @onNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage)2077     private void revokeStoragePermissionsIfScopeExpandedInternal(
2078             @NonNull AndroidPackage newPackage,
2079             @NonNull AndroidPackage oldPackage) {
2080         boolean downgradedSdk = oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q
2081                 && newPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q;
2082         boolean upgradedSdk = oldPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q
2083                 && newPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q;
2084         boolean newlyRequestsLegacy = !upgradedSdk && !oldPackage.isRequestLegacyExternalStorage()
2085                 && newPackage.isRequestLegacyExternalStorage();
2086 
2087         if (!newlyRequestsLegacy && !downgradedSdk) {
2088             return;
2089         }
2090 
2091         final int callingUid = Binder.getCallingUid();
2092         for (int userId: getAllUserIds()) {
2093             for (final String permName : newPackage.getRequestedPermissions()) {
2094                 PermissionInfo permInfo = getPermissionInfo(permName, 0,
2095                         newPackage.getPackageName());
2096                 if (permInfo == null) {
2097                     continue;
2098                 }
2099                 boolean isStorageOrMedia = STORAGE_PERMISSIONS.contains(permInfo.name)
2100                         || READ_MEDIA_AURAL_PERMISSIONS.contains(permInfo.name)
2101                         || READ_MEDIA_VISUAL_PERMISSIONS.contains(permInfo.name);
2102                 if (!isStorageOrMedia) {
2103                     continue;
2104                 }
2105                 boolean isSystemOrPolicyFixed = (getPermissionFlags(newPackage.getPackageName(),
2106                         permInfo.name, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId)
2107                         & (FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_POLICY_FIXED)) != 0;
2108                 if (isSystemOrPolicyFixed) {
2109                     continue;
2110                 }
2111 
2112                 EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(),
2113                         "Revoking permission " + permInfo.name + " from package "
2114                                 + newPackage.getPackageName() + " as either the sdk downgraded "
2115                                 + downgradedSdk + " or newly requested legacy full storage "
2116                                 + newlyRequestsLegacy);
2117 
2118                 try {
2119                     revokeRuntimePermissionInternal(newPackage.getPackageName(), permInfo.name,
2120                             false, callingUid, userId, null, mDefaultPermissionCallback);
2121                 } catch (IllegalStateException | SecurityException e) {
2122                     Log.e(TAG, "unable to revoke " + permInfo.name + " for "
2123                             + newPackage.getPackageName() + " user " + userId, e);
2124                 }
2125             }
2126         }
2127 
2128     }
2129 
2130     /**
2131      * If the package was below api 23, got the SYSTEM_ALERT_WINDOW permission automatically, and
2132      * then updated past api 23, and the app does not satisfy any of the other SAW permission flags,
2133      * the permission should be revoked.
2134      *
2135      * @param newPackage The new package that was installed
2136      * @param oldPackage The old package that was updated
2137      */
2138     private void revokeSystemAlertWindowIfUpgradedPast23(
2139             @NonNull AndroidPackage newPackage,
2140             @NonNull AndroidPackage oldPackage) {
2141         if (oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.M
2142                 || newPackage.getTargetSdkVersion() < Build.VERSION_CODES.M
2143                 || !newPackage.getRequestedPermissions()
2144                 .contains(Manifest.permission.SYSTEM_ALERT_WINDOW)) {
2145             return;
2146         }
2147 
2148         Permission saw;
2149         synchronized (mLock) {
2150             saw = mRegistry.getPermission(Manifest.permission.SYSTEM_ALERT_WINDOW);
2151         }
2152         final PackageStateInternal ps =
2153                 mPackageManagerInt.getPackageStateInternal(newPackage.getPackageName());
2154         if (shouldGrantPermissionByProtectionFlags(newPackage, ps, saw, new ArraySet<>())
2155                 || shouldGrantPermissionBySignature(newPackage, saw)) {
2156             return;
2157         }
2158         for (int userId : getAllUserIds()) {
2159             try {
2160                 revokePermissionFromPackageForUser(newPackage.getPackageName(),
2161                         Manifest.permission.SYSTEM_ALERT_WINDOW, false, userId,
2162                         mDefaultPermissionCallback);
2163             } catch (IllegalStateException | SecurityException e) {
2164                 Log.e(TAG, "unable to revoke SYSTEM_ALERT_WINDOW for "
2165                         + newPackage.getPackageName() + " user " + userId, e);
2166             }
2167         }
2168     }
2169 
2170     /**
2171      * We might auto-grant permissions if any permission of the group is already granted. Hence if
2172      * the group of a granted permission changes we need to revoke it to avoid having permissions of
2173      * the new group auto-granted.
2174      *
2175      * @param newPackage The new package that was installed
2176      * @param oldPackage The old package that was updated
2177      */
2178     private void revokeRuntimePermissionsIfGroupChangedInternal(@NonNull AndroidPackage newPackage,
2179             @NonNull AndroidPackage oldPackage) {
2180         final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
2181         final ArrayMap<String, String> oldPermissionNameToGroupName =
2182                 new ArrayMap<>(numOldPackagePermissions);
2183 
2184         for (int i = 0; i < numOldPackagePermissions; i++) {
2185             final ParsedPermission permission = oldPackage.getPermissions().get(i);
2186 
2187             if (permission.getParsedPermissionGroup() != null) {
2188                 oldPermissionNameToGroupName.put(permission.getName(),
2189                         permission.getParsedPermissionGroup().getName());
2190             }
2191         }
2192 
2193         final int callingUid = Binder.getCallingUid();
2194         final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
2195         for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
2196                 newPermissionNum++) {
2197             final ParsedPermission newPermission =
2198                     newPackage.getPermissions().get(newPermissionNum);
2199             final int newProtection = ParsedPermissionUtils.getProtection(newPermission);
2200 
2201             if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
2202                 final String permissionName = newPermission.getName();
2203                 final String newPermissionGroupName =
2204                         newPermission.getParsedPermissionGroup() == null
2205                                 ? null : newPermission.getParsedPermissionGroup().getName();
2206                 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
2207                         permissionName);
2208 
2209                 if (newPermissionGroupName != null
2210                         && !newPermissionGroupName.equals(oldPermissionGroupName)) {
2211                     final int[] userIds = mUserManagerInt.getUserIds();
2212                     mPackageManagerInt.forEachPackage(pkg -> {
2213                         final String packageName = pkg.getPackageName();
2214                         for (final int userId : userIds) {
2215                             final int permissionState =
2216                                     checkPermission(packageName, permissionName, userId);
2217                             if (permissionState == PackageManager.PERMISSION_GRANTED) {
2218                                 EventLog.writeEvent(0x534e4554, "72710897",
2219                                         newPackage.getUid(),
2220                                         "Revoking permission " + permissionName +
2221                                         " from package " + packageName +
2222                                         " as the group changed from " + oldPermissionGroupName +
2223                                         " to " + newPermissionGroupName);
2224 
2225                                 try {
2226                                     revokeRuntimePermissionInternal(packageName, permissionName,
2227                                             false, callingUid, userId, null,
2228                                             mDefaultPermissionCallback);
2229                                 } catch (IllegalArgumentException e) {
2230                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
2231                                             + packageName, e);
2232                                 }
2233                             }
2234                         }
2235                     });
2236                 }
2237             }
2238         }
2239     }
2240 
2241     /**
2242      * If permissions are upgraded to runtime, or their owner changes to the system, then any
2243      * granted permissions must be revoked.
2244      *
2245      * @param permissionsToRevoke A list of permission names to revoke
2246      */
2247     private void revokeRuntimePermissionsIfPermissionDefinitionChangedInternal(
2248             @NonNull List<String> permissionsToRevoke) {
2249         final int[] userIds = mUserManagerInt.getUserIds();
2250         final int numPermissions = permissionsToRevoke.size();
2251         final int callingUid = Binder.getCallingUid();
2252 
2253         for (int permNum = 0; permNum < numPermissions; permNum++) {
2254             final String permName = permissionsToRevoke.get(permNum);
2255             final boolean isInternalPermission;
2256             synchronized (mLock) {
2257                 final Permission bp = mRegistry.getPermission(permName);
2258                 if (bp == null || !(bp.isInternal() || bp.isRuntime())) {
2259                     continue;
2260                 }
2261                 isInternalPermission = bp.isInternal();
2262             }
2263             mPackageManagerInt.forEachPackage(pkg -> {
2264                 final String packageName = pkg.getPackageName();
2265                 final int appId = pkg.getUid();
2266                 if (appId < Process.FIRST_APPLICATION_UID) {
2267                     // do not revoke from system apps
2268                     return;
2269                 }
2270                 for (final int userId : userIds) {
2271                     final int permissionState = checkPermission(packageName, permName,
2272                             userId);
2273                     final int flags = getPermissionFlags(packageName, permName,
2274                             VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
2275                     final int flagMask = FLAG_PERMISSION_SYSTEM_FIXED
2276                             | FLAG_PERMISSION_POLICY_FIXED
2277                             | FLAG_PERMISSION_GRANTED_BY_DEFAULT
2278                             | FLAG_PERMISSION_GRANTED_BY_ROLE;
2279                     if (permissionState == PackageManager.PERMISSION_GRANTED
2280                             && (flags & flagMask) == 0) {
2281                         final int uid = UserHandle.getUid(userId, appId);
2282                         if (isInternalPermission) {
2283                             EventLog.writeEvent(0x534e4554, "195338390", uid,
2284                                     "Revoking permission " + permName + " from package "
2285                                             + packageName + " due to definition change");
2286                         } else {
2287                             EventLog.writeEvent(0x534e4554, "154505240", uid,
2288                                     "Revoking permission " + permName + " from package "
2289                                             + packageName + " due to definition change");
2290                             EventLog.writeEvent(0x534e4554, "168319670", uid,
2291                                     "Revoking permission " + permName + " from package "
2292                                             + packageName + " due to definition change");
2293                         }
2294                         Slog.e(TAG, "Revoking permission " + permName + " from package "
2295                                 + packageName + " due to definition change");
2296                         try {
2297                             revokeRuntimePermissionInternal(packageName, permName,
2298                                     false, callingUid, userId, null, mDefaultPermissionCallback);
2299                         } catch (Exception e) {
2300                             Slog.e(TAG, "Could not revoke " + permName + " from "
2301                                     + packageName, e);
2302                         }
2303                     }
2304                 }
2305             });
2306         }
2307     }
2308 
2309     private List<String> addAllPermissionsInternal(@NonNull PackageState packageState,
2310                     @NonNull AndroidPackage pkg) {
2311         final int N = ArrayUtils.size(pkg.getPermissions());
2312         ArrayList<String> definitionChangedPermissions = new ArrayList<>();
2313         for (int i=0; i<N; i++) {
2314             ParsedPermission p = pkg.getPermissions().get(i);
2315 
2316             final PermissionInfo permissionInfo;
2317             final Permission oldPermission;
2318             synchronized (mLock) {
2319                 // Now that permission groups have a special meaning, we ignore permission
2320                 // groups for legacy apps to prevent unexpected behavior. In particular,
2321                 // permissions for one app being granted to someone just because they happen
2322                 // to be in a group defined by another app (before this had no implications).
2323                 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
2324                     ComponentMutateUtils.setParsedPermissionGroup(p,
2325                             mRegistry.getPermissionGroup(p.getGroup()));
2326                     // Warn for a permission in an unknown group.
2327                     if (DEBUG_PERMISSIONS
2328                             && p.getGroup() != null && p.getParsedPermissionGroup() == null) {
2329                         Slog.i(TAG, "Permission " + p.getName() + " from package "
2330                                 + p.getPackageName() + " in an unknown group " + p.getGroup());
2331                     }
2332                 }
2333 
2334                 permissionInfo = PackageInfoUtils.generatePermissionInfo(p,
2335                         PackageManager.GET_META_DATA);
2336                 oldPermission = p.isTree() ? mRegistry.getPermissionTree(p.getName())
2337                         : mRegistry.getPermission(p.getName());
2338             }
2339             // TODO(zhanghai): Maybe we should store whether a permission is owned by system inside
2340             //  itself.
2341             final boolean isOverridingSystemPermission = Permission.isOverridingSystemPermission(
2342                     oldPermission, permissionInfo, mPackageManagerInt);
2343             synchronized (mLock) {
2344                 final Permission permission = Permission.createOrUpdate(oldPermission,
2345                         permissionInfo, packageState, mRegistry.getPermissionTrees(),
2346                         isOverridingSystemPermission);
2347                 if (p.isTree()) {
2348                     mRegistry.addPermissionTree(permission);
2349                 } else {
2350                     mRegistry.addPermission(permission);
2351                 }
2352                 if (permission.isDefinitionChanged()) {
2353                     definitionChangedPermissions.add(p.getName());
2354                     permission.setDefinitionChanged(false);
2355                 }
2356             }
2357         }
2358         return definitionChangedPermissions;
2359     }
2360 
2361     private void addAllPermissionGroupsInternal(@NonNull AndroidPackage pkg) {
2362         synchronized (mLock) {
2363             final int N = ArrayUtils.size(pkg.getPermissionGroups());
2364             StringBuilder r = null;
2365             for (int i = 0; i < N; i++) {
2366                 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
2367                 final ParsedPermissionGroup cur = mRegistry.getPermissionGroup(pg.getName());
2368                 final String curPackageName = (cur == null) ? null : cur.getPackageName();
2369                 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
2370                 if (cur == null || isPackageUpdate) {
2371                     mRegistry.addPermissionGroup(pg);
2372                     if (DEBUG_PACKAGE_SCANNING) {
2373                         if (r == null) {
2374                             r = new StringBuilder(256);
2375                         } else {
2376                             r.append(' ');
2377                         }
2378                         if (isPackageUpdate) {
2379                             r.append("UPD:");
2380                         }
2381                         r.append(pg.getName());
2382                     }
2383                 } else {
2384                     Slog.w(TAG, "Permission group " + pg.getName() + " from package "
2385                             + pg.getPackageName() + " ignored: original from "
2386                             + cur.getPackageName());
2387                     if (DEBUG_PACKAGE_SCANNING) {
2388                         if (r == null) {
2389                             r = new StringBuilder(256);
2390                         } else {
2391                             r.append(' ');
2392                         }
2393                         r.append("DUP:");
2394                         r.append(pg.getName());
2395                     }
2396                 }
2397             }
2398             if (r != null && DEBUG_PACKAGE_SCANNING) {
2399                 Log.d(TAG, "  Permission Groups: " + r);
2400             }
2401         }
2402     }
2403 
2404     private void removeAllPermissionsInternal(@NonNull AndroidPackage pkg) {
2405         synchronized (mLock) {
2406             int n = ArrayUtils.size(pkg.getPermissions());
2407             StringBuilder r = null;
2408             for (int i = 0; i < n; i++) {
2409                 ParsedPermission p = pkg.getPermissions().get(i);
2410                 Permission bp = mRegistry.getPermission(p.getName());
2411                 if (bp == null) {
2412                     bp = mRegistry.getPermissionTree(p.getName());
2413                 }
2414                 if (bp != null && bp.isPermission(p)) {
2415                     bp.setPermissionInfo(null);
2416                     if (DEBUG_REMOVE) {
2417                         if (r == null) {
2418                             r = new StringBuilder(256);
2419                         } else {
2420                             r.append(' ');
2421                         }
2422                         r.append(p.getName());
2423                     }
2424                 }
2425                 if (ParsedPermissionUtils.isAppOp(p)) {
2426                     // TODO(zhanghai): Should we just remove the entry for this permission directly?
2427                     mRegistry.removeAppOpPermissionPackage(p.getName(), pkg.getPackageName());
2428                 }
2429             }
2430             if (r != null) {
2431                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
2432             }
2433 
2434             r = null;
2435             for (final String permissionName : pkg.getRequestedPermissions()) {
2436                 final Permission permission = mRegistry.getPermission(permissionName);
2437                 if (permission != null && permission.isAppOp()) {
2438                     mRegistry.removeAppOpPermissionPackage(permissionName,
2439                             pkg.getPackageName());
2440                 }
2441             }
2442             if (r != null) {
2443                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
2444             }
2445         }
2446     }
2447 
2448     @Override
2449     public void onUserRemoved(@UserIdInt int userId) {
2450         Preconditions.checkArgumentNonNegative(userId, "userId");
2451         synchronized (mLock) {
2452             mState.removeUserState(userId);
2453         }
2454     }
2455 
2456     @NonNull
2457     private Set<String> getGrantedPermissionsInternal(@NonNull String packageName,
2458             @UserIdInt int userId) {
2459         final PackageStateInternal ps = mPackageManagerInt.getPackageStateInternal(packageName);
2460         if (ps == null) {
2461             return Collections.emptySet();
2462         }
2463 
2464         synchronized (mLock) {
2465             final UidPermissionState uidState = getUidStateLocked(ps, userId);
2466             if (uidState == null) {
2467                 Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId);
2468                 return Collections.emptySet();
2469             }
2470             if (!ps.getUserStateOrDefault(userId).isInstantApp()) {
2471                 return uidState.getGrantedPermissions();
2472             } else {
2473                 // Install permission state is shared among all users, but instant app state is
2474                 // per-user, so we can only filter it here unless we make install permission state
2475                 // per-user as well.
2476                 final Set<String> instantPermissions =
2477                         new ArraySet<>(uidState.getGrantedPermissions());
2478                 instantPermissions.removeIf(permissionName -> {
2479                     Permission permission = mRegistry.getPermission(permissionName);
2480                     if (permission == null) {
2481                         return true;
2482                     }
2483                     if (!permission.isInstant()) {
2484                         EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId,
2485                                 ps.getAppId()), permissionName);
2486                         return true;
2487                     }
2488                     return false;
2489                 });
2490                 return instantPermissions;
2491             }
2492         }
2493     }
2494 
2495     @NonNull
2496     private int[] getPermissionGidsInternal(@NonNull String permissionName, @UserIdInt int userId) {
2497         synchronized (mLock) {
2498             Permission permission = mRegistry.getPermission(permissionName);
2499             if (permission == null) {
2500                 return EmptyArray.INT;
2501             }
2502             return permission.computeGids(userId);
2503         }
2504     }
2505 
2506     /**
2507      * Restore the permission state for a package.
2508      *
2509      * <ul>
2510      *     <li>During boot the state gets restored from the disk</li>
2511      *     <li>During app update the state gets restored from the last version of the app</li>
2512      * </ul>
2513      *
2514      * @param pkg the package the permissions belong to
2515      * @param replace if the package is getting replaced (this might change the requested
2516      *                permissions of this package)
2517      * @param changingPackageName the name of the package that is changing
2518      * @param callback Result call back
2519      * @param filterUserId If not {@link UserHandle.USER_ALL}, only restore the permission state for
2520      *                     this particular user
2521      */
2522     private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
2523             @Nullable String changingPackageName, @Nullable PermissionCallback callback,
2524             @UserIdInt int filterUserId) {
2525         // IMPORTANT: There are two types of permissions: install and runtime.
2526         // Install time permissions are granted when the app is installed to
2527         // all device users and users added in the future. Runtime permissions
2528         // are granted at runtime explicitly to specific users. Normal and signature
2529         // protected permissions are install time permissions. Dangerous permissions
2530         // are install permissions if the app's target SDK is Lollipop MR1 or older,
2531         // otherwise they are runtime permissions. This function does not manage
2532         // runtime permissions except for the case an app targeting Lollipop MR1
2533         // being upgraded to target a newer SDK, in which case dangerous permissions
2534         // are transformed from install time to runtime ones.
2535 
2536         final PackageStateInternal ps =
2537                 mPackageManagerInt.getPackageStateInternal(pkg.getPackageName());
2538         if (ps == null) {
2539             return;
2540         }
2541 
2542         final int[] userIds = filterUserId == UserHandle.USER_ALL ? getAllUserIds()
2543                 : new int[] { filterUserId };
2544 
2545         boolean installPermissionsChanged = false;
2546         boolean runtimePermissionsRevoked = false;
2547         int[] updatedUserIds = EMPTY_INT_ARRAY;
2548 
2549         ArraySet<String> isPrivilegedPermissionAllowlisted = null;
2550         ArraySet<String> shouldGrantSignaturePermission = null;
2551         ArraySet<String> shouldGrantInternalPermission = null;
2552         ArraySet<String> shouldGrantPrivilegedPermissionIfWasGranted = new ArraySet<>();
2553         final Set<String> requestedPermissions = pkg.getRequestedPermissions();
2554         for (final String permissionName : pkg.getRequestedPermissions()) {
2555             final Permission permission;
2556             synchronized (mLock) {
2557                 permission = mRegistry.getPermission(permissionName);
2558             }
2559             if (permission == null) {
2560                 continue;
2561             }
2562             if (permission.isPrivileged()
2563                     && checkPrivilegedPermissionAllowlist(pkg, ps, permission)) {
2564                 if (isPrivilegedPermissionAllowlisted == null) {
2565                     isPrivilegedPermissionAllowlisted = new ArraySet<>();
2566                 }
2567                 isPrivilegedPermissionAllowlisted.add(permissionName);
2568             }
2569             if (permission.isSignature() && (shouldGrantPermissionBySignature(pkg, permission)
2570                     || shouldGrantPermissionByProtectionFlags(pkg, ps, permission,
2571                             shouldGrantPrivilegedPermissionIfWasGranted))) {
2572                 if (shouldGrantSignaturePermission == null) {
2573                     shouldGrantSignaturePermission = new ArraySet<>();
2574                 }
2575                 shouldGrantSignaturePermission.add(permissionName);
2576             }
2577             if (permission.isInternal()
2578                     && shouldGrantPermissionByProtectionFlags(pkg, ps, permission,
2579                             shouldGrantPrivilegedPermissionIfWasGranted)) {
2580                 if (shouldGrantInternalPermission == null) {
2581                     shouldGrantInternalPermission = new ArraySet<>();
2582                 }
2583                 shouldGrantInternalPermission.add(permissionName);
2584             }
2585         }
2586 
2587         final SparseBooleanArray isPermissionPolicyInitialized = new SparseBooleanArray();
2588         if (mPermissionPolicyInternal != null) {
2589             for (final int userId : userIds) {
2590                 if (mPermissionPolicyInternal.isInitialized(userId)) {
2591                     isPermissionPolicyInitialized.put(userId, true);
2592                 }
2593             }
2594         }
2595 
2596         Collection<String> uidRequestedPermissions;
2597         Collection<String> uidImplicitPermissions;
2598         int uidTargetSdkVersion;
2599         if (!ps.hasSharedUser()) {
2600             uidRequestedPermissions = pkg.getRequestedPermissions();
2601             uidImplicitPermissions = pkg.getImplicitPermissions();
2602             uidTargetSdkVersion = pkg.getTargetSdkVersion();
2603         } else {
2604             uidRequestedPermissions = new ArraySet<>();
2605             uidImplicitPermissions = new ArraySet<>();
2606             uidTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
2607             final ArraySet<PackageStateInternal> packages =
2608                     mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId());
2609             int packagesSize = packages.size();
2610             for (int i = 0; i < packagesSize; i++) {
2611                 AndroidPackage sharedUserPackage =
2612                         packages.valueAt(i).getAndroidPackage();
2613                 if (sharedUserPackage == null) {
2614                     continue;
2615                 }
2616                 uidRequestedPermissions.addAll(
2617                         sharedUserPackage.getRequestedPermissions());
2618                 uidImplicitPermissions.addAll(
2619                         sharedUserPackage.getImplicitPermissions());
2620                 uidTargetSdkVersion = Math.min(uidTargetSdkVersion,
2621                         sharedUserPackage.getTargetSdkVersion());
2622             }
2623         }
2624 
2625         synchronized (mLock) {
2626             for (final int userId : userIds) {
2627                 final UserPermissionState userState = mState.getOrCreateUserState(userId);
2628                 final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId());
2629 
2630                 if (uidState.isMissing()) {
2631                     for (String permissionName : uidRequestedPermissions) {
2632                         Permission permission = mRegistry.getPermission(permissionName);
2633                         if (permission == null) {
2634                             continue;
2635                         }
2636                         if (Objects.equals(permission.getPackageName(), PLATFORM_PACKAGE_NAME)
2637                                 && permission.isRuntime() && !permission.isRemoved()) {
2638                             if (permission.isHardOrSoftRestricted()
2639                                     || permission.isImmutablyRestricted()) {
2640                                 uidState.updatePermissionFlags(permission,
2641                                         FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
2642                                         FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
2643                             }
2644                             if (uidTargetSdkVersion < Build.VERSION_CODES.M) {
2645                                 uidState.updatePermissionFlags(permission,
2646                                         PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
2647                                                 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
2648                                         PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
2649                                                 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
2650                                 uidState.grantPermission(permission);
2651                             }
2652                         }
2653                     }
2654 
2655                     uidState.setMissing(false);
2656                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2657                 }
2658 
2659                 UidPermissionState origState = uidState;
2660 
2661                 boolean installPermissionsChangedForUser = false;
2662 
2663                 if (replace) {
2664                     userState.setInstallPermissionsFixed(ps.getPackageName(), false);
2665                     if (!ps.hasSharedUser()) {
2666                         origState = new UidPermissionState(uidState);
2667                         uidState.reset();
2668                     } else {
2669                         // We need to know only about runtime permission changes since the
2670                         // calling code always writes the install permissions state but
2671                         // the runtime ones are written only if changed. The only cases of
2672                         // changed runtime permissions here are promotion of an install to
2673                         // runtime and revocation of a runtime from a shared user.
2674                         if (revokeUnusedSharedUserPermissionsLocked(uidRequestedPermissions,
2675                                 uidState)) {
2676                             updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2677                             runtimePermissionsRevoked = true;
2678                         }
2679                     }
2680                 }
2681 
2682                 ArraySet<String> newImplicitPermissions = new ArraySet<>();
2683                 final String friendlyName = pkg.getPackageName() + "(" + pkg.getUid() + ")";
2684 
2685                 for (final String permName : requestedPermissions) {
2686                     final Permission bp = mRegistry.getPermission(permName);
2687                     final boolean appSupportsRuntimePermissions =
2688                             pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
2689 
2690                     if (DEBUG_INSTALL && bp != null) {
2691                         Log.i(TAG, "Package " + friendlyName
2692                                 + " checking " + permName + ": " + bp);
2693                     }
2694 
2695                     // TODO(zhanghai): I don't think we need to check source package setting if
2696                     //  permission is present, because otherwise the permission should have been
2697                     //  removed.
2698                     if (bp == null /*|| getSourcePackageSetting(bp) == null*/) {
2699                         if (changingPackageName == null || changingPackageName.equals(
2700                                 pkg.getPackageName())) {
2701                             if (DEBUG_PERMISSIONS) {
2702                                 Slog.i(TAG, "Unknown permission " + permName
2703                                         + " in package " + friendlyName);
2704                             }
2705                         }
2706                         continue;
2707                     }
2708 
2709                     // Cache newImplicitPermissions before modifing permissionsState as for the
2710                     // shared uids the original and new state are the same object
2711                     if (!origState.hasPermissionState(permName)
2712                             && (pkg.getImplicitPermissions().contains(permName))) {
2713                             // If permName is an implicit permission, try to auto-grant
2714                             newImplicitPermissions.add(permName);
2715                             if (DEBUG_PERMISSIONS) {
2716                                 Slog.i(TAG, permName + " is newly added for " + friendlyName);
2717                             }
2718                     }
2719 
2720                     // TODO(b/140256621): The package instant app method has been removed
2721                     //  as part of work in b/135203078, so this has been commented out in the
2722                     //  meantime
2723                     // Limit ephemeral apps to ephemeral allowed permissions.
2724         //            if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) {
2725         //                if (DEBUG_PERMISSIONS) {
2726         //                    Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
2727         //                            + " for package " + pkg.getPackageName());
2728         //                }
2729         //                continue;
2730         //            }
2731 
2732                     if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
2733                         if (DEBUG_PERMISSIONS) {
2734                             Log.i(TAG, "Denying runtime-only permission " + bp.getName()
2735                                     + " for package " + friendlyName);
2736                         }
2737                         continue;
2738                     }
2739 
2740                     final String perm = bp.getName();
2741 
2742                     // Keep track of app op permissions.
2743                     if (bp.isAppOp()) {
2744                         mRegistry.addAppOpPermissionPackage(perm, pkg.getPackageName());
2745                     }
2746 
2747                     boolean shouldGrantNormalPermission = true;
2748                     if (bp.isNormal() && !origState.isPermissionGranted(perm)) {
2749                         // If this is an existing, non-system package, then
2750                         // we can't add any new permissions to it. Runtime
2751                         // permissions can be added any time - they are dynamic.
2752                         if (!ps.isSystem() && userState.areInstallPermissionsFixed(
2753                                 ps.getPackageName())) {
2754                             // Except...  if this is a permission that was added
2755                             // to the platform (note: need to only do this when
2756                             // updating the platform).
2757                             if (!isCompatPlatformPermissionForPackage(perm, pkg)) {
2758                                 shouldGrantNormalPermission = false;
2759                             }
2760                         }
2761                     }
2762 
2763                     if (DEBUG_PERMISSIONS) {
2764                         Slog.i(TAG, "Considering granting permission " + perm + " to package "
2765                                 + pkg.getPackageName());
2766                     }
2767 
2768                     if (bp.isNormal() || bp.isSignature() || bp.isInternal()) {
2769                         if ((bp.isNormal() && shouldGrantNormalPermission)
2770                                 || (bp.isSignature()
2771                                         && (!bp.isPrivileged() || CollectionUtils.contains(
2772                                                 isPrivilegedPermissionAllowlisted, permName))
2773                                         && (CollectionUtils.contains(shouldGrantSignaturePermission,
2774                                                 permName)
2775                                                 || (((bp.isPrivileged() && CollectionUtils.contains(
2776                                                         shouldGrantPrivilegedPermissionIfWasGranted,
2777                                                         permName)) || bp.isDevelopment()
2778                                                                 || bp.isRole())
2779                                                         && origState.isPermissionGranted(
2780                                                                 permName))))
2781                                 || (bp.isInternal()
2782                                         && (!bp.isPrivileged() || CollectionUtils.contains(
2783                                                 isPrivilegedPermissionAllowlisted, permName))
2784                                         && (CollectionUtils.contains(shouldGrantInternalPermission,
2785                                                 permName)
2786                                                 || (((bp.isPrivileged() && CollectionUtils.contains(
2787                                                         shouldGrantPrivilegedPermissionIfWasGranted,
2788                                                         permName)) || bp.isDevelopment()
2789                                                                 || bp.isRole())
2790                                                         && origState.isPermissionGranted(
2791                                                                 permName))))) {
2792                             // Grant an install permission.
2793                             if (uidState.grantPermission(bp)) {
2794                                 installPermissionsChangedForUser = true;
2795                             }
2796                         } else {
2797                             if (DEBUG_PERMISSIONS) {
2798                                 boolean wasGranted = uidState.isPermissionGranted(bp.getName());
2799                                 if (wasGranted || bp.isAppOp()) {
2800                                     Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting")
2801                                             + " permission " + perm
2802                                             + " from package " + friendlyName
2803                                             + " (protectionLevel=" + bp.getProtectionLevel()
2804                                             + " flags=0x"
2805                                             + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg,
2806                                             ps))
2807                                             + ")");
2808                                 }
2809                             }
2810                             if (uidState.revokePermission(bp)) {
2811                                 installPermissionsChangedForUser = true;
2812                             }
2813                         }
2814                         PermissionState origPermState = origState.getPermissionState(perm);
2815                         int flags = origPermState != null ? origPermState.getFlags() : 0;
2816                         uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL, flags);
2817                     } else if (bp.isRuntime()) {
2818                         boolean hardRestricted = bp.isHardRestricted();
2819                         boolean softRestricted = bp.isSoftRestricted();
2820 
2821                         // If permission policy is not ready we don't deal with restricted
2822                         // permissions as the policy may allowlist some permissions. Once
2823                         // the policy is initialized we would re-evaluate permissions.
2824                         final boolean permissionPolicyInitialized =
2825                                 isPermissionPolicyInitialized.get(userId);
2826 
2827                         PermissionState origPermState = origState.getPermissionState(perm);
2828                         int flags = origPermState != null ? origPermState.getFlags() : 0;
2829 
2830                         boolean wasChanged = false;
2831 
2832                         boolean restrictionExempt =
2833                                 (origState.getPermissionFlags(bp.getName())
2834                                         & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2835                         boolean restrictionApplied = (origState.getPermissionFlags(
2836                                 bp.getName()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2837 
2838                         if (appSupportsRuntimePermissions) {
2839                             // If hard restricted we don't allow holding it
2840                             if (permissionPolicyInitialized && hardRestricted) {
2841                                 if (!restrictionExempt) {
2842                                     if (origPermState != null && origPermState.isGranted()
2843                                             && uidState.revokePermission(bp)) {
2844                                         wasChanged = true;
2845                                     }
2846                                     if (!restrictionApplied) {
2847                                         flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2848                                         wasChanged = true;
2849                                     }
2850                                 }
2851                             // If soft restricted we allow holding in a restricted form
2852                             } else if (permissionPolicyInitialized && softRestricted) {
2853                                 // Regardless if granted set the restriction flag as it
2854                                 // may affect app treatment based on this permission.
2855                                 if (!restrictionExempt && !restrictionApplied) {
2856                                     flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2857                                     wasChanged = true;
2858                                 }
2859                             }
2860 
2861                             // Remove review flag as it is not necessary anymore
2862                             if (!NOTIFICATION_PERMISSIONS.contains(perm)) {
2863                                 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2864                                     flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2865                                     wasChanged = true;
2866                                 }
2867                             }
2868 
2869                             if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0
2870                                     && !isPermissionSplitFromNonRuntime(permName,
2871                                     pkg.getTargetSdkVersion())) {
2872                                 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
2873                                 wasChanged = true;
2874                             // Hard restricted permissions cannot be held.
2875                             } else if (!permissionPolicyInitialized
2876                                     || (!hardRestricted || restrictionExempt)) {
2877                                 if ((origPermState != null && origPermState.isGranted())) {
2878                                     if (!uidState.grantPermission(bp)) {
2879                                         wasChanged = true;
2880                                     }
2881                                 }
2882                             }
2883                             if (mIsLeanback && NOTIFICATION_PERMISSIONS.contains(permName)) {
2884                                 uidState.grantPermission(bp);
2885                                 if (origPermState == null || !origPermState.isGranted()) {
2886                                     if (uidState.grantPermission(bp)) {
2887                                         wasChanged = true;
2888                                     }
2889                                 }
2890                             }
2891                         } else {
2892                             if (origPermState == null) {
2893                                 // New permission
2894                                 if (PLATFORM_PACKAGE_NAME.equals(
2895                                         bp.getPackageName())) {
2896                                     if (!bp.isRemoved()) {
2897                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED
2898                                                 | FLAG_PERMISSION_REVOKED_COMPAT;
2899                                         wasChanged = true;
2900                                     }
2901                                 }
2902                             }
2903 
2904                             if (!uidState.isPermissionGranted(bp.getName())
2905                                     && uidState.grantPermission(bp)) {
2906                                 wasChanged = true;
2907                             }
2908 
2909                             // If legacy app always grant the permission but if restricted
2910                             // and not exempt take a note a restriction should be applied.
2911                             if (permissionPolicyInitialized
2912                                     && (hardRestricted || softRestricted)
2913                                             && !restrictionExempt && !restrictionApplied) {
2914                                 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2915                                 wasChanged = true;
2916                             }
2917                         }
2918 
2919                         // If unrestricted or restriction exempt, don't apply restriction.
2920                         if (permissionPolicyInitialized) {
2921                             if (!(hardRestricted || softRestricted) || restrictionExempt) {
2922                                 if (restrictionApplied) {
2923                                     flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2924                                     // Dropping restriction on a legacy app implies a review
2925                                     if (!appSupportsRuntimePermissions) {
2926                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2927                                     }
2928                                     wasChanged = true;
2929                                 }
2930                             }
2931                         }
2932 
2933                         if (wasChanged) {
2934                             updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2935                         }
2936 
2937                         uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL,
2938                                 flags);
2939                     } else {
2940                         Slog.wtf(LOG_TAG, "Unknown permission protection " + bp.getProtection()
2941                                 + " for permission " + bp.getName());
2942                     }
2943                 }
2944 
2945                 if ((installPermissionsChangedForUser || replace)
2946                         && !userState.areInstallPermissionsFixed(ps.getPackageName())
2947                         && !ps.isSystem() || ps.isUpdatedSystemApp()) {
2948                     // This is the first that we have heard about this package, so the
2949                     // permissions we have now selected are fixed until explicitly
2950                     // changed.
2951                     userState.setInstallPermissionsFixed(ps.getPackageName(), true);
2952                 }
2953 
2954                 if (installPermissionsChangedForUser) {
2955                     installPermissionsChanged = true;
2956                     if (changingPackageName != null && replace) {
2957                         updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2958                     }
2959                 }
2960                 updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState,
2961                         pkg.getPackageName(), uidImplicitPermissions, uidTargetSdkVersion, userId,
2962                         updatedUserIds);
2963                 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState,
2964                         uidState, pkg, newImplicitPermissions, userId, updatedUserIds);
2965             }
2966         }
2967 
2968         updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, userIds,
2969                 updatedUserIds);
2970 
2971         // TODO: Kill UIDs whose GIDs or runtime permissions changed. This might be more important
2972         //  for shared users.
2973         // Persist the runtime permissions state for users with changes. If permissions
2974         // were revoked because no app in the shared user declares them we have to
2975         // write synchronously to avoid losing runtime permissions state.
2976         // Also write synchronously if we changed any install permission for an updated app, because
2977         // the install permission state is likely already fixed before update, and if we lose the
2978         // changes here the app won't be reconsidered for newly-added install permissions.
2979         if (callback != null) {
2980             callback.onPermissionUpdated(updatedUserIds,
2981                     (changingPackageName != null && replace && installPermissionsChanged)
2982                             || runtimePermissionsRevoked, pkg.getUid());
2983         }
2984     }
2985 
2986     /**
2987      * Returns all relevant user ids.  This list include the current set of created user ids as well
2988      * as pre-created user ids.
2989      * @return user ids for created users and pre-created users
2990      */
2991     private int[] getAllUserIds() {
2992         return UserManagerService.getInstance().getUserIdsIncludingPreCreated();
2993     }
2994 
2995     /**
2996      * Revoke permissions that are not implicit anymore and that have
2997      * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
2998      *
2999      * @param ps The state of the permissions of the package
3000      * @param packageName The name of the package
3001      * @param uidImplicitPermissions The implicit permissions of all packages in the UID
3002      * @param uidTargetSdkVersion The lowest target SDK version of all packages in the UID
3003      * @param userIds All user IDs in the system, must be passed in because this method is locked
3004      * @param updatedUserIds a list of user ids that needs to be amended if the permission state
3005      *                       for a user is changed.
3006      *
3007      * @return The updated value of the {@code updatedUserIds} parameter
3008      */
3009     @NonNull
3010     @GuardedBy("mLock")
3011     private int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps,
3012             @NonNull String packageName, @NonNull Collection<String> uidImplicitPermissions,
3013             int uidTargetSdkVersion, int userId, @NonNull int[] updatedUserIds) {
3014         boolean supportsRuntimePermissions = uidTargetSdkVersion >= Build.VERSION_CODES.M;
3015 
3016         for (String permission : ps.getGrantedPermissions()) {
3017             if (!uidImplicitPermissions.contains(permission)) {
3018                 Permission bp = mRegistry.getPermission(permission);
3019                 if (bp != null && bp.isRuntime()) {
3020                     int flags = ps.getPermissionFlags(permission);
3021                     if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
3022                         int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
3023 
3024                         // We're willing to preserve an implicit "Nearby devices"
3025                         // permission grant if this app was already able to interact
3026                         // with nearby devices via background location access
3027                         boolean preserveGrant = false;
3028                         if (ArrayUtils.contains(NEARBY_DEVICES_PERMISSIONS, permission)
3029                                 && ps.isPermissionGranted(
3030                                         android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
3031                                 && (ps.getPermissionFlags(
3032                                         android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
3033                                         & (FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
3034                                                 | FLAG_PERMISSION_REVOKED_COMPAT)) == 0) {
3035                             preserveGrant = true;
3036                         }
3037 
3038                         if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
3039                                 && supportsRuntimePermissions
3040                                 && !preserveGrant) {
3041                             if (ps.revokePermission(bp)) {
3042                                 if (DEBUG_PERMISSIONS) {
3043                                     Slog.i(TAG, "Revoking runtime permission "
3044                                             + permission + " for " + packageName
3045                                             + " as it is now requested");
3046                                 }
3047                             }
3048 
3049                             flagsToRemove |= USER_PERMISSION_FLAGS;
3050                         }
3051 
3052                         ps.updatePermissionFlags(bp, flagsToRemove, 0);
3053                         updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
3054                     }
3055                 }
3056             }
3057         }
3058 
3059         return updatedUserIds;
3060     }
3061 
3062     /**
3063      * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
3064      *
3065      * <p>A single new permission can be split off from several source permissions. In this case
3066      * the most leniant state is inherited.
3067      *
3068      * <p>Warning: This does not handle foreground / background permissions
3069      *
3070      * @param sourcePerms The permissions to inherit from
3071      * @param newPerm The permission to inherit to
3072      * @param ps The permission state of the package
3073      * @param pkg The package requesting the permissions
3074      */
3075     @GuardedBy("mLock")
3076     private void inheritPermissionStateToNewImplicitPermissionLocked(
3077             @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
3078             @NonNull UidPermissionState ps, @NonNull AndroidPackage pkg) {
3079         String pkgName = pkg.getPackageName();
3080         boolean isGranted = false;
3081         int flags = 0;
3082 
3083         int numSourcePerm = sourcePerms.size();
3084         for (int i = 0; i < numSourcePerm; i++) {
3085             String sourcePerm = sourcePerms.valueAt(i);
3086             if (ps.isPermissionGranted(sourcePerm)) {
3087                 if (!isGranted) {
3088                     flags = 0;
3089                 }
3090 
3091                 isGranted = true;
3092                 flags |= ps.getPermissionFlags(sourcePerm);
3093             } else {
3094                 if (!isGranted) {
3095                     flags |= ps.getPermissionFlags(sourcePerm);
3096                 }
3097             }
3098         }
3099 
3100         if (isGranted) {
3101             if (DEBUG_PERMISSIONS) {
3102                 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
3103                         + " for " + pkgName);
3104             }
3105 
3106             ps.grantPermission(mRegistry.getPermission(newPerm));
3107         }
3108 
3109         // Add permission flags
3110         ps.updatePermissionFlags(mRegistry.getPermission(newPerm), flags, flags);
3111     }
3112 
3113     /**
3114      * When the app has requested legacy storage we might need to update
3115      * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
3116      * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
3117      *
3118      * @param pkg The package for which the permissions are updated
3119      * @param replace If the app is being replaced
3120      * @param userIds All user IDs in the system, must be passed in because this method is locked
3121      * @param updatedUserIds The ids of the users that already changed.
3122      *
3123      * @return The ids of the users that are changed
3124      */
3125     private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(@NonNull AndroidPackage pkg,
3126             boolean replace, @NonNull int[] userIds, @NonNull int[] updatedUserIds) {
3127         if (replace && pkg.isRequestLegacyExternalStorage() && (
3128                 pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
3129                         || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
3130             return userIds.clone();
3131         }
3132 
3133         return updatedUserIds;
3134     }
3135 
3136     /**
3137      * Set the state of a implicit permission that is seen for the first time.
3138      *
3139      * @param origPs The permission state of the package before the split
3140      * @param ps The new permission state
3141      * @param pkg The package the permission belongs to
3142      * @param userId The user ID
3143      * @param updatedUserIds List of users for which the permission state has already been changed
3144      *
3145      * @return  List of users for which the permission state has been changed
3146      */
3147     @NonNull
3148     @GuardedBy("mLock")
3149     private int[] setInitialGrantForNewImplicitPermissionsLocked(
3150             @NonNull UidPermissionState origPs, @NonNull UidPermissionState ps,
3151             @NonNull AndroidPackage pkg, @NonNull ArraySet<String> newImplicitPermissions,
3152             @UserIdInt int userId, @NonNull int[] updatedUserIds) {
3153         String pkgName = pkg.getPackageName();
3154         ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
3155 
3156         final List<PermissionManager.SplitPermissionInfo> permissionList =
3157                 getSplitPermissionInfos();
3158         int numSplitPerms = permissionList.size();
3159         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
3160             PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum);
3161 
3162             List<String> newPerms = spi.getNewPermissions();
3163             int numNewPerms = newPerms.size();
3164             for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
3165                 String newPerm = newPerms.get(newPermNum);
3166 
3167                 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
3168                 if (splitPerms == null) {
3169                     splitPerms = new ArraySet<>();
3170                     newToSplitPerms.put(newPerm, splitPerms);
3171                 }
3172 
3173                 splitPerms.add(spi.getSplitPermission());
3174             }
3175         }
3176 
3177         int numNewImplicitPerms = newImplicitPermissions.size();
3178         for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
3179                 newImplicitPermNum++) {
3180             String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
3181             ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
3182 
3183             if (sourcePerms != null) {
3184                 Permission bp = mRegistry.getPermission(newPerm);
3185                 if (bp == null) {
3186                     throw new IllegalStateException("Unknown new permission in split permission: "
3187                             + newPerm);
3188                 }
3189                 if (bp.isRuntime()) {
3190 
3191                     if (!(newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)
3192                             || READ_MEDIA_AURAL_PERMISSIONS.contains(newPerm)
3193                             || READ_MEDIA_VISUAL_PERMISSIONS.contains(newPerm))) {
3194                         ps.updatePermissionFlags(bp,
3195                                 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
3196                                 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
3197                     }
3198                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
3199 
3200                     if (!origPs.hasPermissionState(sourcePerms)) {
3201                         boolean inheritsFromInstallPerm = false;
3202                         for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
3203                                 sourcePermNum++) {
3204                             final String sourcePerm = sourcePerms.valueAt(sourcePermNum);
3205                             Permission sourceBp = mRegistry.getPermission(sourcePerm);
3206                             if (sourceBp == null) {
3207                                 throw new IllegalStateException("Unknown source permission in split"
3208                                         + " permission: " + sourcePerm);
3209                             }
3210                             if (!sourceBp.isRuntime()) {
3211                                 inheritsFromInstallPerm = true;
3212                                 break;
3213                             }
3214                         }
3215 
3216                         if (!inheritsFromInstallPerm) {
3217                             // Both permissions are new so nothing to inherit.
3218                             if (DEBUG_PERMISSIONS) {
3219                                 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
3220                                         + " for " + pkgName + " as split permission is also new");
3221                             }
3222                             continue;
3223                         }
3224                     }
3225 
3226                     // Inherit from new install or existing runtime permissions
3227                     inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, newPerm, ps,
3228                             pkg);
3229                 }
3230             }
3231         }
3232 
3233         return updatedUserIds;
3234     }
3235 
3236     @NonNull
3237     @Override
3238     public List<SplitPermissionInfoParcelable> getSplitPermissions() {
3239         return PermissionManager.splitPermissionInfoListToParcelableList(getSplitPermissionInfos());
3240     }
3241 
3242     @NonNull
3243     private List<PermissionManager.SplitPermissionInfo> getSplitPermissionInfos() {
3244         return SystemConfig.getInstance().getSplitPermissions();
3245     }
3246 
3247     private static boolean isCompatPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
3248         boolean allowed = false;
3249         for (int i = 0, size = CompatibilityPermissionInfo.COMPAT_PERMS.length; i < size; i++) {
3250             final CompatibilityPermissionInfo info = CompatibilityPermissionInfo.COMPAT_PERMS[i];
3251             if (info.getName().equals(perm)
3252                     && pkg.getTargetSdkVersion() < info.getSdkVersion()) {
3253                 allowed = true;
3254                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
3255                         + pkg.getPackageName());
3256                 break;
3257             }
3258         }
3259         return allowed;
3260     }
3261 
3262     private boolean checkPrivilegedPermissionAllowlist(@NonNull AndroidPackage pkg,
3263             @NonNull PackageStateInternal packageSetting, @NonNull Permission permission) {
3264         if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) {
3265             return true;
3266         }
3267         final String packageName = pkg.getPackageName();
3268         if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) {
3269             return true;
3270         }
3271         if (!(packageSetting.isSystem() && packageSetting.isPrivileged())) {
3272             return true;
3273         }
3274         if (!mPrivilegedPermissionAllowlistSourcePackageNames
3275                 .contains(permission.getPackageName())) {
3276             return true;
3277         }
3278         final String permissionName = permission.getName();
3279         final String containingApexPackageName =
3280                 mApexManager.getActiveApexPackageNameContainingPackage(packageName);
3281         final Boolean allowlistState = getPrivilegedPermissionAllowlistState(packageSetting,
3282                 permissionName, containingApexPackageName);
3283         if (allowlistState != null) {
3284             return allowlistState;
3285         }
3286         // Updated system apps do not need to be allowlisted
3287         if (packageSetting.isUpdatedSystemApp()) {
3288             // Let shouldGrantPermissionByProtectionFlags() decide whether the privileged permission
3289             // can be granted, because an updated system app may be in a shared UID, and in case a
3290             // new privileged permission is requested by the updated system app but not the factory
3291             // app, although this app and permission combination isn't in the allowlist and can't
3292             // get the permission this way, other apps in the shared UID may still get it. A proper
3293             // fix for this would be to perform the reconciliation by UID, but for now let's keep
3294             // the old workaround working, which is to keep granted privileged permissions still
3295             // granted.
3296             return true;
3297         }
3298         // Only enforce the allowlist on boot
3299         if (!mSystemReady) {
3300             final boolean isInUpdatedApex = packageSetting.isApkInUpdatedApex();
3301             // Apps that are in updated apexs' do not need to be allowlisted
3302             if (!isInUpdatedApex) {
3303                 Slog.w(TAG, "Privileged permission " + permissionName + " for package "
3304                         + packageName + " (" + pkg.getPath()
3305                         + ") not in privapp-permissions allowlist");
3306                 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3307                     synchronized (mLock) {
3308                         if (mPrivappPermissionsViolations == null) {
3309                             mPrivappPermissionsViolations = new ArraySet<>();
3310                         }
3311                         mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): "
3312                                 + permissionName);
3313                     }
3314                 }
3315             }
3316         }
3317         return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE;
3318     }
3319 
3320     @Nullable
3321     private Boolean getPrivilegedPermissionAllowlistState(@NonNull PackageState packageState,
3322             @NonNull String permissionName, String containingApexPackageName) {
3323         final PermissionAllowlist permissionAllowlist =
3324                 SystemConfig.getInstance().getPermissionAllowlist();
3325         final String packageName = packageState.getPackageName();
3326         if (packageState.isVendor() || packageState.isOdm()) {
3327             return permissionAllowlist.getVendorPrivilegedAppAllowlistState(packageName,
3328                     permissionName);
3329         } else if (packageState.isProduct()) {
3330             return permissionAllowlist.getProductPrivilegedAppAllowlistState(packageName,
3331                     permissionName);
3332         } else if (packageState.isSystemExt()) {
3333             return permissionAllowlist.getSystemExtPrivilegedAppAllowlistState(packageName,
3334                     permissionName);
3335         } else if (containingApexPackageName != null) {
3336             final Boolean nonApexAllowlistState =
3337                     permissionAllowlist.getPrivilegedAppAllowlistState(packageName, permissionName);
3338             if (nonApexAllowlistState != null) {
3339                 // TODO(andreionea): Remove check as soon as all apk-in-apex
3340                 // permission allowlists are migrated.
3341                 Slog.w(TAG, "Package " + packageName + " is an APK in APEX,"
3342                         + " but has permission allowlist on the system image. Please bundle the"
3343                         + " allowlist in the " + containingApexPackageName + " APEX instead.");
3344             }
3345             final String moduleName = mApexManager.getApexModuleNameForPackageName(
3346                     containingApexPackageName);
3347             final Boolean apexAllowlistState =
3348                     permissionAllowlist.getApexPrivilegedAppAllowlistState(moduleName, packageName,
3349                             permissionName);
3350             if (apexAllowlistState != null) {
3351                 return apexAllowlistState;
3352             }
3353             return nonApexAllowlistState;
3354         } else {
3355             return permissionAllowlist.getPrivilegedAppAllowlistState(packageName, permissionName);
3356         }
3357     }
3358 
3359     private boolean shouldGrantPermissionBySignature(@NonNull AndroidPackage pkg,
3360             @NonNull Permission bp) {
3361         // expect single system package
3362         String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
3363                 KnownPackages.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
3364         final AndroidPackage systemPackage =
3365                 mPackageManagerInt.getPackage(systemPackageName);
3366         // check if the package is allow to use this signature permission.  A package is allowed to
3367         // use a signature permission if:
3368         //     - it has the same set of signing certificates as the source package
3369         //     - or its signing certificate was rotated from the source package's certificate
3370         //     - or its signing certificate is a previous signing certificate of the defining
3371         //       package, and the defining package still trusts the old certificate for permissions
3372         //     - or it shares a common signing certificate in its lineage with the defining package,
3373         //       and the defining package still trusts the old certificate for permissions
3374         //     - or it shares the above relationships with the system package
3375         final SigningDetails sourceSigningDetails =
3376                 getSourcePackageSigningDetails(bp);
3377         return sourceSigningDetails.hasCommonSignerWithCapability(
3378                         pkg.getSigningDetails(),
3379                         SigningDetails.CertCapabilities.PERMISSION)
3380                 || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
3381                 || systemPackage.getSigningDetails().checkCapability(
3382                         pkg.getSigningDetails(),
3383                         SigningDetails.CertCapabilities.PERMISSION);
3384     }
3385 
3386     private boolean shouldGrantPermissionByProtectionFlags(@NonNull AndroidPackage pkg,
3387             @NonNull PackageStateInternal pkgSetting, @NonNull Permission bp,
3388             @NonNull ArraySet<String> shouldGrantPrivilegedPermissionIfWasGranted) {
3389         boolean allowed = false;
3390         final boolean isPrivilegedPermission = bp.isPrivileged();
3391         final boolean isOemPermission = bp.isOem();
3392         if (!allowed && (isPrivilegedPermission || isOemPermission) && pkgSetting.isSystem()) {
3393             final String permissionName = bp.getName();
3394             // For updated system applications, a privileged/oem permission
3395             // is granted only if it had been defined by the original application.
3396             if (pkgSetting.isUpdatedSystemApp()) {
3397                 final PackageStateInternal disabledPs = mPackageManagerInt
3398                         .getDisabledSystemPackage(pkg.getPackageName());
3399                 final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.getPkg();
3400                 if (disabledPkg != null
3401                         && ((isPrivilegedPermission && disabledPs.isPrivileged())
3402                         || (isOemPermission && canGrantOemPermission(disabledPs,
3403                                 permissionName)))) {
3404                     if (disabledPkg.getRequestedPermissions().contains(permissionName)) {
3405                         allowed = true;
3406                     } else {
3407                         // If the original was granted this permission, we take
3408                         // that grant decision as read and propagate it to the
3409                         // update.
3410                         shouldGrantPrivilegedPermissionIfWasGranted.add(permissionName);
3411                     }
3412                 }
3413             } else {
3414                 allowed = (isPrivilegedPermission && pkgSetting.isPrivileged())
3415                         || (isOemPermission && canGrantOemPermission(pkgSetting, permissionName));
3416             }
3417             // In any case, don't grant a privileged permission to privileged vendor apps, if
3418             // the permission's protectionLevel does not have the extra 'vendorPrivileged'
3419             // flag.
3420             if (allowed && isPrivilegedPermission && !bp.isVendorPrivileged()
3421                     && (pkgSetting.isVendor() || pkgSetting.isOdm())) {
3422                 Slog.w(TAG, "Permission " + permissionName
3423                         + " cannot be granted to privileged vendor apk " + pkg.getPackageName()
3424                         + " because it isn't a 'vendorPrivileged' permission.");
3425                 allowed = false;
3426             }
3427         }
3428         if (!allowed && bp.isPre23() && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
3429             // If this was a previously normal/dangerous permission that got moved
3430             // to a system permission as part of the runtime permission redesign, then
3431             // we still want to blindly grant it to old apps.
3432             allowed = true;
3433         }
3434         // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
3435         //                  need a separate flag anymore. Hence we need to check which
3436         //                  permissions are needed by the permission controller
3437         if (!allowed && bp.isInstaller()
3438                 && (ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3439                         KnownPackages.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
3440                 pkg.getPackageName()) || ArrayUtils.contains(
3441                         mPackageManagerInt.getKnownPackageNames(
3442                                 KnownPackages.PACKAGE_PERMISSION_CONTROLLER,
3443                 UserHandle.USER_SYSTEM), pkg.getPackageName()))) {
3444             // If this permission is to be granted to the system installer and
3445             // this app is an installer, then it gets the permission.
3446             allowed = true;
3447         }
3448         if (!allowed && bp.isVerifier()
3449                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3450                         KnownPackages.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
3451                 pkg.getPackageName())) {
3452             // If this permission is to be granted to the system verifier and
3453             // this app is a verifier, then it gets the permission.
3454             allowed = true;
3455         }
3456         if (!allowed && bp.isPreInstalled() && pkgSetting.isSystem()) {
3457             // Any pre-installed system app is allowed to get this permission.
3458             allowed = true;
3459         }
3460         if (!allowed && bp.isKnownSigner()) {
3461             // If the permission is to be granted to a known signer then check if any of this
3462             // app's signing certificates are in the trusted certificate digest Set.
3463             allowed = pkg.getSigningDetails().hasAncestorOrSelfWithDigest(bp.getKnownCerts());
3464         }
3465         // Deferred to be checked under permission data lock inside restorePermissionState().
3466         //if (!allowed && bp.isDevelopment()) {
3467         //    // For development permissions, a development permission
3468         //    // is granted only if it was already granted.
3469         //    allowed = origPermissions.isPermissionGranted(permissionName);
3470         //}
3471         if (!allowed && bp.isSetup()
3472                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3473                         KnownPackages.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
3474                 pkg.getPackageName())) {
3475             // If this permission is to be granted to the system setup wizard and
3476             // this app is a setup wizard, then it gets the permission.
3477             allowed = true;
3478         }
3479         if (!allowed && bp.isSystemTextClassifier()
3480                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3481                 KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
3482                 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
3483             // Special permissions for the system default text classifier.
3484             allowed = true;
3485         }
3486         if (!allowed && bp.isConfigurator()
3487                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3488                 KnownPackages.PACKAGE_CONFIGURATOR,
3489                 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
3490             // Special permissions for the device configurator.
3491             allowed = true;
3492         }
3493         if (!allowed && bp.isIncidentReportApprover()
3494                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3495                 KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER,
3496                 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
3497             // If this permission is to be granted to the incident report approver and
3498             // this app is the incident report approver, then it gets the permission.
3499             allowed = true;
3500         }
3501         if (!allowed && bp.isAppPredictor()
3502                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3503                         KnownPackages.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
3504                 pkg.getPackageName())) {
3505             // Special permissions for the system app predictor.
3506             allowed = true;
3507         }
3508         if (!allowed && bp.isCompanion()
3509                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3510                         KnownPackages.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
3511                 pkg.getPackageName())) {
3512             // Special permissions for the system companion device manager.
3513             allowed = true;
3514         }
3515         if (!allowed && bp.isRetailDemo()
3516                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3517                         KnownPackages.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM),
3518                 pkg.getPackageName()) && isProfileOwner(pkg.getUid())) {
3519             // Special permission granted only to the OEM specified retail demo app
3520             allowed = true;
3521         }
3522         if (!allowed && bp.isRecents()
3523                 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3524                         KnownPackages.PACKAGE_RECENTS, UserHandle.USER_SYSTEM),
3525                 pkg.getPackageName())) {
3526             // Special permission for the recents app.
3527             allowed = true;
3528         }
3529         if (!allowed && bp.isModule() && mApexManager.getActiveApexPackageNameContainingPackage(
3530                 pkg.getPackageName()) != null) {
3531             // Special permission granted for APKs inside APEX modules.
3532             allowed = true;
3533         }
3534         return allowed;
3535     }
3536 
3537     @NonNull
3538     private SigningDetails getSourcePackageSigningDetails(
3539             @NonNull Permission bp) {
3540         final PackageStateInternal ps = getSourcePackageSetting(bp);
3541         if (ps == null) {
3542             return SigningDetails.UNKNOWN;
3543         }
3544         return ps.getSigningDetails();
3545     }
3546 
3547     @Nullable
3548     private PackageStateInternal getSourcePackageSetting(@NonNull Permission bp) {
3549         final String sourcePackageName = bp.getPackageName();
3550         return mPackageManagerInt.getPackageStateInternal(sourcePackageName);
3551     }
3552 
3553     private static boolean canGrantOemPermission(@NonNull PackageState packageState,
3554             String permission) {
3555         if (!packageState.isOem()) {
3556             return false;
3557         }
3558         var packageName = packageState.getPackageName();
3559         // all oem permissions must explicitly be granted or denied
3560         final Boolean granted = SystemConfig.getInstance().getPermissionAllowlist()
3561                 .getOemAppAllowlistState(packageState.getPackageName(), permission);
3562         if (granted == null) {
3563             throw new IllegalStateException("OEM permission " + permission
3564                     + " requested by package " + packageName
3565                     + " must be explicitly declared granted or not");
3566         }
3567         return Boolean.TRUE == granted;
3568     }
3569 
3570     private static boolean isProfileOwner(int uid) {
3571         DevicePolicyManagerInternal dpmInternal =
3572                 LocalServices.getService(DevicePolicyManagerInternal.class);
3573         //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode.
3574         if (dpmInternal != null) {
3575             return dpmInternal.isActiveProfileOwner(uid) || dpmInternal.isActiveDeviceOwner(uid);
3576         }
3577         return false;
3578     }
3579 
3580     private boolean isPermissionsReviewRequiredInternal(@NonNull String packageName,
3581             @UserIdInt int userId) {
3582         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
3583         if (pkg == null) {
3584             return false;
3585         }
3586 
3587         // Permission review applies only to apps not supporting the new permission model.
3588         if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
3589             return false;
3590         }
3591 
3592         // Legacy apps have the permission and get user consent on launch.
3593         synchronized (mLock) {
3594             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
3595             if (uidState == null) {
3596                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
3597                         + userId);
3598                 return false;
3599             }
3600             return uidState.isPermissionsReviewRequired();
3601         }
3602     }
3603 
3604     private void grantRequestedPermissionsInternal(@NonNull AndroidPackage pkg,
3605             @Nullable ArrayMap<String, Integer> permissionStates, int userId) {
3606         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3607                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3608 
3609         final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
3610                 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
3611 
3612         final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
3613                 >= Build.VERSION_CODES.M;
3614 
3615         final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
3616 
3617         final int myUid = Process.myUid();
3618 
3619         for (String permission : pkg.getRequestedPermissions()) {
3620             Integer permissionState = permissionStates.get(permission);
3621 
3622             if (permissionState == null || permissionState == PERMISSION_STATE_DEFAULT) {
3623                 continue;
3624             }
3625 
3626             final boolean shouldGrantRuntimePermission;
3627             final boolean isAppOpPermission;
3628             synchronized (mLock) {
3629                 final Permission bp = mRegistry.getPermission(permission);
3630                 if (bp == null) {
3631                     continue;
3632                 }
3633                 shouldGrantRuntimePermission = (bp.isRuntime() || bp.isDevelopment())
3634                         && (!instantApp || bp.isInstant())
3635                         && (supportsRuntimePermissions || !bp.isRuntimeOnly())
3636                         && permissionState == PERMISSION_STATE_GRANTED;
3637                 isAppOpPermission = bp.isAppOp();
3638             }
3639 
3640             final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission,
3641                     myUid, userId);
3642             if (shouldGrantRuntimePermission) {
3643                 if (supportsRuntimePermissions) {
3644                     // Installer cannot change immutable permissions.
3645                     if ((flags & immutableFlags) == 0) {
3646                         grantRuntimePermissionInternal(pkg.getPackageName(), permission, false,
3647                                 myUid, userId, mDefaultPermissionCallback);
3648                     }
3649                 } else {
3650                     // In permission review mode we clear the review flag and the revoked compat
3651                     // flag when we are asked to install the app with all permissions granted.
3652                     if ((flags & compatFlags) != 0) {
3653                         updatePermissionFlagsInternal(pkg.getPackageName(), permission, compatFlags,
3654                                 0, myUid, userId, false, mDefaultPermissionCallback);
3655                     }
3656                 }
3657             } else if (isAppOpPermission
3658                     && PackageInstallerService.INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS
3659                     .contains(permission)) {
3660                 if ((flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0) {
3661                     continue;
3662                 }
3663                 int mode =
3664                         permissionState == PERMISSION_STATE_GRANTED ? MODE_ALLOWED : MODE_ERRORED;
3665                 int uid = UserHandle.getUid(userId, pkg.getUid());
3666                 String appOp = AppOpsManager.permissionToOp(permission);
3667                 mHandler.post(() -> {
3668                     AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
3669                     appOpsManager.setUidMode(appOp, uid, mode);
3670                 });
3671             }
3672         }
3673     }
3674 
3675     private void setAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
3676             @Nullable List<String> permissions,
3677             @PackageManager.PermissionWhitelistFlags int allowlistFlags,
3678             @UserIdInt int userId) {
3679         ArraySet<String> oldGrantedRestrictedPermissions = null;
3680         boolean updatePermissions = false;
3681         final int myUid = Process.myUid();
3682 
3683         for (final String permissionName : pkg.getRequestedPermissions()) {
3684             final boolean isGranted;
3685             synchronized (mLock) {
3686                 final Permission bp = mRegistry.getPermission(permissionName);
3687                 if (bp == null || !bp.isHardOrSoftRestricted()) {
3688                     continue;
3689                 }
3690 
3691                 final UidPermissionState uidState = getUidStateLocked(pkg, userId);
3692                 if (uidState == null) {
3693                     Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
3694                             + " and user " + userId);
3695                     continue;
3696                 }
3697                 isGranted = uidState.isPermissionGranted(permissionName);
3698             }
3699 
3700             if (isGranted) {
3701                 if (oldGrantedRestrictedPermissions == null) {
3702                     oldGrantedRestrictedPermissions = new ArraySet<>();
3703                 }
3704                 oldGrantedRestrictedPermissions.add(permissionName);
3705             }
3706 
3707             final int oldFlags = getPermissionFlagsInternal(pkg.getPackageName(), permissionName,
3708                     myUid, userId);
3709 
3710             int newFlags = oldFlags;
3711             int mask = 0;
3712             int allowlistFlagsCopy = allowlistFlags;
3713             while (allowlistFlagsCopy != 0) {
3714                 final int flag = 1 << Integer.numberOfTrailingZeros(allowlistFlagsCopy);
3715                 allowlistFlagsCopy &= ~flag;
3716                 switch (flag) {
3717                     case FLAG_PERMISSION_WHITELIST_SYSTEM: {
3718                         mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3719                         if (permissions != null && permissions.contains(permissionName)) {
3720                             newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3721                         } else {
3722                             newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3723                         }
3724                     }
3725                     break;
3726                     case FLAG_PERMISSION_WHITELIST_UPGRADE: {
3727                         mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3728                         if (permissions != null && permissions.contains(permissionName)) {
3729                             newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3730                         } else {
3731                             newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3732                         }
3733                     }
3734                     break;
3735                     case FLAG_PERMISSION_WHITELIST_INSTALLER: {
3736                         mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3737                         if (permissions != null && permissions.contains(permissionName)) {
3738                             newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3739                         } else {
3740                             newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3741                         }
3742                     }
3743                     break;
3744                 }
3745             }
3746 
3747             if (oldFlags == newFlags) {
3748                 continue;
3749             }
3750 
3751             updatePermissions = true;
3752 
3753             final boolean wasAllowlisted = (oldFlags
3754                     & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3755             final boolean isAllowlisted = (newFlags
3756                     & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3757 
3758             // If the permission is policy fixed as granted but it is no longer
3759             // on any of the allowlists we need to clear the policy fixed flag
3760             // as allowlisting trumps policy i.e. policy cannot grant a non
3761             // grantable permission.
3762             if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
3763                 if (!isAllowlisted && isGranted) {
3764                     mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3765                     newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3766                 }
3767             }
3768 
3769             // If we are allowlisting an app that does not support runtime permissions
3770             // we need to make sure it goes through the permission review UI at launch.
3771             if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
3772                     && !wasAllowlisted && isAllowlisted) {
3773                 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3774                 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3775             }
3776 
3777             updatePermissionFlagsInternal(pkg.getPackageName(), permissionName, mask, newFlags,
3778                     myUid, userId, false, null /*callback*/);
3779         }
3780 
3781         if (updatePermissions) {
3782             // Update permission of this app to take into account the new allowlist state.
3783             restorePermissionState(pkg, false, pkg.getPackageName(), mDefaultPermissionCallback,
3784                     userId);
3785 
3786             // If this resulted in losing a permission we need to kill the app.
3787             if (oldGrantedRestrictedPermissions == null) {
3788                 return;
3789             }
3790 
3791             final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
3792             for (int j = 0; j < oldGrantedCount; j++) {
3793                 final String permissionName = oldGrantedRestrictedPermissions.valueAt(j);
3794                 // Sometimes we create a new permission state instance during update.
3795                 final boolean isGranted;
3796                 synchronized (mLock) {
3797                     final UidPermissionState uidState = getUidStateLocked(pkg, userId);
3798                     if (uidState == null) {
3799                         Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
3800                                 + " and user " + userId);
3801                         continue;
3802                     }
3803                     isGranted = uidState.isPermissionGranted(permissionName);
3804                 }
3805                 if (!isGranted) {
3806                     mDefaultPermissionCallback.onPermissionRevoked(
3807                             UserHandle.getUid(userId, pkg.getUid()), userId, null);
3808                     break;
3809                 }
3810             }
3811         }
3812     }
3813 
3814     private void revokeSharedUserPermissionsForLeavingPackageInternal(
3815             @Nullable AndroidPackage pkg, int appId, @NonNull List<AndroidPackage> sharedUserPkgs,
3816             @UserIdInt int userId) {
3817         if (pkg == null) {
3818             Slog.i(TAG, "Trying to update info for null package. Just ignoring");
3819             return;
3820         }
3821 
3822         // No shared user packages
3823         if (sharedUserPkgs.isEmpty()) {
3824             return;
3825         }
3826 
3827         PackageStateInternal disabledPs = mPackageManagerInt.getDisabledSystemPackage(
3828                 pkg.getPackageName());
3829         boolean isShadowingSystemPkg = disabledPs != null && disabledPs.getAppId() == pkg.getUid();
3830 
3831         boolean shouldKillUid = false;
3832         // Update permissions
3833         for (String eachPerm : pkg.getRequestedPermissions()) {
3834             // Check if another package in the shared user needs the permission.
3835             boolean used = false;
3836             for (AndroidPackage sharedUserpkg : sharedUserPkgs) {
3837                 if (sharedUserpkg != null
3838                         && !sharedUserpkg.getPackageName().equals(pkg.getPackageName())
3839                         && sharedUserpkg.getRequestedPermissions().contains(eachPerm)) {
3840                     used = true;
3841                     break;
3842                 }
3843             }
3844             if (used) {
3845                 continue;
3846             }
3847 
3848             // If the package is shadowing a disabled system package,
3849             // do not drop permissions that the shadowed package requests.
3850             if (isShadowingSystemPkg
3851                     && disabledPs.getPkg().getRequestedPermissions().contains(eachPerm)) {
3852                 continue;
3853             }
3854 
3855             synchronized (mLock) {
3856                 UidPermissionState uidState = getUidStateLocked(appId, userId);
3857                 if (uidState == null) {
3858                     Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
3859                             + " and user " + userId);
3860                     continue;
3861                 }
3862 
3863                 Permission bp = mRegistry.getPermission(eachPerm);
3864                 if (bp == null) {
3865                     continue;
3866                 }
3867 
3868                 // TODO(zhanghai): Why are we only killing the UID when GIDs changed, instead of any
3869                 //  permission change?
3870                 if (uidState.removePermissionState(bp.getName()) && bp.hasGids()) {
3871                     shouldKillUid = true;
3872                 }
3873             }
3874         }
3875 
3876         // If gids changed, kill all affected packages.
3877         if (shouldKillUid) {
3878             mHandler.post(() -> {
3879                 // This has to happen with no lock held.
3880                 killUid(appId, UserHandle.USER_ALL, KILL_APP_REASON_GIDS_CHANGED);
3881             });
3882         }
3883     }
3884 
3885     @GuardedBy("mLock")
3886     private boolean revokeUnusedSharedUserPermissionsLocked(
3887             @NonNull Collection<String> uidRequestedPermissions,
3888             @NonNull UidPermissionState uidState) {
3889         boolean runtimePermissionChanged = false;
3890 
3891         // Prune permissions
3892         final List<PermissionState> permissionStates = uidState.getPermissionStates();
3893         final int permissionStatesSize = permissionStates.size();
3894         for (int i = permissionStatesSize - 1; i >= 0; i--) {
3895             PermissionState permissionState = permissionStates.get(i);
3896             if (!uidRequestedPermissions.contains(permissionState.getName())) {
3897                 Permission bp = mRegistry.getPermission(permissionState.getName());
3898                 if (bp != null) {
3899                     if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) {
3900                         runtimePermissionChanged = true;
3901                     }
3902                 }
3903             }
3904         }
3905 
3906         return runtimePermissionChanged;
3907     }
3908 
3909     /**
3910      * Update permissions when a package changed.
3911      *
3912      * <p><ol>
3913      *     <li>Reconsider the ownership of permission</li>
3914      *     <li>Update the state (grant, flags) of the permissions</li>
3915      * </ol>
3916      *
3917      * @param packageName The package that is updated
3918      * @param pkg The package that is updated, or {@code null} if package is deleted
3919      */
3920     private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
3921         // If the package is being deleted, update the permissions of all the apps
3922         final int flags =
3923                 (pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG
3924                         : UPDATE_PERMISSIONS_REPLACE_PKG);
3925         updatePermissions(
3926                 packageName, pkg, getVolumeUuidForPackage(pkg), flags, mDefaultPermissionCallback);
3927     }
3928 
3929     /**
3930      * Update all permissions for all apps.
3931      *
3932      * <p><ol>
3933      *     <li>Reconsider the ownership of permission</li>
3934      *     <li>Update the state (grant, flags) of the permissions</li>
3935      * </ol>
3936      *
3937      * @param volumeUuid The volume UUID of the packages to be updated
3938      * @param fingerprintChanged whether the current build fingerprint is different from what it was
3939      *                           when this volume was last mounted
3940      */
3941     private void updateAllPermissions(@NonNull String volumeUuid, boolean fingerprintChanged) {
3942         PackageManager.corkPackageInfoCache();  // Prevent invalidation storm
3943         try {
3944             final int flags = UPDATE_PERMISSIONS_ALL |
3945                     (fingerprintChanged
3946                             ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
3947                             : 0);
3948             updatePermissions(null, null, volumeUuid, flags, mDefaultPermissionCallback);
3949         } finally {
3950             PackageManager.uncorkPackageInfoCache();
3951         }
3952     }
3953 
3954     /**
3955      * Update all packages on the volume, <u>beside</u> the changing package. If the changing
3956      * package is set too, all packages are updated.
3957      */
3958     private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
3959     /** The changing package is replaced. Requires the changing package to be set */
3960     private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
3961     /**
3962      * Schedule all packages <u>beside</u> the changing package for replacement. Requires
3963      * UPDATE_PERMISSIONS_ALL to be set
3964      */
3965     private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;
3966 
3967     @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
3968             UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
3969             UPDATE_PERMISSIONS_REPLACE_ALL })
3970     @Retention(RetentionPolicy.SOURCE)
3971     private @interface UpdatePermissionFlags {}
3972 
3973     /**
3974      * Update permissions when packages changed.
3975      *
3976      * <p><ol>
3977      *     <li>Reconsider the ownership of permission</li>
3978      *     <li>Update the state (grant, flags) of the permissions</li>
3979      * </ol>
3980      *
3981      * <p>Meaning of combination of package parameters:
3982      * <table>
3983      *     <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
3984      *     <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
3985      *     <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
3986      *                                                                    updated</td></tr>
3987      * </table>
3988      *
3989      * @param changingPkgName The package that is updated, or {@code null} if all packages should be
3990      *                    updated
3991      * @param changingPkg The package that is updated, or {@code null} if all packages should be
3992      *                    updated or package is deleted
3993      * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
3994      *                          all volumes
3995      * @param flags Control permission for which apps should be updated
3996      * @param callback Callback to call after permission changes
3997      */
3998     private void updatePermissions(final @Nullable String changingPkgName,
3999             final @Nullable AndroidPackage changingPkg,
4000             final @Nullable String replaceVolumeUuid,
4001             @UpdatePermissionFlags int flags,
4002             final @Nullable PermissionCallback callback) {
4003         // TODO: Most of the methods exposing BasePermission internals [source package name,
4004         // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
4005         // have package settings, we should make note of it elsewhere [map between
4006         // source package name and BasePermission] and cycle through that here. Then we
4007         // define a single method on BasePermission that takes a PackageSetting, changing
4008         // package name and a package.
4009         // NOTE: With this approach, we also don't need to tree trees differently than
4010         // normal permissions. Today, we need two separate loops because these BasePermission
4011         // objects are stored separately.
4012         // Make sure there are no dangling permission trees.
4013         boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
4014                 changingPkgName, changingPkg);
4015         // Make sure all dynamic permissions have been assigned to a package,
4016         // and make sure there are no dangling permissions.
4017         boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
4018                 callback);
4019 
4020         if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
4021             // Permission ownership has changed. This e.g. changes which packages can get signature
4022             // permissions
4023             Slog.i(TAG, "Permission ownership changed. Updating all permissions.");
4024             flags |= UPDATE_PERMISSIONS_ALL;
4025         }
4026 
4027         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
4028         // Now update the permissions for all packages.
4029         if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
4030             final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
4031             mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
4032                 if (pkg == changingPkg) {
4033                     return;
4034                 }
4035                 // Only replace for packages on requested volume
4036                 final String volumeUuid = getVolumeUuidForPackage(pkg);
4037                 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
4038                 restorePermissionState(pkg, replace, changingPkgName, callback,
4039                         UserHandle.USER_ALL);
4040             });
4041         }
4042 
4043         if (changingPkg != null) {
4044             // Only replace for packages on requested volume
4045             final String volumeUuid = getVolumeUuidForPackage(changingPkg);
4046             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
4047                     && Objects.equals(replaceVolumeUuid, volumeUuid);
4048             restorePermissionState(changingPkg, replace, changingPkgName, callback,
4049                     UserHandle.USER_ALL);
4050         }
4051         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4052     }
4053 
4054     /**
4055      * Update which app declares a permission.
4056      *
4057      * @param packageName The package that is updated, or {@code null} if all packages should be
4058      *                    updated
4059      *
4060      * @return {@code true} if a permission source package might have changed
4061      */
4062     private boolean updatePermissionSourcePackage(@Nullable String packageName,
4063             final @Nullable PermissionCallback callback) {
4064         // Always need update if packageName is null
4065         if (packageName == null) {
4066             return true;
4067         }
4068 
4069         boolean changed = false;
4070         Set<Permission> needsUpdate = null;
4071         synchronized (mLock) {
4072             for (final Permission bp : mRegistry.getPermissions()) {
4073                 if (bp.isDynamic()) {
4074                     bp.updateDynamicPermission(mRegistry.getPermissionTrees());
4075                 }
4076                 if (!packageName.equals(bp.getPackageName())) {
4077                     // Not checking sourcePackageSetting because it can be null when
4078                     // the permission source package is the target package and the target package is
4079                     // being uninstalled,
4080                     continue;
4081                 }
4082                 // The target package is the source of the current permission
4083                 // Set to changed for either install or uninstall
4084                 changed = true;
4085                 if (needsUpdate == null) {
4086                     needsUpdate = new ArraySet<>();
4087                 }
4088                 needsUpdate.add(bp);
4089             }
4090         }
4091         if (needsUpdate != null) {
4092             final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
4093             for (final Permission bp : needsUpdate) {
4094                 // If the target package is being uninstalled, we need to revoke this permission
4095                 // From all other packages
4096                 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4097                     if (!isPermissionDeclaredByDisabledSystemPkg(bp)) {
4098                         Slog.i(TAG, "Removing permission " + bp.getName()
4099                                 + " that used to be declared by " + bp.getPackageName());
4100                         if (bp.isRuntime()) {
4101                             final int[] userIds = mUserManagerInt.getUserIds();
4102                             final int numUserIds = userIds.length;
4103                             for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
4104                                 final int userId = userIds[userIdNum];
4105                                 mPackageManagerInt.forEachPackage((AndroidPackage p) ->
4106                                         revokePermissionFromPackageForUser(p.getPackageName(),
4107                                                 bp.getName(), true, userId, callback));
4108                             }
4109                         } else {
4110                             mPackageManagerInt.forEachPackage(p -> {
4111                                 final int[] userIds = mUserManagerInt.getUserIds();
4112                                 synchronized (mLock) {
4113                                     for (final int userId : userIds) {
4114                                         final UidPermissionState uidState = getUidStateLocked(p,
4115                                                 userId);
4116                                         if (uidState == null) {
4117                                             Slog.e(TAG, "Missing permissions state for "
4118                                                     + p.getPackageName() + " and user " + userId);
4119                                             continue;
4120                                         }
4121                                         uidState.removePermissionState(bp.getName());
4122                                     }
4123                                 }
4124                             });
4125                         }
4126                     }
4127                     synchronized (mLock) {
4128                         mRegistry.removePermission(bp.getName());
4129                     }
4130                     continue;
4131                 }
4132                 final AndroidPackage sourcePkg =
4133                         mPackageManagerInt.getPackage(bp.getPackageName());
4134                 final PackageStateInternal sourcePs =
4135                         mPackageManagerInt.getPackageStateInternal(bp.getPackageName());
4136                 synchronized (mLock) {
4137                     if (sourcePkg != null && sourcePs != null) {
4138                         continue;
4139                     }
4140                     Slog.w(TAG, "Removing dangling permission: " + bp.getName()
4141                             + " from package " + bp.getPackageName());
4142                     mRegistry.removePermission(bp.getName());
4143                 }
4144             }
4145         }
4146         return changed;
4147     }
4148 
4149     private boolean isPermissionDeclaredByDisabledSystemPkg(@NonNull Permission permission) {
4150         final PackageStateInternal disabledSourcePs = mPackageManagerInt.getDisabledSystemPackage(
4151                     permission.getPackageName());
4152         if (disabledSourcePs != null && disabledSourcePs.getPkg() != null) {
4153             final String permissionName = permission.getName();
4154             final List<ParsedPermission> sourcePerms = disabledSourcePs.getPkg().getPermissions();
4155             for (ParsedPermission sourcePerm : sourcePerms) {
4156                 if (TextUtils.equals(permissionName, sourcePerm.getName())
4157                         && permission.getProtectionLevel() == sourcePerm.getProtectionLevel()) {
4158                     return true;
4159                 }
4160             }
4161         }
4162         return false;
4163     }
4164 
4165     /**
4166      * Revoke a runtime permission from a package for a given user ID.
4167      */
4168     private void revokePermissionFromPackageForUser(@NonNull String pName,
4169             @NonNull String permissionName, boolean overridePolicy, int userId,
4170             @Nullable PermissionCallback callback) {
4171         final ApplicationInfo appInfo =
4172                 mPackageManagerInt.getApplicationInfo(pName, 0,
4173                         Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
4174         if (appInfo != null
4175                 && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4176             return;
4177         }
4178 
4179         if (checkPermission(pName, permissionName, userId)
4180                 == PackageManager.PERMISSION_GRANTED) {
4181             try {
4182                 revokeRuntimePermissionInternal(
4183                         pName, permissionName,
4184                         overridePolicy,
4185                         Process.SYSTEM_UID,
4186                         userId,
4187                         null, callback);
4188             } catch (IllegalArgumentException e) {
4189                 Slog.e(TAG,
4190                         "Failed to revoke "
4191                                 + permissionName
4192                                 + " from "
4193                                 + pName,
4194                         e);
4195             }
4196         }
4197     }
4198 
4199     /**
4200      * Update which app owns a permission trees.
4201      *
4202      * <p>Possible parameter combinations
4203      * <table>
4204      *     <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4205      *     <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4206      *     <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4207      * </table>
4208      *
4209      * @param packageName The package that is updated, or {@code null} if all packages should be
4210      *                    updated
4211      * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4212      *            package is deleted
4213      *
4214      * @return {@code true} if a permission tree ownership might have changed
4215      */
4216     private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
4217             @Nullable AndroidPackage pkg) {
4218         // Always need update if packageName is null
4219         if (packageName == null) {
4220             return true;
4221         }
4222         boolean changed = false;
4223 
4224         synchronized (mLock) {
4225             final Iterator<Permission> it = mRegistry.getPermissionTrees().iterator();
4226             while (it.hasNext()) {
4227                 final Permission bp = it.next();
4228                 if (!packageName.equals(bp.getPackageName())) {
4229                     // Not checking sourcePackageSetting because it can be null when
4230                     // the permission source package is the target package and the target package is
4231                     // being uninstalled,
4232                     continue;
4233                 }
4234                 // The target package is the source of the current permission tree
4235                 // Set to changed for either install or uninstall
4236                 changed = true;
4237                 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4238                     Slog.i(TAG, "Removing permission tree " + bp.getName()
4239                             + " that used to be declared by " + bp.getPackageName());
4240                     it.remove();
4241                 }
4242             }
4243         }
4244         return changed;
4245     }
4246 
4247     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4248         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4249                 != PackageManager.PERMISSION_GRANTED
4250             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4251                 != PackageManager.PERMISSION_GRANTED) {
4252             throw new SecurityException(message + " requires "
4253                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4254                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4255         }
4256     }
4257 
4258     private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
4259         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
4260                 != PackageManager.PERMISSION_GRANTED
4261             && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4262                 != PackageManager.PERMISSION_GRANTED
4263             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4264                 != PackageManager.PERMISSION_GRANTED) {
4265             throw new SecurityException(message + " requires "
4266                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4267                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
4268                     + Manifest.permission.GET_RUNTIME_PERMISSIONS);
4269         }
4270     }
4271 
4272     /**
4273      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
4274      * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
4275      *
4276      * @param checkShell whether to prevent shell from access if there's a debugging restriction
4277      * @param message the message to log on security exception
4278      */
4279     private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
4280             boolean requireFullPermission, boolean checkShell, @Nullable String message) {
4281         if (userId < 0) {
4282             throw new IllegalArgumentException("Invalid userId " + userId);
4283         }
4284         if (checkShell) {
4285             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4286         }
4287         final int callingUserId = UserHandle.getUserId(callingUid);
4288         if (checkCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission)) {
4289             return;
4290         }
4291         String errorMessage = buildInvalidCrossUserPermissionMessage(
4292                 callingUid, userId, message, requireFullPermission);
4293         Slog.w(TAG, errorMessage);
4294         throw new SecurityException(errorMessage);
4295     }
4296 
4297     /**
4298      *  Enforces that if the caller is shell, it does not have the provided user restriction.
4299      */
4300     private void enforceShellRestriction(@NonNull String restriction, int callingUid,
4301             @UserIdInt int userId) {
4302         if (callingUid == Process.SHELL_UID) {
4303             if (userId >= 0 && mUserManagerInt.hasUserRestriction(restriction, userId)) {
4304                 throw new SecurityException("Shell does not have permission to access user "
4305                         + userId);
4306             } else if (userId < 0) {
4307                 Slog.e(LOG_TAG, "Unable to check shell permission for user "
4308                         + userId + "\n\t" + Debug.getCallers(3));
4309             }
4310         }
4311     }
4312 
4313     private boolean checkCrossUserPermission(int callingUid, @UserIdInt int callingUserId,
4314             @UserIdInt int userId, boolean requireFullPermission) {
4315         if (userId == callingUserId) {
4316             return true;
4317         }
4318         if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4319             return true;
4320         }
4321         if (requireFullPermission) {
4322             return checkCallingOrSelfPermission(
4323                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4324         }
4325         return checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4326                 || checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS);
4327     }
4328 
4329     private boolean checkCallingOrSelfPermission(String permission) {
4330         return mContext.checkCallingOrSelfPermission(permission)
4331                 == PackageManager.PERMISSION_GRANTED;
4332     }
4333 
4334     @NonNull
4335     private static String buildInvalidCrossUserPermissionMessage(int callingUid,
4336             @UserIdInt int userId, @Nullable String message, boolean requireFullPermission) {
4337         StringBuilder builder = new StringBuilder();
4338         if (message != null) {
4339             builder.append(message);
4340             builder.append(": ");
4341         }
4342         builder.append("UID ");
4343         builder.append(callingUid);
4344         builder.append(" requires ");
4345         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4346         if (!requireFullPermission) {
4347             builder.append(" or ");
4348             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4349         }
4350         builder.append(" to access user ");
4351         builder.append(userId);
4352         builder.append(".");
4353         return builder.toString();
4354     }
4355 
4356     @GuardedBy("mLock")
4357     private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) {
4358         int size = 0;
4359         for (final Permission permission : mRegistry.getPermissions()) {
4360             size += permissionTree.calculateFootprint(permission);
4361         }
4362         return size;
4363     }
4364 
4365     @GuardedBy("mLock")
4366     private void enforcePermissionCapLocked(PermissionInfo info, Permission tree) {
4367         // We calculate the max size of permissions defined by this uid and throw
4368         // if that plus the size of 'info' would exceed our stated maximum.
4369         if (tree.getUid() != Process.SYSTEM_UID) {
4370             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4371             if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
4372                 throw new SecurityException("Permission tree size cap exceeded");
4373             }
4374         }
4375     }
4376 
4377     @Override
4378     public void onSystemReady() {
4379         // Now that we've scanned all packages, and granted any default
4380         // permissions, ensure permissions are updated. Beware of dragons if you
4381         // try optimizing this.
4382         updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);
4383 
4384         final PermissionPolicyInternal permissionPolicyInternal = LocalServices.getService(
4385                 PermissionPolicyInternal.class);
4386         permissionPolicyInternal.setOnInitializedCallback(userId ->
4387                 // The SDK updated case is already handled when we run during the ctor.
4388                 updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false)
4389         );
4390 
4391         synchronized (mLock) {
4392             mSystemReady = true;
4393 
4394             if (mPrivappPermissionsViolations != null) {
4395                 throw new IllegalStateException("Signature|privileged permissions not in "
4396                         + "privapp-permissions allowlist: " + mPrivappPermissionsViolations);
4397             }
4398         }
4399 
4400         mPermissionControllerManager = new PermissionControllerManager(
4401                 mContext, PermissionThread.getHandler());
4402         mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);    }
4403 
4404     private static String getVolumeUuidForPackage(AndroidPackage pkg) {
4405         if (pkg == null) {
4406             return StorageManager.UUID_PRIVATE_INTERNAL;
4407         }
4408         if (pkg.isExternalStorage()) {
4409             if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
4410                 return StorageManager.UUID_PRIMARY_PHYSICAL;
4411             } else {
4412                 return pkg.getVolumeUuid();
4413             }
4414         } else {
4415             return StorageManager.UUID_PRIVATE_INTERNAL;
4416         }
4417     }
4418 
4419     private static boolean hasPermission(AndroidPackage pkg, String permName) {
4420         if (pkg.getPermissions().isEmpty()) {
4421             return false;
4422         }
4423 
4424         for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
4425             if (pkg.getPermissions().get(i).getName().equals(permName)) {
4426                 return true;
4427             }
4428         }
4429         return false;
4430     }
4431 
4432     /**
4433      * Log that a permission request was granted/revoked.
4434      *
4435      * @param action the action performed
4436      * @param name name of the permission
4437      * @param packageName package permission is for
4438      */
4439     private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
4440         final LogMaker log = new LogMaker(action);
4441         log.setPackageName(packageName);
4442         log.addTaggedData(MetricsProto.MetricsEvent.FIELD_PERMISSION, name);
4443 
4444         mMetricsLogger.write(log);
4445     }
4446 
4447     @GuardedBy("mLock")
4448     @Nullable
4449     private UidPermissionState getUidStateLocked(@NonNull PackageStateInternal ps,
4450             @UserIdInt int userId) {
4451         return getUidStateLocked(ps.getAppId(), userId);
4452     }
4453 
4454     @GuardedBy("mLock")
4455     @Nullable
4456     private UidPermissionState getUidStateLocked(@NonNull AndroidPackage pkg,
4457             @UserIdInt int userId) {
4458         return getUidStateLocked(pkg.getUid(), userId);
4459     }
4460 
4461     @GuardedBy("mLock")
4462     @Nullable
4463     private UidPermissionState getUidStateLocked(@AppIdInt int appId, @UserIdInt int userId) {
4464         final UserPermissionState userState = mState.getUserState(userId);
4465         if (userState == null) {
4466             return null;
4467         }
4468         return userState.getUidState(appId);
4469     }
4470 
4471     private void removeUidStateAndResetPackageInstallPermissionsFixed(@AppIdInt int appId,
4472             @NonNull String packageName, @UserIdInt int userId) {
4473         synchronized (mLock) {
4474             final UserPermissionState userState = mState.getUserState(userId);
4475             if (userState == null) {
4476                 return;
4477             }
4478             userState.removeUidState(appId);
4479             userState.setInstallPermissionsFixed(packageName, false);
4480         }
4481     }
4482 
4483     @Override
4484     public void readLegacyPermissionStateTEMP() {
4485         final int[] userIds = getAllUserIds();
4486         mPackageManagerInt.forEachPackageState(ps -> {
4487             final int appId = ps.getAppId();
4488             final LegacyPermissionState legacyState;
4489             if (ps.hasSharedUser()) {
4490                 final int sharedUserId = ps.getSharedUserAppId();
4491                 SharedUserApi sharedUserApi = mPackageManagerInt.getSharedUserApi(sharedUserId);
4492                 if (sharedUserApi == null) {
4493                     Slog.wtf(TAG, "Missing shared user Api for " + sharedUserId);
4494                     return;
4495                 }
4496                 legacyState = sharedUserApi.getSharedUserLegacyPermissionState();
4497             } else {
4498                 legacyState = ps.getLegacyPermissionState();
4499             }
4500             synchronized (mLock) {
4501                 for (final int userId : userIds) {
4502                     final UserPermissionState userState = mState.getOrCreateUserState(userId);
4503 
4504                     userState.setInstallPermissionsFixed(ps.getPackageName(),
4505                             ps.isInstallPermissionsFixed());
4506                     final UidPermissionState uidState = userState.getOrCreateUidState(appId);
4507                     uidState.reset();
4508                     uidState.setMissing(legacyState.isMissing(userId));
4509                     readLegacyPermissionStatesLocked(uidState,
4510                             legacyState.getPermissionStates(userId));
4511                 }
4512             }
4513         });
4514     }
4515 
4516     @GuardedBy("mLock")
4517     private void readLegacyPermissionStatesLocked(@NonNull UidPermissionState uidState,
4518             @NonNull Collection<LegacyPermissionState.PermissionState> permissionStates) {
4519         for (final LegacyPermissionState.PermissionState permissionState : permissionStates) {
4520             final String permissionName = permissionState.getName();
4521             final Permission permission = mRegistry.getPermission(permissionName);
4522             if (permission == null) {
4523                 Slog.w(TAG, "Unknown permission: " + permissionName);
4524                 continue;
4525             }
4526             uidState.putPermissionState(permission, permissionState.isGranted(),
4527                     permissionState.getFlags());
4528         }
4529     }
4530 
4531     @Override
4532     public void writeLegacyPermissionStateTEMP() {
4533         final int[] userIds;
4534         synchronized (mLock) {
4535             userIds = mState.getUserIds();
4536         }
4537         mPackageManagerInt.forEachPackageSetting(ps -> {
4538             ps.setInstallPermissionsFixed(false);
4539             final LegacyPermissionState legacyState;
4540             if (ps.hasSharedUser()) {
4541                 final int sharedUserId = ps.getSharedUserAppId();
4542                 SharedUserApi sharedUserApi = mPackageManagerInt.getSharedUserApi(sharedUserId);
4543                 if (sharedUserApi == null) {
4544                     Slog.wtf(TAG, "Missing shared user Api for " + sharedUserId);
4545                     return;
4546                 }
4547                 legacyState = sharedUserApi.getSharedUserLegacyPermissionState();
4548             } else {
4549                 legacyState = ps.getLegacyPermissionState();
4550             }
4551             legacyState.reset();
4552             final int appId = ps.getAppId();
4553 
4554             synchronized (mLock) {
4555                 for (final int userId : userIds) {
4556                     final UserPermissionState userState = mState.getUserState(userId);
4557                     if (userState == null) {
4558                         Slog.e(TAG, "Missing user state for " + userId);
4559                         continue;
4560                     }
4561 
4562                     if (userState.areInstallPermissionsFixed(ps.getPackageName())) {
4563                         ps.setInstallPermissionsFixed(true);
4564                     }
4565 
4566                     final UidPermissionState uidState = userState.getUidState(appId);
4567                     if (uidState == null) {
4568                         Slog.e(TAG, "Missing permission state for " + ps.getPackageName()
4569                                 + " and user " + userId);
4570                         continue;
4571                     }
4572 
4573                     legacyState.setMissing(uidState.isMissing(), userId);
4574                     final List<PermissionState> permissionStates = uidState.getPermissionStates();
4575                     final int permissionStatesSize = permissionStates.size();
4576                     for (int i = 0; i < permissionStatesSize; i++) {
4577                         final PermissionState permissionState = permissionStates.get(i);
4578 
4579                         final LegacyPermissionState.PermissionState legacyPermissionState =
4580                                 new LegacyPermissionState.PermissionState(permissionState.getName(),
4581                                         permissionState.getPermission().isRuntime(),
4582                                         permissionState.isGranted(), permissionState.getFlags());
4583                         legacyState.putPermissionState(legacyPermissionState, userId);
4584                     }
4585                 }
4586             }
4587         });
4588     }
4589 
4590     @Override
4591     public void readLegacyPermissionsTEMP(
4592             @NonNull LegacyPermissionSettings legacyPermissionSettings) {
4593         for (int readPermissionOrPermissionTree = 0; readPermissionOrPermissionTree < 2;
4594                 readPermissionOrPermissionTree++) {
4595             final List<LegacyPermission> legacyPermissions = readPermissionOrPermissionTree == 0
4596                     ? legacyPermissionSettings.getPermissions()
4597                     : legacyPermissionSettings.getPermissionTrees();
4598             synchronized (mLock) {
4599                 final int legacyPermissionsSize = legacyPermissions.size();
4600                 for (int i = 0; i < legacyPermissionsSize; i++) {
4601                     final LegacyPermission legacyPermission = legacyPermissions.get(i);
4602                     final Permission permission = new Permission(
4603                             legacyPermission.getPermissionInfo(), legacyPermission.getType());
4604                     if (readPermissionOrPermissionTree == 0) {
4605                         // Config permissions are currently read in PermissionManagerService
4606                         // constructor. The old behavior was to add other attributes to the config
4607                         // permission in LegacyPermission.read(), so equivalently we can add the
4608                         // GIDs to the new permissions here, since config permissions created in
4609                         // PermissionManagerService constructor get only their names and GIDs there.
4610                         final Permission configPermission = mRegistry.getPermission(
4611                                 permission.getName());
4612                         if (configPermission != null
4613                                 && configPermission.getType() == Permission.TYPE_CONFIG) {
4614                             permission.setGids(configPermission.getRawGids(),
4615                                     configPermission.areGidsPerUser());
4616                         }
4617                         mRegistry.addPermission(permission);
4618                     } else {
4619                         mRegistry.addPermissionTree(permission);
4620                     }
4621                 }
4622             }
4623         }
4624     }
4625 
4626     @Override
4627     public void writeLegacyPermissionsTEMP(
4628             @NonNull LegacyPermissionSettings legacyPermissionSettings) {
4629         for (int writePermissionOrPermissionTree = 0; writePermissionOrPermissionTree < 2;
4630                 writePermissionOrPermissionTree++) {
4631             final List<LegacyPermission> legacyPermissions = new ArrayList<>();
4632             synchronized (mLock) {
4633                 final Collection<Permission> permissions = writePermissionOrPermissionTree == 0
4634                         ? mRegistry.getPermissions() : mRegistry.getPermissionTrees();
4635                 for (final Permission permission : permissions) {
4636                     // We don't need to provide UID and GIDs, which are only retrieved when dumping.
4637                     final LegacyPermission legacyPermission = new LegacyPermission(
4638                             permission.getPermissionInfo(), permission.getType(), 0,
4639                             EmptyArray.INT);
4640                     legacyPermissions.add(legacyPermission);
4641                 }
4642             }
4643             if (writePermissionOrPermissionTree == 0) {
4644                 legacyPermissionSettings.replacePermissions(legacyPermissions);
4645             } else {
4646                 legacyPermissionSettings.replacePermissionTrees(legacyPermissions);
4647             }
4648         }
4649     }
4650 
4651     @Nullable
4652     @Override
4653     public String getDefaultPermissionGrantFingerprint(@UserIdInt int userId) {
4654         return mPackageManagerInt.isPermissionUpgradeNeeded(userId) ? null : Build.FINGERPRINT;
4655     }
4656 
4657     @Override
4658     public void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint,
4659             @UserIdInt int userId) {
4660         // Ignored - default permission grant here shares the same version with runtime permission
4661         // upgrade, and the new version is set by that later.
4662     }
4663 
4664     private void onPackageAddedInternal(@NonNull PackageState packageState,
4665             @NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) {
4666         if (!pkg.getAdoptPermissions().isEmpty()) {
4667             // This package wants to adopt ownership of permissions from
4668             // another package.
4669             for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) {
4670                 final String origName = pkg.getAdoptPermissions().get(i);
4671                 if (canAdoptPermissionsInternal(origName, pkg)) {
4672                     Slog.i(TAG, "Adopting permissions from " + origName + " to "
4673                             + pkg.getPackageName());
4674                     synchronized (mLock) {
4675                         mRegistry.transferPermissions(origName, pkg.getPackageName());
4676                     }
4677                 }
4678             }
4679         }
4680 
4681         // Don't allow ephemeral applications to define new permissions groups.
4682         if (isInstantApp) {
4683             Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
4684                     + " ignored: instant apps cannot define new permission groups.");
4685         } else {
4686             addAllPermissionGroupsInternal(pkg);
4687         }
4688 
4689         // If a permission has had its defining app changed, or it has had its protection
4690         // upgraded, we need to revoke apps that hold it
4691         final List<String> permissionsWithChangedDefinition;
4692         // Don't allow ephemeral applications to define new permissions.
4693         if (isInstantApp) {
4694             permissionsWithChangedDefinition = null;
4695             Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
4696                     + " ignored: instant apps cannot define new permissions.");
4697         } else {
4698             permissionsWithChangedDefinition = addAllPermissionsInternal(packageState, pkg);
4699         }
4700 
4701         boolean hasOldPkg = oldPkg != null;
4702         boolean hasPermissionDefinitionChanges =
4703                 !CollectionUtils.isEmpty(permissionsWithChangedDefinition);
4704         if (hasOldPkg || hasPermissionDefinitionChanges) {
4705             // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
4706             // revoke callbacks from this method might need to kill apps which need the
4707             // mPackages lock on a different thread. This would dead lock.
4708             AsyncTask.execute(() -> {
4709                 if (hasOldPkg) {
4710                     revokeRuntimePermissionsIfGroupChangedInternal(pkg, oldPkg);
4711                     revokeStoragePermissionsIfScopeExpandedInternal(pkg, oldPkg);
4712                     revokeSystemAlertWindowIfUpgradedPast23(pkg, oldPkg);
4713                 }
4714                 if (hasPermissionDefinitionChanges) {
4715                     revokeRuntimePermissionsIfPermissionDefinitionChangedInternal(
4716                             permissionsWithChangedDefinition);
4717                 }
4718             });
4719         }
4720     }
4721 
4722     private boolean canAdoptPermissionsInternal(@NonNull String oldPackageName,
4723             @NonNull AndroidPackage newPkg) {
4724         final PackageStateInternal oldPs =
4725                 mPackageManagerInt.getPackageStateInternal(oldPackageName);
4726         if (oldPs == null) {
4727             return false;
4728         }
4729         if (!oldPs.isSystem()) {
4730             Slog.w(TAG, "Unable to update from " + oldPs.getPackageName()
4731                     + " to " + newPkg.getPackageName()
4732                     + ": old package not in system partition");
4733             return false;
4734         }
4735         if (mPackageManagerInt.getPackage(oldPs.getPackageName()) != null) {
4736             Slog.w(TAG, "Unable to update from " + oldPs.getPackageName()
4737                     + " to " + newPkg.getPackageName()
4738                     + ": old package still exists");
4739             return false;
4740         }
4741         return true;
4742     }
4743 
4744     private boolean isEffectivelyGranted(PermissionState state) {
4745         final int flags = state.getFlags();
4746         final int denyMask = FLAG_PERMISSION_REVIEW_REQUIRED
4747                 | FLAG_PERMISSION_REVOKED_COMPAT
4748                 | FLAG_PERMISSION_ONE_TIME;
4749 
4750         if ((flags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4751             return true;
4752         } else if ((flags & FLAG_PERMISSION_POLICY_FIXED) != 0) {
4753             return (flags & FLAG_PERMISSION_REVOKED_COMPAT) == 0 && state.isGranted();
4754         } else if ((flags & denyMask) != 0) {
4755             return false;
4756         } else {
4757             return state.isGranted();
4758         }
4759     }
4760 
4761     /**
4762      * Merge srcState into destState. Return [granted, flags].
4763      */
4764     private Pair<Boolean, Integer> mergePermissionState(int appId,
4765             PermissionState srcState, PermissionState destState) {
4766         // This merging logic prioritizes the shared permission state (destState) over
4767         // the current package's state (srcState), because an uninstallation of a previously
4768         // unrelated app (the updated system app) should not affect the functionality of
4769         // existing apps (other apps in the shared UID group).
4770 
4771         final int userSettableMask = FLAG_PERMISSION_USER_SET
4772                 | FLAG_PERMISSION_USER_FIXED
4773                 | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;
4774 
4775         final int defaultGrantMask = FLAG_PERMISSION_GRANTED_BY_DEFAULT
4776                 | FLAG_PERMISSION_GRANTED_BY_ROLE;
4777 
4778         final int priorityFixedMask = FLAG_PERMISSION_SYSTEM_FIXED
4779                 | FLAG_PERMISSION_POLICY_FIXED;
4780 
4781         final int priorityMask = defaultGrantMask | priorityFixedMask;
4782 
4783         final int destFlags = destState.getFlags();
4784         final boolean destIsGranted = isEffectivelyGranted(destState);
4785 
4786         final int srcFlags = srcState.getFlags();
4787         final boolean srcIsGranted = isEffectivelyGranted(srcState);
4788 
4789         final int combinedFlags = destFlags | srcFlags;
4790 
4791         /* Merge flags */
4792 
4793         int newFlags = 0;
4794 
4795         // Inherit user set flags only from dest as we want to preserve the
4796         // user preference of destState, not the one of the current package.
4797         newFlags |= (destFlags & userSettableMask);
4798 
4799         // Inherit all exempt flags
4800         newFlags |= (combinedFlags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT);
4801         // If no exempt flags are set, set APPLY_RESTRICTION
4802         if ((newFlags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
4803             newFlags |= FLAG_PERMISSION_APPLY_RESTRICTION;
4804         }
4805 
4806         // Inherit all priority flags
4807         newFlags |= (combinedFlags & priorityMask);
4808 
4809         // If no priority flags are set, inherit REVOKE_WHEN_REQUESTED
4810         if ((combinedFlags & priorityMask) == 0) {
4811             newFlags |= (combinedFlags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
4812         }
4813 
4814         // Handle REVIEW_REQUIRED
4815         if ((newFlags & priorityFixedMask) == 0) {
4816             if ((newFlags & (defaultGrantMask | userSettableMask)) == 0
4817                     && NOTIFICATION_PERMISSIONS.contains(srcState.getName())) {
4818                 // For notification permissions, inherit from both states
4819                 // if no priority FIXED or DEFAULT_GRANT or USER_SET flags are set
4820                 newFlags |= (combinedFlags & FLAG_PERMISSION_REVIEW_REQUIRED);
4821             } else if ((newFlags & priorityMask) == 0) {
4822                 // Else inherit from destState if no priority flags are set
4823                 newFlags |= (destFlags & FLAG_PERMISSION_REVIEW_REQUIRED);
4824             }
4825         }
4826 
4827         /* Determine effective grant state */
4828 
4829         final boolean effectivelyGranted;
4830         if ((newFlags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4831             effectivelyGranted = true;
4832         } else if ((destFlags & FLAG_PERMISSION_POLICY_FIXED) != 0) {
4833             // If this flag comes from destState, preserve its state
4834             effectivelyGranted = destIsGranted;
4835         } else if ((srcFlags & FLAG_PERMISSION_POLICY_FIXED) != 0) {
4836             effectivelyGranted = destIsGranted || srcIsGranted;
4837             // If this flag comes from srcState, preserve flag only if
4838             // there is no conflict
4839             if (destIsGranted != srcIsGranted) {
4840                 newFlags &= ~FLAG_PERMISSION_POLICY_FIXED;
4841             }
4842         } else if ((destFlags & defaultGrantMask) != 0) {
4843             // If a permission state has default grant flags and is not
4844             // granted, this meant user has overridden the grant state.
4845             // Respect the user's preference on destState.
4846             // Due to this reason, if this flag comes from destState,
4847             // preserve its state
4848             effectivelyGranted = destIsGranted;
4849         } else if ((srcFlags & defaultGrantMask) != 0) {
4850             effectivelyGranted = destIsGranted || srcIsGranted;
4851         } else if ((destFlags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
4852             // Similar reason to defaultGrantMask, if this flag comes
4853             // from destState, preserve its state
4854             effectivelyGranted = destIsGranted;
4855         } else if ((srcFlags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
4856             effectivelyGranted = destIsGranted || srcIsGranted;
4857             // If this flag comes from srcState, remove this flag if
4858             // destState is already granted to prevent revocation.
4859             if (destIsGranted) {
4860                 newFlags &= ~FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
4861             }
4862         } else {
4863             // If still not determined, fallback to destState.
4864             effectivelyGranted = destIsGranted;
4865         }
4866 
4867         /* Post-processing / fix ups */
4868 
4869         if (!effectivelyGranted) {
4870             // If not effectively granted, inherit AUTO_REVOKED
4871             newFlags |= (combinedFlags & FLAG_PERMISSION_AUTO_REVOKED);
4872 
4873             // REVOKE_WHEN_REQUESTED make no sense when denied
4874             newFlags &= ~FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
4875         } else {
4876             // REVIEW_REQUIRED make no sense when granted
4877             newFlags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
4878         }
4879 
4880         if (effectivelyGranted != destIsGranted) {
4881             // Remove user set flags if state changes
4882             newFlags &= ~userSettableMask;
4883         }
4884 
4885         // Fix permission state based on targetSdk of the shared UID
4886         final boolean newGrantState;
4887         if (!effectivelyGranted && isPermissionSplitFromNonRuntime(
4888                 srcState.getName(),
4889                 mPackageManagerInt.getUidTargetSdkVersion(appId))) {
4890             // Even though effectively denied, it has to be set to granted
4891             // for backwards compatibility
4892             newFlags |= FLAG_PERMISSION_REVOKED_COMPAT;
4893             newGrantState = true;
4894         } else {
4895             // Either it's effectively granted, or it targets a high enough API level
4896             // to handle this permission properly
4897             newGrantState = effectivelyGranted;
4898         }
4899 
4900         return new Pair<>(newGrantState, newFlags);
4901     }
4902 
4903     /**
4904      * This method handles permission migration of packages leaving/joining shared UID
4905      */
4906     private void handleAppIdMigration(@NonNull AndroidPackage pkg, int previousAppId) {
4907         final PackageStateInternal ps =
4908                 mPackageManagerInt.getPackageStateInternal(pkg.getPackageName());
4909 
4910         if (ps.hasSharedUser()) {
4911             // The package is joining a shared user group. This can only happen when a system
4912             // app left shared UID with an update, and then the update is uninstalled.
4913             // If no apps remain in its original shared UID group, clone the current
4914             // permission state to the shared appId; or else, merge the current permission
4915             // state into the shared UID state.
4916 
4917             synchronized (mLock) {
4918                 for (final int userId : getAllUserIds()) {
4919                     final UserPermissionState userState = mState.getOrCreateUserState(userId);
4920 
4921                     // This is the permission state the package was using
4922                     final UidPermissionState uidState = userState.getUidState(previousAppId);
4923                     if (uidState == null) {
4924                         continue;
4925                     }
4926 
4927                     // This is the shared UID permission state the package wants to join
4928                     final UidPermissionState sharedUidState = userState.getUidState(ps.getAppId());
4929                     if (sharedUidState == null) {
4930                         // No apps remain in the shared UID group, clone permissions
4931                         userState.createUidStateWithExisting(ps.getAppId(), uidState);
4932                     } else {
4933                         final List<PermissionState> states = uidState.getPermissionStates();
4934                         final int count = states.size();
4935                         for (int i = 0; i < count; ++i) {
4936                             final PermissionState srcState = states.get(i);
4937                             final PermissionState destState =
4938                                     sharedUidState.getPermissionState(srcState.getName());
4939                             if (destState != null) {
4940                                 // Merge the 2 permission states
4941                                 Pair<Boolean, Integer> newState =
4942                                         mergePermissionState(ps.getAppId(), srcState, destState);
4943                                 sharedUidState.putPermissionState(srcState.getPermission(),
4944                                         newState.first, newState.second);
4945                             } else {
4946                                 // Simply copy the permission state over
4947                                 sharedUidState.putPermissionState(srcState.getPermission(),
4948                                         srcState.isGranted(), srcState.getFlags());
4949                             }
4950                         }
4951                     }
4952 
4953                     // Remove permissions for the previous appId
4954                     userState.removeUidState(previousAppId);
4955                 }
4956             }
4957         } else {
4958             // The package is migrating out of a shared user group.
4959             // Operations we need to do before calling updatePermissions():
4960             // - Retrieve the original uid permission state and create a copy of it as the
4961             //   new app's uid state. The new permission state will be properly updated in
4962             //   updatePermissions().
4963             // - Remove the app from the original shared user group. Other apps in the shared
4964             //   user group will perceive as if the original app is uninstalled.
4965 
4966             final List<AndroidPackage> origSharedUserPackages =
4967                     mPackageManagerInt.getPackagesForAppId(previousAppId);
4968 
4969             synchronized (mLock) {
4970                 for (final int userId : getAllUserIds()) {
4971                     // Retrieve the original uid state
4972                     final UserPermissionState userState = mState.getUserState(userId);
4973                     if (userState == null) {
4974                         continue;
4975                     }
4976                     final UidPermissionState prevUidState = userState.getUidState(previousAppId);
4977                     if (prevUidState == null) {
4978                         continue;
4979                     }
4980 
4981                     // Insert new uid state by cloning the original one
4982                     userState.createUidStateWithExisting(ps.getAppId(), prevUidState);
4983 
4984                     // Remove original app ID from original shared user group
4985                     // Should match the implementation of onPackageUninstalledInternal(...)
4986                     if (origSharedUserPackages.isEmpty()) {
4987                         removeUidStateAndResetPackageInstallPermissionsFixed(
4988                                 previousAppId, pkg.getPackageName(), userId);
4989                     } else {
4990                         revokeSharedUserPermissionsForLeavingPackageInternal(pkg, previousAppId,
4991                                 origSharedUserPackages, userId);
4992                     }
4993                 }
4994             }
4995         }
4996     }
4997 
4998     private void onPackageInstalledInternal(@NonNull AndroidPackage pkg, int previousAppId,
4999             @NonNull PermissionManagerServiceInternal.PackageInstalledParams params,
5000             @UserIdInt int[] userIds) {
5001         if (previousAppId != INVALID_UID) {
5002             handleAppIdMigration(pkg, previousAppId);
5003         }
5004         updatePermissions(pkg.getPackageName(), pkg);
5005         for (final int userId : userIds) {
5006             addAllowlistedRestrictedPermissionsInternal(pkg,
5007                     params.getAllowlistedRestrictedPermissions(),
5008                     FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
5009             grantRequestedPermissionsInternal(pkg, params.getPermissionStates(), userId);
5010         }
5011     }
5012 
5013     private void addAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
5014             @NonNull List<String> allowlistedRestrictedPermissions,
5015             @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId) {
5016         List<String> permissions = getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId);
5017         if (permissions != null) {
5018             ArraySet<String> permissionSet = new ArraySet<>(permissions);
5019             permissionSet.addAll(allowlistedRestrictedPermissions);
5020             permissions = new ArrayList<>(permissionSet);
5021         } else {
5022             permissions = allowlistedRestrictedPermissions;
5023         }
5024         setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId);
5025     }
5026 
5027     private void onPackageRemovedInternal(@NonNull AndroidPackage pkg) {
5028         removeAllPermissionsInternal(pkg);
5029     }
5030 
5031     private void onPackageUninstalledInternal(@NonNull String packageName, int appId,
5032             @NonNull PackageState packageState, @Nullable AndroidPackage pkg,
5033             @NonNull List<AndroidPackage> sharedUserPkgs, @UserIdInt int[] userIds) {
5034         // TODO: Handle the case when a system app upgrade is uninstalled and need to rejoin
5035         //  a shared UID permission state.
5036 
5037         // System packages should always have an available APK.
5038         if (packageState.isSystem() && pkg != null
5039                 // We may be fully removing invalid system packages during boot, and in that case we
5040                 // do want to remove their permission state. So make sure that the package is only
5041                 // being marked as uninstalled instead of fully removed.
5042                 && mPackageManagerInt.getPackage(packageName) != null) {
5043             // If we are only marking a system package as uninstalled, we need to keep its
5044             // pregranted permission state so that it still works once it gets reinstalled, thus
5045             // only reset the user modifications to its permission state.
5046             for (final int userId : userIds) {
5047                 resetRuntimePermissionsInternal(pkg, userId);
5048             }
5049             return;
5050         }
5051         updatePermissions(packageName, null);
5052         for (final int userId : userIds) {
5053             if (sharedUserPkgs.isEmpty()) {
5054                 removeUidStateAndResetPackageInstallPermissionsFixed(appId, packageName, userId);
5055             } else {
5056                 // Remove permissions associated with package. Since runtime
5057                 // permissions are per user we have to kill the removed package
5058                 // or packages running under the shared user of the removed
5059                 // package if revoking the permissions requested only by the removed
5060                 // package is successful and this causes a change in gids.
5061                 revokeSharedUserPermissionsForLeavingPackageInternal(pkg, appId, sharedUserPkgs,
5062                         userId);
5063             }
5064         }
5065     }
5066 
5067     @NonNull
5068     @Override
5069     public List<LegacyPermission> getLegacyPermissions() {
5070         synchronized (mLock) {
5071             final List<LegacyPermission> legacyPermissions = new ArrayList<>();
5072             for (final Permission permission : mRegistry.getPermissions()) {
5073                 final LegacyPermission legacyPermission = new LegacyPermission(
5074                         permission.getPermissionInfo(), permission.getType(), permission.getUid(),
5075                         permission.getRawGids());
5076                 legacyPermissions.add(legacyPermission);
5077             }
5078             return legacyPermissions;
5079         }
5080     }
5081 
5082     @Override
5083     public Map<String, Set<String>> getAllAppOpPermissionPackages() {
5084         synchronized (mLock) {
5085             final ArrayMap<String, ArraySet<String>> appOpPermissionPackages =
5086                     mRegistry.getAllAppOpPermissionPackages();
5087             final Map<String, Set<String>> deepClone = new ArrayMap<>();
5088             final int appOpPermissionPackagesSize = appOpPermissionPackages.size();
5089             for (int i = 0; i < appOpPermissionPackagesSize; i++) {
5090                 final String appOpPermission = appOpPermissionPackages.keyAt(i);
5091                 final ArraySet<String> packageNames = appOpPermissionPackages.valueAt(i);
5092                 deepClone.put(appOpPermission, new ArraySet<>(packageNames));
5093             }
5094             return deepClone;
5095         }
5096     }
5097 
5098     @NonNull
5099     @Override
5100     public LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId) {
5101         final LegacyPermissionState legacyState = new LegacyPermissionState();
5102         synchronized (mLock) {
5103             final int[] userIds = mState.getUserIds();
5104             for (final int userId : userIds) {
5105                 final UidPermissionState uidState = getUidStateLocked(appId, userId);
5106                 if (uidState == null) {
5107                     Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID "
5108                             + userId);
5109                     continue;
5110                 }
5111 
5112                 final List<PermissionState> permissionStates = uidState.getPermissionStates();
5113                 final int permissionStatesSize = permissionStates.size();
5114                 for (int i = 0; i < permissionStatesSize; i++) {
5115                     final PermissionState permissionState = permissionStates.get(i);
5116 
5117                     final LegacyPermissionState.PermissionState legacyPermissionState =
5118                             new LegacyPermissionState.PermissionState(permissionState.getName(),
5119                                     permissionState.getPermission().isRuntime(),
5120                                     permissionState.isGranted(), permissionState.getFlags());
5121                     legacyState.putPermissionState(legacyPermissionState, userId);
5122                 }
5123             }
5124         }
5125         return legacyState;
5126     }
5127 
5128     @NonNull
5129     @Override
5130     public int[] getGidsForUid(int uid) {
5131         final int appId = UserHandle.getAppId(uid);
5132         final int userId = UserHandle.getUserId(uid);
5133         synchronized (mLock) {
5134             final UidPermissionState uidState = getUidStateLocked(appId, userId);
5135             if (uidState == null) {
5136                 Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID "
5137                         + userId);
5138                 return EMPTY_INT_ARRAY;
5139             }
5140             return uidState.computeGids(mGlobalGids, userId);
5141         }
5142     }
5143 
5144     @Override
5145     public boolean isPermissionsReviewRequired(@NonNull String packageName,
5146             @UserIdInt int userId) {
5147         Objects.requireNonNull(packageName, "packageName");
5148         // TODO(b/173235285): Some caller may pass USER_ALL as userId.
5149         //Preconditions.checkArgumentNonnegative(userId, "userId");
5150         return isPermissionsReviewRequiredInternal(packageName, userId);
5151     }
5152 
5153     @NonNull
5154     @Override
5155     public Set<String> getInstalledPermissions(@NonNull String packageName) {
5156         Objects.requireNonNull(packageName, "packageName");
5157         final Set<String> installedPermissions = new ArraySet<>();
5158         synchronized (mLock) {
5159             for (final Permission permission : mRegistry.getPermissions()) {
5160                 if (Objects.equals(permission.getPackageName(), packageName)) {
5161                     installedPermissions.add(permission.getName());
5162                 }
5163             }
5164         }
5165         return installedPermissions;
5166     }
5167 
5168     @NonNull
5169     @Override
5170     public Set<String> getGrantedPermissions(@NonNull String packageName, @UserIdInt int userId) {
5171         Objects.requireNonNull(packageName, "packageName");
5172         Preconditions.checkArgumentNonNegative(userId, "userId");
5173         return getGrantedPermissionsInternal(packageName, userId);
5174     }
5175 
5176     @NonNull
5177     @Override
5178     public int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) {
5179         Objects.requireNonNull(permissionName, "permissionName");
5180         Preconditions.checkArgumentNonNegative(userId, "userId");
5181         return getPermissionGidsInternal(permissionName, userId);
5182     }
5183 
5184     @NonNull
5185     @Override
5186     public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
5187         Objects.requireNonNull(permissionName, "permissionName");
5188         return PermissionManagerServiceImpl.this.getAppOpPermissionPackagesInternal(permissionName);
5189     }
5190 
5191     @Override
5192     public void onStorageVolumeMounted(@Nullable String volumeUuid, boolean fingerprintChanged) {
5193         updateAllPermissions(volumeUuid, fingerprintChanged);
5194     }
5195 
5196     @Override
5197     public void resetRuntimePermissions(@NonNull AndroidPackage pkg, @UserIdInt int userId) {
5198         Objects.requireNonNull(pkg, "pkg");
5199         Preconditions.checkArgumentNonNegative(userId, "userId");
5200         resetRuntimePermissionsInternal(pkg, userId);
5201     }
5202 
5203     @Override
5204     public void resetRuntimePermissionsForUser(@UserIdInt int userId) {
5205         Preconditions.checkArgumentNonNegative(userId, "userId");
5206         resetRuntimePermissionsInternal(null, userId);
5207     }
5208 
5209     @Override
5210     public Permission getPermissionTEMP(String permName) {
5211         synchronized (mLock) {
5212             return mRegistry.getPermission(permName);
5213         }
5214     }
5215 
5216     @NonNull
5217     @Override
5218     public List<PermissionInfo> getAllPermissionsWithProtection(
5219             @PermissionInfo.Protection int protection) {
5220         List<PermissionInfo> matchingPermissions = new ArrayList<>();
5221 
5222         synchronized (mLock) {
5223             for (final Permission permission : mRegistry.getPermissions()) {
5224                 if (permission.getProtection() == protection) {
5225                     matchingPermissions.add(permission.generatePermissionInfo(0));
5226                 }
5227             }
5228         }
5229 
5230         return matchingPermissions;
5231     }
5232 
5233     @NonNull
5234     @Override
5235     public List<PermissionInfo> getAllPermissionsWithProtectionFlags(
5236             @PermissionInfo.ProtectionFlags int protectionFlags) {
5237         List<PermissionInfo> matchingPermissions = new ArrayList<>();
5238 
5239         synchronized (mLock) {
5240             for (final Permission permission : mRegistry.getPermissions()) {
5241                 if ((permission.getProtectionFlags() & protectionFlags) == protectionFlags) {
5242                     matchingPermissions.add(permission.generatePermissionInfo(0));
5243                 }
5244             }
5245         }
5246 
5247         return matchingPermissions;
5248     }
5249 
5250     @Override
5251     public void onUserCreated(@UserIdInt int userId) {
5252         Preconditions.checkArgumentNonNegative(userId, "userId");
5253         // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
5254         updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, true);
5255     }
5256 
5257     @Override
5258     public void onPackageAdded(@NonNull PackageState packageState, boolean isInstantApp,
5259                     @Nullable AndroidPackage oldPkg) {
5260         Objects.requireNonNull(packageState);
5261         var pkg = packageState.getAndroidPackage();
5262         Objects.requireNonNull(pkg);
5263         onPackageAddedInternal(packageState, pkg, isInstantApp, oldPkg);
5264     }
5265 
5266     @Override
5267     public void onPackageInstalled(@NonNull AndroidPackage pkg, int previousAppId,
5268             @NonNull PermissionManagerServiceInternal.PackageInstalledParams params,
5269             @UserIdInt int userId) {
5270         Objects.requireNonNull(pkg, "pkg");
5271         Objects.requireNonNull(params, "params");
5272         Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
5273                 || userId == UserHandle.USER_ALL, "userId");
5274         final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds()
5275                 : new int[] { userId };
5276         onPackageInstalledInternal(pkg, previousAppId, params, userIds);
5277     }
5278 
5279     @Override
5280     public void onPackageRemoved(@NonNull AndroidPackage pkg) {
5281         Objects.requireNonNull(pkg);
5282         onPackageRemovedInternal(pkg);
5283     }
5284 
5285     @Override
5286     public void onPackageUninstalled(@NonNull String packageName, int appId,
5287             @NonNull PackageState packageState, @Nullable AndroidPackage pkg,
5288             @NonNull List<AndroidPackage> sharedUserPkgs, @CanBeALL @UserIdInt int userId) {
5289         Objects.requireNonNull(packageState, "packageState");
5290         Objects.requireNonNull(packageName, "packageName");
5291         Objects.requireNonNull(sharedUserPkgs, "sharedUserPkgs");
5292         Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
5293                 || userId == UserHandle.USER_ALL, "userId");
5294         final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds()
5295                 : new int[] { userId };
5296         onPackageUninstalledInternal(packageName, appId, packageState, pkg, sharedUserPkgs,
5297                 userIds);
5298     }
5299 
5300     /**
5301      * Callbacks invoked when interesting actions have been taken on a permission.
5302      * <p>
5303      * NOTE: The current arguments are merely to support the existing use cases. This
5304      * needs to be properly thought out with appropriate arguments for each of the
5305      * callback methods.
5306      */
5307     private static class PermissionCallback {
5308         public void onGidsChanged(@AppIdInt int appId, @UserIdInt int userId) {}
5309         public void onPermissionChanged() {}
5310         public void onPermissionGranted(int uid, @UserIdInt int userId) {}
5311         public void onInstallPermissionGranted() {}
5312         public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason) {
5313             onPermissionRevoked(uid, userId, reason, false, null);
5314         }
5315         public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason,
5316                 boolean overrideKill, @Nullable String permissionName) {}
5317         public void onInstallPermissionRevoked() {}
5318         public void onPermissionUpdated(@UserIdInt int[] userIds, boolean sync, int appId) {}
5319         public void onPermissionRemoved() {}
5320         public void onInstallPermissionUpdated() {}
5321     }
5322 
5323     private static final class OnPermissionChangeListeners extends Handler {
5324         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
5325 
5326         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
5327                 new RemoteCallbackList<>();
5328 
5329         OnPermissionChangeListeners(Looper looper) {
5330             super(looper);
5331         }
5332 
5333         @Override
5334         public void handleMessage(Message msg) {
5335             switch (msg.what) {
5336                 case MSG_ON_PERMISSIONS_CHANGED: {
5337                     final int uid = msg.arg1;
5338                     handleOnPermissionsChanged(uid);
5339                 } break;
5340             }
5341         }
5342 
5343         public void addListener(IOnPermissionsChangeListener listener) {
5344             mPermissionListeners.register(listener);
5345         }
5346 
5347         public void removeListener(IOnPermissionsChangeListener listener) {
5348             mPermissionListeners.unregister(listener);
5349         }
5350 
5351         public void onPermissionsChanged(int uid) {
5352             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
5353                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
5354             }
5355         }
5356 
5357         private void handleOnPermissionsChanged(int uid) {
5358             final int count = mPermissionListeners.beginBroadcast();
5359             try {
5360                 for (int i = 0; i < count; i++) {
5361                     IOnPermissionsChangeListener callback = mPermissionListeners
5362                             .getBroadcastItem(i);
5363                     try {
5364                         callback.onPermissionsChanged(uid,
5365                                 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
5366                     } catch (RemoteException e) {
5367                         Log.e(TAG, "Permission listener is dead", e);
5368                     }
5369                 }
5370             } finally {
5371                 mPermissionListeners.finishBroadcast();
5372             }
5373         }
5374     }
5375 }
5376