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