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