1 /*
2  * Copyright (C) 2017 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.READ_EXTERNAL_STORAGE;
20 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
21 import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
22 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
23 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
24 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
25 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
26 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
27 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
31 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
34 import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
35 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
36 
37 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
38 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
39 import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
40 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
41 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
42 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
43 
44 import static java.util.concurrent.TimeUnit.SECONDS;
45 
46 import android.Manifest;
47 import android.annotation.NonNull;
48 import android.annotation.Nullable;
49 import android.annotation.UserIdInt;
50 import android.content.Context;
51 import android.content.pm.ApplicationInfo;
52 import android.content.pm.PackageManager;
53 import android.content.pm.PackageManager.PermissionWhitelistFlags;
54 import android.content.pm.PackageManagerInternal;
55 import android.content.pm.PackageParser;
56 import android.content.pm.PackageParser.Package;
57 import android.content.pm.PermissionGroupInfo;
58 import android.content.pm.PermissionInfo;
59 import android.metrics.LogMaker;
60 import android.os.Binder;
61 import android.os.Build;
62 import android.os.Handler;
63 import android.os.HandlerThread;
64 import android.os.Process;
65 import android.os.Trace;
66 import android.os.UserHandle;
67 import android.os.UserManager;
68 import android.os.UserManagerInternal;
69 import android.os.storage.StorageManager;
70 import android.os.storage.StorageManagerInternal;
71 import android.permission.PermissionControllerManager;
72 import android.permission.PermissionManager;
73 import android.permission.PermissionManagerInternal;
74 import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
75 import android.text.TextUtils;
76 import android.util.ArrayMap;
77 import android.util.ArraySet;
78 import android.util.EventLog;
79 import android.util.Log;
80 import android.util.Slog;
81 import android.util.SparseArray;
82 import android.util.SparseBooleanArray;
83 
84 import com.android.internal.annotations.GuardedBy;
85 import com.android.internal.logging.MetricsLogger;
86 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
87 import com.android.internal.os.RoSystemProperties;
88 import com.android.internal.util.ArrayUtils;
89 import com.android.internal.util.function.pooled.PooledLambda;
90 import com.android.server.FgThread;
91 import com.android.server.LocalServices;
92 import com.android.server.ServiceThread;
93 import com.android.server.SystemConfig;
94 import com.android.server.Watchdog;
95 import com.android.server.pm.PackageManagerServiceUtils;
96 import com.android.server.pm.PackageSetting;
97 import com.android.server.pm.SharedUserSetting;
98 import com.android.server.pm.UserManagerService;
99 import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
100 import com.android.server.pm.permission.PermissionsState.PermissionState;
101 import com.android.server.policy.PermissionPolicyInternal;
102 import com.android.server.policy.SoftRestrictedPermissionPolicy;
103 
104 import libcore.util.EmptyArray;
105 
106 import java.util.ArrayList;
107 import java.util.Collection;
108 import java.util.HashMap;
109 import java.util.Iterator;
110 import java.util.List;
111 import java.util.Map;
112 import java.util.Objects;
113 import java.util.Set;
114 import java.util.concurrent.CompletableFuture;
115 import java.util.concurrent.ExecutionException;
116 import java.util.concurrent.TimeUnit;
117 import java.util.concurrent.TimeoutException;
118 
119 /**
120  * Manages all permissions and handles permissions related tasks.
121  */
122 public class PermissionManagerService {
123     private static final String TAG = "PackageManager";
124 
125     /** Permission grant: not grant the permission. */
126     private static final int GRANT_DENIED = 1;
127     /** Permission grant: grant the permission as an install permission. */
128     private static final int GRANT_INSTALL = 2;
129     /** Permission grant: grant the permission as a runtime one. */
130     private static final int GRANT_RUNTIME = 3;
131     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
132     private static final int GRANT_UPGRADE = 4;
133 
134     private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
135 
136     /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
137     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
138     /** Empty array to avoid allocations */
139     private static final int[] EMPTY_INT_ARRAY = new int[0];
140 
141     /**
142      * When these flags are set, the system should not automatically modify the permission grant
143      * state.
144      */
145     private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
146             | FLAG_PERMISSION_POLICY_FIXED
147             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
148 
149     /** Permission flags set by the user */
150     private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
151             | FLAG_PERMISSION_USER_FIXED;
152 
153     /** If the permission of the value is granted, so is the key */
154     private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
155 
156     static {
FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)157         FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
158                 Manifest.permission.ACCESS_FINE_LOCATION);
FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS, Manifest.permission.INTERACT_ACROSS_USERS_FULL)159         FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
160                 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
161     }
162 
163     /** Lock to protect internal data access */
164     private final Object mLock;
165 
166     /** Internal connection to the package manager */
167     private final PackageManagerInternal mPackageManagerInt;
168 
169     /** Internal connection to the user manager */
170     private final UserManagerInternal mUserManagerInt;
171 
172     /** Permission controller: User space permission management */
173     private PermissionControllerManager mPermissionControllerManager;
174 
175     /** Default permission policy to provide proper behaviour out-of-the-box */
176     private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
177 
178     /**
179      * Built-in permissions. Read from system configuration files. Mapping is from
180      * UID to permission name.
181      */
182     private final SparseArray<ArraySet<String>> mSystemPermissions;
183 
184     /** Built-in group IDs given to all packages. Read from system configuration files. */
185     private final int[] mGlobalGids;
186 
187     private final HandlerThread mHandlerThread;
188     private final Handler mHandler;
189     private final Context mContext;
190     private final MetricsLogger mMetricsLogger = new MetricsLogger();
191 
192     /** Internal storage for permissions and related settings */
193     @GuardedBy("mLock")
194     private final PermissionSettings mSettings;
195 
196     @GuardedBy("mLock")
197     private ArraySet<String> mPrivappPermissionsViolations;
198 
199     @GuardedBy("mLock")
200     private boolean mSystemReady;
201 
202     @GuardedBy("mLock")
203     private PermissionPolicyInternal mPermissionPolicyInternal;
204 
205     /**
206      * For each foreground/background permission the mapping:
207      * Background permission -> foreground permissions
208      */
209     @GuardedBy("mLock")
210     private ArrayMap<String, List<String>> mBackgroundPermissions;
211 
212     /**
213      * A permission backup might contain apps that are not installed. In this case we delay the
214      * restoration until the app is installed.
215      *
216      * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
217      * there is <u>no more</u> delayed backup left.
218      */
219     @GuardedBy("mLock")
220     private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
221 
222     /** Listeners for permission state (granting and flags) changes */
223     @GuardedBy("mLock")
224     final private ArrayList<OnRuntimePermissionStateChangedListener>
225             mRuntimePermissionStateChangedListeners = new ArrayList<>();
226 
PermissionManagerService(Context context, @NonNull Object externalLock)227     PermissionManagerService(Context context,
228             @NonNull Object externalLock) {
229         mContext = context;
230         mLock = externalLock;
231         mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
232         mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
233         mSettings = new PermissionSettings(mLock);
234 
235         mHandlerThread = new ServiceThread(TAG,
236                 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
237         mHandlerThread.start();
238         mHandler = new Handler(mHandlerThread.getLooper());
239         Watchdog.getInstance().addThread(mHandler);
240 
241         mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
242                 context, mHandlerThread.getLooper(), this);
243         SystemConfig systemConfig = SystemConfig.getInstance();
244         mSystemPermissions = systemConfig.getSystemPermissions();
245         mGlobalGids = systemConfig.getGlobalGids();
246 
247         // propagate permission configuration
248         final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
249                 SystemConfig.getInstance().getPermissions();
250         synchronized (mLock) {
251             for (int i=0; i<permConfig.size(); i++) {
252                 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
253                 BasePermission bp = mSettings.getPermissionLocked(perm.name);
254                 if (bp == null) {
255                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
256                     mSettings.putPermissionLocked(perm.name, bp);
257                 }
258                 if (perm.gids != null) {
259                     bp.setGids(perm.gids, perm.perUser);
260                 }
261             }
262         }
263 
264         PermissionManagerServiceInternalImpl localService =
265                 new PermissionManagerServiceInternalImpl();
266         LocalServices.addService(PermissionManagerServiceInternal.class, localService);
267         LocalServices.addService(PermissionManagerInternal.class, localService);
268     }
269 
270     /**
271      * Creates and returns an initialized, internal service for use by other components.
272      * <p>
273      * The object returned is identical to the one returned by the LocalServices class using:
274      * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
275      * <p>
276      * NOTE: The external lock is temporary and should be removed. This needs to be a
277      * lock created by the permission manager itself.
278      */
create(Context context, @NonNull Object externalLock)279     public static PermissionManagerServiceInternal create(Context context,
280             @NonNull Object externalLock) {
281         final PermissionManagerServiceInternal permMgrInt =
282                 LocalServices.getService(PermissionManagerServiceInternal.class);
283         if (permMgrInt != null) {
284             return permMgrInt;
285         }
286         new PermissionManagerService(context, externalLock);
287         return LocalServices.getService(PermissionManagerServiceInternal.class);
288     }
289 
getPermission(String permName)290     @Nullable BasePermission getPermission(String permName) {
291         synchronized (mLock) {
292             return mSettings.getPermissionLocked(permName);
293         }
294     }
295 
checkPermission(String permName, String pkgName, int callingUid, int userId)296     private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
297         if (!mUserManagerInt.exists(userId)) {
298             return PackageManager.PERMISSION_DENIED;
299         }
300 
301         final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
302         if (pkg != null && pkg.mExtras != null) {
303             if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
304                 return PackageManager.PERMISSION_DENIED;
305             }
306             final PackageSetting ps = (PackageSetting) pkg.mExtras;
307             final boolean instantApp = ps.getInstantApp(userId);
308             final PermissionsState permissionsState = ps.getPermissionsState();
309             if (permissionsState.hasPermission(permName, userId)) {
310                 if (instantApp) {
311                     synchronized (mLock) {
312                         BasePermission bp = mSettings.getPermissionLocked(permName);
313                         if (bp != null && bp.isInstant()) {
314                             return PackageManager.PERMISSION_GRANTED;
315                         }
316                     }
317                 } else {
318                     return PackageManager.PERMISSION_GRANTED;
319                 }
320             }
321             if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
322                 return PackageManager.PERMISSION_GRANTED;
323             }
324         }
325 
326         return PackageManager.PERMISSION_DENIED;
327     }
328 
checkUidPermission(String permName, PackageParser.Package pkg, int uid, int callingUid)329     private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
330             int callingUid) {
331         final int callingUserId = UserHandle.getUserId(callingUid);
332         final boolean isCallerInstantApp =
333                 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
334         final boolean isUidInstantApp =
335                 mPackageManagerInt.getInstantAppPackageName(uid) != null;
336         final int userId = UserHandle.getUserId(uid);
337         if (!mUserManagerInt.exists(userId)) {
338             return PackageManager.PERMISSION_DENIED;
339         }
340 
341         if (pkg != null) {
342             if (pkg.mSharedUserId != null) {
343                 if (isCallerInstantApp) {
344                     return PackageManager.PERMISSION_DENIED;
345                 }
346             } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
347                 return PackageManager.PERMISSION_DENIED;
348             }
349             final PermissionsState permissionsState =
350                     ((PackageSetting) pkg.mExtras).getPermissionsState();
351             if (permissionsState.hasPermission(permName, userId)) {
352                 if (isUidInstantApp) {
353                     if (mSettings.isPermissionInstant(permName)) {
354                         return PackageManager.PERMISSION_GRANTED;
355                     }
356                 } else {
357                     return PackageManager.PERMISSION_GRANTED;
358                 }
359             }
360             if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
361                 return PackageManager.PERMISSION_GRANTED;
362             }
363         } else {
364             ArraySet<String> perms = mSystemPermissions.get(uid);
365             if (perms != null) {
366                 if (perms.contains(permName)) {
367                     return PackageManager.PERMISSION_GRANTED;
368                 }
369                 if (FULLER_PERMISSION_MAP.containsKey(permName)
370                         && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
371                     return PackageManager.PERMISSION_GRANTED;
372                 }
373             }
374         }
375         return PackageManager.PERMISSION_DENIED;
376     }
377 
378     /**
379      * Get the state of the runtime permissions as xml file.
380      *
381      * <p>Can not be called on main thread.
382      *
383      * @param user The user the data should be extracted for
384      *
385      * @return The state as a xml file
386      */
backupRuntimePermissions(@onNull UserHandle user)387     private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
388         CompletableFuture<byte[]> backup = new CompletableFuture<>();
389         mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
390                 backup::complete);
391 
392         try {
393             return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
394         } catch (InterruptedException | ExecutionException  | TimeoutException e) {
395             Slog.e(TAG, "Cannot create permission backup for " + user, e);
396             return null;
397         }
398     }
399 
400     /**
401      * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
402      *
403      * <p>If not all state can be restored, the un-appliable state will be delayed and can be
404      * applied via {@link #restoreDelayedRuntimePermissions}.
405      *
406      * @param backup The state as an xml file
407      * @param user The user the data should be restored for
408      */
restoreRuntimePermissions(@onNull byte[] backup, @NonNull UserHandle user)409     private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
410         synchronized (mLock) {
411             mHasNoDelayedPermBackup.delete(user.getIdentifier());
412             mPermissionControllerManager.restoreRuntimePermissionBackup(backup, user);
413         }
414     }
415 
416     /**
417      * Try to apply permission backup that was previously not applied.
418      *
419      * <p>Can not be called on main thread.
420      *
421      * @param packageName The package that is newly installed
422      * @param user The user the package is installed for
423      *
424      * @see #restoreRuntimePermissions
425      */
restoreDelayedRuntimePermissions(@onNull String packageName, @NonNull UserHandle user)426     private void restoreDelayedRuntimePermissions(@NonNull String packageName,
427             @NonNull UserHandle user) {
428         synchronized (mLock) {
429             if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
430                 return;
431             }
432 
433             mPermissionControllerManager.restoreDelayedRuntimePermissionBackup(packageName, user,
434                     mContext.getMainExecutor(), (hasMoreBackup) -> {
435                         if (hasMoreBackup) {
436                             return;
437                         }
438 
439                         synchronized (mLock) {
440                             mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
441                         }
442                     });
443         }
444     }
445 
addOnRuntimePermissionStateChangedListener(@onNull OnRuntimePermissionStateChangedListener listener)446     private void addOnRuntimePermissionStateChangedListener(@NonNull
447             OnRuntimePermissionStateChangedListener listener) {
448         synchronized (mLock) {
449             mRuntimePermissionStateChangedListeners.add(listener);
450         }
451     }
452 
removeOnRuntimePermissionStateChangedListener(@onNull OnRuntimePermissionStateChangedListener listener)453     private void removeOnRuntimePermissionStateChangedListener(@NonNull
454             OnRuntimePermissionStateChangedListener listener) {
455         synchronized (mLock) {
456             mRuntimePermissionStateChangedListeners.remove(listener);
457         }
458     }
459 
notifyRuntimePermissionStateChanged(@onNull String packageName, @UserIdInt int userId)460     private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
461             @UserIdInt int userId) {
462         FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
463                 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
464                         PermissionManagerService.this, packageName, userId));
465     }
466 
doNotifyRuntimePermissionStateChanged(@onNull String packageName, @UserIdInt int userId)467     private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
468             @UserIdInt int userId) {
469         final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
470         synchronized (mLock) {
471             if (mRuntimePermissionStateChangedListeners.isEmpty()) {
472                 return;
473             }
474             listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
475         }
476         final int listenerCount = listeners.size();
477         for (int i = 0; i < listenerCount; i++) {
478             listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
479         }
480     }
481 
482     /**
483      * Returns {@code true} if the permission can be implied from another granted permission.
484      * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
485      * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
486      * it access to any implied permissions.
487      */
isImpliedPermissionGranted(PermissionsState permissionsState, String permName, int userId)488     private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
489             String permName, int userId) {
490         return FULLER_PERMISSION_MAP.containsKey(permName)
491                 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
492     }
493 
getPermissionGroupInfo(String groupName, int flags, int callingUid)494     private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
495             int callingUid) {
496         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
497             return null;
498         }
499         synchronized (mLock) {
500             return PackageParser.generatePermissionGroupInfo(
501                     mSettings.mPermissionGroups.get(groupName), flags);
502         }
503     }
504 
getAllPermissionGroups(int flags, int callingUid)505     private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
506         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
507             return null;
508         }
509         synchronized (mLock) {
510             final int N = mSettings.mPermissionGroups.size();
511             final ArrayList<PermissionGroupInfo> out
512                     = new ArrayList<PermissionGroupInfo>(N);
513             for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
514                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
515             }
516             return out;
517         }
518     }
519 
getPermissionInfo(String permName, String packageName, int flags, int callingUid)520     private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
521             int callingUid) {
522         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
523             return null;
524         }
525         // reader
526         synchronized (mLock) {
527             final BasePermission bp = mSettings.getPermissionLocked(permName);
528             if (bp == null) {
529                 return null;
530             }
531             final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
532                     bp.getProtectionLevel(), packageName, callingUid);
533             return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
534         }
535     }
536 
getPermissionInfoByGroup( String groupName, int flags, int callingUid)537     private List<PermissionInfo> getPermissionInfoByGroup(
538             String groupName, int flags, int callingUid) {
539         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
540             return null;
541         }
542         synchronized (mLock) {
543             if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
544                 return null;
545             }
546             final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
547             for (BasePermission bp : mSettings.mPermissions.values()) {
548                 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
549                 if (pi != null) {
550                     out.add(pi);
551                 }
552             }
553             return out;
554         }
555     }
556 
adjustPermissionProtectionFlagsLocked( int protectionLevel, String packageName, int uid)557     private int adjustPermissionProtectionFlagsLocked(
558             int protectionLevel, String packageName, int uid) {
559         // Signature permission flags area always reported
560         final int protectionLevelMasked = protectionLevel
561                 & (PermissionInfo.PROTECTION_NORMAL
562                 | PermissionInfo.PROTECTION_DANGEROUS
563                 | PermissionInfo.PROTECTION_SIGNATURE);
564         if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
565             return protectionLevel;
566         }
567         // System sees all flags.
568         final int appId = UserHandle.getAppId(uid);
569         if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
570                 || appId == Process.SHELL_UID) {
571             return protectionLevel;
572         }
573         // Normalize package name to handle renamed packages and static libs
574         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
575         if (pkg == null) {
576             return protectionLevel;
577         }
578         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
579             return protectionLevelMasked;
580         }
581         // Apps that target O see flags for all protection levels.
582         final PackageSetting ps = (PackageSetting) pkg.mExtras;
583         if (ps == null) {
584             return protectionLevel;
585         }
586         if (ps.getAppId() != appId) {
587             return protectionLevel;
588         }
589         return protectionLevel;
590     }
591 
592     /**
593      * We might auto-grant permissions if any permission of the group is already granted. Hence if
594      * the group of a granted permission changes we need to revoke it to avoid having permissions of
595      * the new group auto-granted.
596      *
597      * @param newPackage The new package that was installed
598      * @param oldPackage The old package that was updated
599      * @param allPackageNames All package names
600      * @param permissionCallback Callback for permission changed
601      */
revokeRuntimePermissionsIfGroupChanged( @onNull PackageParser.Package newPackage, @NonNull PackageParser.Package oldPackage, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback)602     private void revokeRuntimePermissionsIfGroupChanged(
603             @NonNull PackageParser.Package newPackage,
604             @NonNull PackageParser.Package oldPackage,
605             @NonNull ArrayList<String> allPackageNames,
606             @NonNull PermissionCallback permissionCallback) {
607         final int numOldPackagePermissions = oldPackage.permissions.size();
608         final ArrayMap<String, String> oldPermissionNameToGroupName
609                 = new ArrayMap<>(numOldPackagePermissions);
610 
611         for (int i = 0; i < numOldPackagePermissions; i++) {
612             final PackageParser.Permission permission = oldPackage.permissions.get(i);
613 
614             if (permission.group != null) {
615                 oldPermissionNameToGroupName.put(permission.info.name,
616                         permission.group.info.name);
617             }
618         }
619 
620         final int numNewPackagePermissions = newPackage.permissions.size();
621         for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
622                 newPermissionNum++) {
623             final PackageParser.Permission newPermission =
624                     newPackage.permissions.get(newPermissionNum);
625             final int newProtection = newPermission.info.getProtection();
626 
627             if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
628                 final String permissionName = newPermission.info.name;
629                 final String newPermissionGroupName =
630                         newPermission.group == null ? null : newPermission.group.info.name;
631                 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
632                         permissionName);
633 
634                 if (newPermissionGroupName != null
635                         && !newPermissionGroupName.equals(oldPermissionGroupName)) {
636                     final int[] userIds = mUserManagerInt.getUserIds();
637                     final int numUserIds = userIds.length;
638                     for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
639                         final int userId = userIds[userIdNum];
640 
641                         final int numPackages = allPackageNames.size();
642                         for (int packageNum = 0; packageNum < numPackages; packageNum++) {
643                             final String packageName = allPackageNames.get(packageNum);
644 
645                             if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
646                                     userId) == PackageManager.PERMISSION_GRANTED) {
647                                 EventLog.writeEvent(0x534e4554, "72710897",
648                                         newPackage.applicationInfo.uid,
649                                         "Revoking permission " + permissionName +
650                                         " from package " + packageName +
651                                         " as the group changed from " + oldPermissionGroupName +
652                                         " to " + newPermissionGroupName);
653 
654                                 try {
655                                     revokeRuntimePermission(permissionName, packageName, false,
656                                             userId, permissionCallback);
657                                 } catch (IllegalArgumentException e) {
658                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
659                                             + packageName, e);
660                                 }
661                             }
662                         }
663                     }
664                 }
665             }
666         }
667     }
668 
addAllPermissions(PackageParser.Package pkg, boolean chatty)669     private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
670         final int N = pkg.permissions.size();
671         for (int i=0; i<N; i++) {
672             PackageParser.Permission p = pkg.permissions.get(i);
673 
674             // Assume by default that we did not install this permission into the system.
675             p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
676 
677             synchronized (PermissionManagerService.this.mLock) {
678                 // Now that permission groups have a special meaning, we ignore permission
679                 // groups for legacy apps to prevent unexpected behavior. In particular,
680                 // permissions for one app being granted to someone just because they happen
681                 // to be in a group defined by another app (before this had no implications).
682                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
683                     p.group = mSettings.mPermissionGroups.get(p.info.group);
684                     // Warn for a permission in an unknown group.
685                     if (DEBUG_PERMISSIONS
686                             && p.info.group != null && p.group == null) {
687                         Slog.i(TAG, "Permission " + p.info.name + " from package "
688                                 + p.info.packageName + " in an unknown group " + p.info.group);
689                     }
690                 }
691 
692                 if (p.tree) {
693                     final BasePermission bp = BasePermission.createOrUpdate(
694                             mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
695                             mSettings.getAllPermissionTreesLocked(), chatty);
696                     mSettings.putPermissionTreeLocked(p.info.name, bp);
697                 } else {
698                     final BasePermission bp = BasePermission.createOrUpdate(
699                             mSettings.getPermissionLocked(p.info.name),
700                             p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
701                     mSettings.putPermissionLocked(p.info.name, bp);
702                 }
703             }
704         }
705     }
706 
addAllPermissionGroups(PackageParser.Package pkg, boolean chatty)707     private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
708         final int N = pkg.permissionGroups.size();
709         StringBuilder r = null;
710         for (int i=0; i<N; i++) {
711             final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
712             final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
713             final String curPackageName = (cur == null) ? null : cur.info.packageName;
714             final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
715             if (cur == null || isPackageUpdate) {
716                 mSettings.mPermissionGroups.put(pg.info.name, pg);
717                 if (chatty && DEBUG_PACKAGE_SCANNING) {
718                     if (r == null) {
719                         r = new StringBuilder(256);
720                     } else {
721                         r.append(' ');
722                     }
723                     if (isPackageUpdate) {
724                         r.append("UPD:");
725                     }
726                     r.append(pg.info.name);
727                 }
728             } else {
729                 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
730                         + pg.info.packageName + " ignored: original from "
731                         + cur.info.packageName);
732                 if (chatty && DEBUG_PACKAGE_SCANNING) {
733                     if (r == null) {
734                         r = new StringBuilder(256);
735                     } else {
736                         r.append(' ');
737                     }
738                     r.append("DUP:");
739                     r.append(pg.info.name);
740                 }
741             }
742         }
743         if (r != null && DEBUG_PACKAGE_SCANNING) {
744             Log.d(TAG, "  Permission Groups: " + r);
745         }
746 
747     }
748 
removeAllPermissions(PackageParser.Package pkg, boolean chatty)749     private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
750         synchronized (mLock) {
751             int N = pkg.permissions.size();
752             StringBuilder r = null;
753             for (int i=0; i<N; i++) {
754                 PackageParser.Permission p = pkg.permissions.get(i);
755                 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
756                 if (bp == null) {
757                     bp = mSettings.mPermissionTrees.get(p.info.name);
758                 }
759                 if (bp != null && bp.isPermission(p)) {
760                     bp.setPermission(null);
761                     if (DEBUG_REMOVE && chatty) {
762                         if (r == null) {
763                             r = new StringBuilder(256);
764                         } else {
765                             r.append(' ');
766                         }
767                         r.append(p.info.name);
768                     }
769                 }
770                 if (p.isAppOp()) {
771                     ArraySet<String> appOpPkgs =
772                             mSettings.mAppOpPermissionPackages.get(p.info.name);
773                     if (appOpPkgs != null) {
774                         appOpPkgs.remove(pkg.packageName);
775                     }
776                 }
777             }
778             if (r != null) {
779                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
780             }
781 
782             N = pkg.requestedPermissions.size();
783             r = null;
784             for (int i=0; i<N; i++) {
785                 String perm = pkg.requestedPermissions.get(i);
786                 if (mSettings.isPermissionAppOp(perm)) {
787                     ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
788                     if (appOpPkgs != null) {
789                         appOpPkgs.remove(pkg.packageName);
790                         if (appOpPkgs.isEmpty()) {
791                             mSettings.mAppOpPermissionPackages.remove(perm);
792                         }
793                     }
794                 }
795             }
796             if (r != null) {
797                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
798             }
799         }
800     }
801 
addDynamicPermission( PermissionInfo info, int callingUid, PermissionCallback callback)802     private boolean addDynamicPermission(
803             PermissionInfo info, int callingUid, PermissionCallback callback) {
804         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
805             throw new SecurityException("Instant apps can't add permissions");
806         }
807         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
808             throw new SecurityException("Label must be specified in permission");
809         }
810         final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
811         final boolean added;
812         final boolean changed;
813         synchronized (mLock) {
814             BasePermission bp = mSettings.getPermissionLocked(info.name);
815             added = bp == null;
816             int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
817             if (added) {
818                 enforcePermissionCapLocked(info, tree);
819                 bp = new BasePermission(info.name, tree.getSourcePackageName(),
820                         BasePermission.TYPE_DYNAMIC);
821             } else if (!bp.isDynamic()) {
822                 throw new SecurityException("Not allowed to modify non-dynamic permission "
823                         + info.name);
824             }
825             changed = bp.addToTree(fixedLevel, info, tree);
826             if (added) {
827                 mSettings.putPermissionLocked(info.name, bp);
828             }
829         }
830         if (changed && callback != null) {
831             callback.onPermissionChanged();
832         }
833         return added;
834     }
835 
removeDynamicPermission( String permName, int callingUid, PermissionCallback callback)836     private void removeDynamicPermission(
837             String permName, int callingUid, PermissionCallback callback) {
838         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
839             throw new SecurityException("Instant applications don't have access to this method");
840         }
841         final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
842         synchronized (mLock) {
843             final BasePermission bp = mSettings.getPermissionLocked(permName);
844             if (bp == null) {
845                 return;
846             }
847             if (bp.isDynamic()) {
848                 // TODO: switch this back to SecurityException
849                 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
850                         + permName);
851             }
852             mSettings.removePermissionLocked(permName);
853             if (callback != null) {
854                 callback.onPermissionRemoved();
855             }
856         }
857     }
858 
859     /**
860      * Restore the permission state for a package.
861      *
862      * <ul>
863      *     <li>During boot the state gets restored from the disk</li>
864      *     <li>During app update the state gets restored from the last version of the app</li>
865      * </ul>
866      *
867      * <p>This restores the permission state for all users.
868      *
869      * @param pkg the package the permissions belong to
870      * @param replace if the package is getting replaced (this might change the requested
871      *                permissions of this package)
872      * @param packageOfInterest If this is the name of {@code pkg} add extra logging
873      * @param callback Result call back
874      */
restorePermissionState(@onNull PackageParser.Package pkg, boolean replace, @Nullable String packageOfInterest, @Nullable PermissionCallback callback)875     private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
876             @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
877         // IMPORTANT: There are two types of permissions: install and runtime.
878         // Install time permissions are granted when the app is installed to
879         // all device users and users added in the future. Runtime permissions
880         // are granted at runtime explicitly to specific users. Normal and signature
881         // protected permissions are install time permissions. Dangerous permissions
882         // are install permissions if the app's target SDK is Lollipop MR1 or older,
883         // otherwise they are runtime permissions. This function does not manage
884         // runtime permissions except for the case an app targeting Lollipop MR1
885         // being upgraded to target a newer SDK, in which case dangerous permissions
886         // are transformed from install time to runtime ones.
887 
888         final PackageSetting ps = (PackageSetting) pkg.mExtras;
889         if (ps == null) {
890             return;
891         }
892 
893         final PermissionsState permissionsState = ps.getPermissionsState();
894         PermissionsState origPermissions = permissionsState;
895 
896         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
897 
898         boolean runtimePermissionsRevoked = false;
899         int[] updatedUserIds = EMPTY_INT_ARRAY;
900 
901         boolean changedInstallPermission = false;
902 
903         if (replace) {
904             ps.setInstallPermissionsFixed(false);
905             if (!ps.isSharedUser()) {
906                 origPermissions = new PermissionsState(permissionsState);
907                 permissionsState.reset();
908             } else {
909                 // We need to know only about runtime permission changes since the
910                 // calling code always writes the install permissions state but
911                 // the runtime ones are written only if changed. The only cases of
912                 // changed runtime permissions here are promotion of an install to
913                 // runtime and revocation of a runtime from a shared user.
914                 synchronized (mLock) {
915                     updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
916                             ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
917                     if (!ArrayUtils.isEmpty(updatedUserIds)) {
918                         runtimePermissionsRevoked = true;
919                     }
920                 }
921             }
922         }
923 
924         permissionsState.setGlobalGids(mGlobalGids);
925 
926         synchronized (mLock) {
927             ArraySet<String> newImplicitPermissions = new ArraySet<>();
928 
929             final int N = pkg.requestedPermissions.size();
930             for (int i = 0; i < N; i++) {
931                 final String permName = pkg.requestedPermissions.get(i);
932                 final BasePermission bp = mSettings.getPermissionLocked(permName);
933                 final boolean appSupportsRuntimePermissions =
934                         pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
935                 String upgradedActivityRecognitionPermission = null;
936 
937                 if (DEBUG_INSTALL) {
938                     Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
939                 }
940 
941                 if (bp == null || bp.getSourcePackageSetting() == null) {
942                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
943                         if (DEBUG_PERMISSIONS) {
944                             Slog.i(TAG, "Unknown permission " + permName
945                                     + " in package " + pkg.packageName);
946                         }
947                     }
948                     continue;
949                 }
950 
951                 // Cache newImplicitPermissions before modifing permissionsState as for the shared
952                 // uids the original and new state are the same object
953                 if (!origPermissions.hasRequestedPermission(permName)
954                         && (pkg.implicitPermissions.contains(permName)
955                                 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
956                     if (pkg.implicitPermissions.contains(permName)) {
957                         // If permName is an implicit permission, try to auto-grant
958                         newImplicitPermissions.add(permName);
959 
960                         if (DEBUG_PERMISSIONS) {
961                             Slog.i(TAG, permName + " is newly added for " + pkg.packageName);
962                         }
963                     } else {
964                         // Special case for Activity Recognition permission. Even if AR permission
965                         // is not an implicit permission we want to add it to the list (try to
966                         // auto-grant it) if the app was installed on a device before AR permission
967                         // was split, regardless of if the app now requests the new AR permission
968                         // or has updated its target SDK and AR is no longer implicit to it.
969                         // This is a compatibility workaround for apps when AR permission was
970                         // split in Q.
971                         final List<PermissionManager.SplitPermissionInfo> permissionList =
972                                 getSplitPermissions();
973                         int numSplitPerms = permissionList.size();
974                         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
975                             PermissionManager.SplitPermissionInfo sp =
976                                     permissionList.get(splitPermNum);
977                             String splitPermName = sp.getSplitPermission();
978                             if (sp.getNewPermissions().contains(permName)
979                                     && origPermissions.hasInstallPermission(splitPermName)) {
980                                 upgradedActivityRecognitionPermission = splitPermName;
981                                 newImplicitPermissions.add(permName);
982 
983                                 if (DEBUG_PERMISSIONS) {
984                                     Slog.i(TAG, permName + " is newly added for "
985                                             + pkg.packageName);
986                                 }
987                                 break;
988                             }
989                         }
990                     }
991                 }
992 
993                 // Limit ephemeral apps to ephemeral allowed permissions.
994                 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
995                     if (DEBUG_PERMISSIONS) {
996                         Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
997                                 + " for package " + pkg.packageName);
998                     }
999                     continue;
1000                 }
1001 
1002                 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
1003                     if (DEBUG_PERMISSIONS) {
1004                         Log.i(TAG, "Denying runtime-only permission " + bp.getName()
1005                                 + " for package " + pkg.packageName);
1006                     }
1007                     continue;
1008                 }
1009 
1010                 final String perm = bp.getName();
1011                 boolean allowedSig = false;
1012                 int grant = GRANT_DENIED;
1013 
1014                 // Keep track of app op permissions.
1015                 if (bp.isAppOp()) {
1016                     mSettings.addAppOpPackage(perm, pkg.packageName);
1017                 }
1018 
1019                 if (bp.isNormal()) {
1020                     // For all apps normal permissions are install time ones.
1021                     grant = GRANT_INSTALL;
1022                 } else if (bp.isRuntime()) {
1023                     if (origPermissions.hasInstallPermission(bp.getName())
1024                             || upgradedActivityRecognitionPermission != null) {
1025                         // Before Q we represented some runtime permissions as install permissions,
1026                         // in Q we cannot do this anymore. Hence upgrade them all.
1027                         grant = GRANT_UPGRADE;
1028                     } else {
1029                         // For modern apps keep runtime permissions unchanged.
1030                         grant = GRANT_RUNTIME;
1031                     }
1032                 } else if (bp.isSignature()) {
1033                     // For all apps signature permissions are install time ones.
1034                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
1035                     if (allowedSig) {
1036                         grant = GRANT_INSTALL;
1037                     }
1038                 }
1039 
1040                 if (DEBUG_PERMISSIONS) {
1041                     Slog.i(TAG, "Considering granting permission " + perm + " to package "
1042                             + pkg.packageName);
1043                 }
1044 
1045                 if (grant != GRANT_DENIED) {
1046                     if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
1047                         // If this is an existing, non-system package, then
1048                         // we can't add any new permissions to it. Runtime
1049                         // permissions can be added any time - they ad dynamic.
1050                         if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
1051                             // Except...  if this is a permission that was added
1052                             // to the platform (note: need to only do this when
1053                             // updating the platform).
1054                             if (!isNewPlatformPermissionForPackage(perm, pkg)) {
1055                                 grant = GRANT_DENIED;
1056                             }
1057                         }
1058                     }
1059 
1060                     switch (grant) {
1061                         case GRANT_INSTALL: {
1062                             // Revoke this as runtime permission to handle the case of
1063                             // a runtime permission being downgraded to an install one.
1064                             // Also in permission review mode we keep dangerous permissions
1065                             // for legacy apps
1066                             for (int userId : UserManagerService.getInstance().getUserIds()) {
1067                                 if (origPermissions.getRuntimePermissionState(
1068                                         perm, userId) != null) {
1069                                     // Revoke the runtime permission and clear the flags.
1070                                     origPermissions.revokeRuntimePermission(bp, userId);
1071                                     origPermissions.updatePermissionFlags(bp, userId,
1072                                             PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
1073                                     // If we revoked a permission permission, we have to write.
1074                                     updatedUserIds = ArrayUtils.appendInt(
1075                                             updatedUserIds, userId);
1076                                 }
1077                             }
1078                             // Grant an install permission.
1079                             if (permissionsState.grantInstallPermission(bp) !=
1080                                     PERMISSION_OPERATION_FAILURE) {
1081                                 changedInstallPermission = true;
1082                             }
1083                         } break;
1084 
1085                         case GRANT_RUNTIME: {
1086                             boolean hardRestricted = bp.isHardRestricted();
1087                             boolean softRestricted = bp.isSoftRestricted();
1088 
1089                             for (int userId : currentUserIds) {
1090                                 // If permission policy is not ready we don't deal with restricted
1091                                 // permissions as the policy may whitelist some permissions. Once
1092                                 // the policy is initialized we would re-evaluate permissions.
1093                                 final boolean permissionPolicyInitialized =
1094                                         mPermissionPolicyInternal != null
1095                                                 && mPermissionPolicyInternal.isInitialized(userId);
1096 
1097                                 PermissionState permState = origPermissions
1098                                         .getRuntimePermissionState(perm, userId);
1099                                 int flags = permState != null ? permState.getFlags() : 0;
1100 
1101                                 boolean wasChanged = false;
1102 
1103                                 boolean restrictionExempt =
1104                                         (origPermissions.getPermissionFlags(bp.name, userId)
1105                                                 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1106                                 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1107                                         bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1108 
1109                                 if (appSupportsRuntimePermissions) {
1110                                     // If hard restricted we don't allow holding it
1111                                     if (permissionPolicyInitialized && hardRestricted) {
1112                                         if (!restrictionExempt) {
1113                                             if (permState != null && permState.isGranted()
1114                                                     && permissionsState.revokeRuntimePermission(
1115                                                     bp, userId) != PERMISSION_OPERATION_FAILURE) {
1116                                                 wasChanged = true;
1117                                             }
1118                                             if (!restrictionApplied) {
1119                                                 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1120                                                 wasChanged = true;
1121                                             }
1122                                         }
1123                                     // If soft restricted we allow holding in a restricted form
1124                                     } else if (permissionPolicyInitialized && softRestricted) {
1125                                         // Regardless if granted set the restriction flag as it
1126                                         // may affect app treatment based on this permission.
1127                                         if (!restrictionExempt && !restrictionApplied) {
1128                                             flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1129                                             wasChanged = true;
1130                                         }
1131                                     }
1132 
1133                                     // Remove review flag as it is not necessary anymore
1134                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1135                                         flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1136                                         wasChanged = true;
1137                                     }
1138 
1139                                     if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1140                                         flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1141                                         wasChanged = true;
1142                                     // Hard restricted permissions cannot be held.
1143                                     } else if (!permissionPolicyInitialized
1144                                             || (!hardRestricted || restrictionExempt)) {
1145                                         if (permState != null && permState.isGranted()) {
1146                                             if (permissionsState.grantRuntimePermission(bp, userId)
1147                                                     == PERMISSION_OPERATION_FAILURE) {
1148                                                 wasChanged = true;
1149                                             }
1150                                         }
1151                                     }
1152                                 } else {
1153                                     if (permState == null) {
1154                                         // New permission
1155                                         if (PLATFORM_PACKAGE_NAME.equals(
1156                                                 bp.getSourcePackageName())) {
1157                                             if (!bp.isRemoved()) {
1158                                                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
1159                                                         | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1160                                                 wasChanged = true;
1161                                             }
1162                                         }
1163                                     }
1164 
1165                                     if (!permissionsState.hasRuntimePermission(bp.name, userId)
1166                                             && permissionsState.grantRuntimePermission(bp, userId)
1167                                                     != PERMISSION_OPERATION_FAILURE) {
1168                                         wasChanged = true;
1169                                     }
1170 
1171                                     // If legacy app always grant the permission but if restricted
1172                                     // and not exempt take a note a restriction should be applied.
1173                                     if (permissionPolicyInitialized
1174                                             && (hardRestricted || softRestricted)
1175                                                     && !restrictionExempt && !restrictionApplied) {
1176                                         flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1177                                         wasChanged = true;
1178                                     }
1179                                 }
1180 
1181                                 // If unrestricted or restriction exempt, don't apply restriction.
1182                                 if (permissionPolicyInitialized) {
1183                                     if (!(hardRestricted || softRestricted) || restrictionExempt) {
1184                                         if (restrictionApplied) {
1185                                             flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1186                                             // Dropping restriction on a legacy app implies a review
1187                                             if (!appSupportsRuntimePermissions) {
1188                                                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1189                                             }
1190                                             wasChanged = true;
1191                                         }
1192                                     }
1193                                 }
1194 
1195                                 if (wasChanged) {
1196                                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1197                                 }
1198 
1199                                 permissionsState.updatePermissionFlags(bp, userId,
1200                                         MASK_PERMISSION_FLAGS_ALL, flags);
1201                             }
1202                         } break;
1203 
1204                         case GRANT_UPGRADE: {
1205                             // Upgrade from Pre-Q to Q permission model. Make all permissions
1206                             // runtime
1207                             PermissionState permState = origPermissions
1208                                     .getInstallPermissionState(perm);
1209                             int flags = (permState != null) ? permState.getFlags() : 0;
1210 
1211                             BasePermission bpToRevoke =
1212                                     upgradedActivityRecognitionPermission == null
1213                                     ? bp : mSettings.getPermissionLocked(
1214                                             upgradedActivityRecognitionPermission);
1215                             // Remove install permission
1216                             if (origPermissions.revokeInstallPermission(bpToRevoke)
1217                                     != PERMISSION_OPERATION_FAILURE) {
1218                                 origPermissions.updatePermissionFlags(bpToRevoke,
1219                                         UserHandle.USER_ALL,
1220                                         (MASK_PERMISSION_FLAGS_ALL
1221                                                 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
1222                                 changedInstallPermission = true;
1223                             }
1224 
1225                             boolean hardRestricted = bp.isHardRestricted();
1226                             boolean softRestricted = bp.isSoftRestricted();
1227 
1228                             for (int userId : currentUserIds) {
1229                                 // If permission policy is not ready we don't deal with restricted
1230                                 // permissions as the policy may whitelist some permissions. Once
1231                                 // the policy is initialized we would re-evaluate permissions.
1232                                 final boolean permissionPolicyInitialized =
1233                                         mPermissionPolicyInternal != null
1234                                                 && mPermissionPolicyInternal.isInitialized(userId);
1235 
1236                                 boolean wasChanged = false;
1237 
1238                                 boolean restrictionExempt =
1239                                         (origPermissions.getPermissionFlags(bp.name, userId)
1240                                                 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1241                                 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1242                                         bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1243 
1244                                 if (appSupportsRuntimePermissions) {
1245                                     // If hard restricted we don't allow holding it
1246                                     if (permissionPolicyInitialized && hardRestricted) {
1247                                         if (!restrictionExempt) {
1248                                             if (permState != null && permState.isGranted()
1249                                                     && permissionsState.revokeRuntimePermission(
1250                                                     bp, userId) != PERMISSION_OPERATION_FAILURE) {
1251                                                 wasChanged = true;
1252                                             }
1253                                             if (!restrictionApplied) {
1254                                                 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1255                                                 wasChanged = true;
1256                                             }
1257                                         }
1258                                     // If soft restricted we allow holding in a restricted form
1259                                     } else if (permissionPolicyInitialized && softRestricted) {
1260                                         // Regardless if granted set the  restriction flag as it
1261                                         // may affect app treatment based on this permission.
1262                                         if (!restrictionExempt && !restrictionApplied) {
1263                                             flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1264                                             wasChanged = true;
1265                                         }
1266                                     }
1267 
1268                                     // Remove review flag as it is not necessary anymore
1269                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1270                                         flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1271                                         wasChanged = true;
1272                                     }
1273 
1274                                     if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1275                                         flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1276                                         wasChanged = true;
1277                                     // Hard restricted permissions cannot be held.
1278                                     } else if (!permissionPolicyInitialized ||
1279                                             (!hardRestricted || restrictionExempt)) {
1280                                         if (permissionsState.grantRuntimePermission(bp, userId) !=
1281                                                 PERMISSION_OPERATION_FAILURE) {
1282                                              wasChanged = true;
1283                                         }
1284                                     }
1285                                 } else {
1286                                     if (!permissionsState.hasRuntimePermission(bp.name, userId)
1287                                             && permissionsState.grantRuntimePermission(bp,
1288                                                     userId) != PERMISSION_OPERATION_FAILURE) {
1289                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1290                                         wasChanged = true;
1291                                     }
1292 
1293                                     // If legacy app always grant the permission but if restricted
1294                                     // and not exempt take a note a restriction should be applied.
1295                                     if (permissionPolicyInitialized
1296                                             && (hardRestricted || softRestricted)
1297                                                     && !restrictionExempt && !restrictionApplied) {
1298                                         flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1299                                         wasChanged = true;
1300                                     }
1301                                 }
1302 
1303                                 // If unrestricted or restriction exempt, don't apply restriction.
1304                                 if (permissionPolicyInitialized) {
1305                                     if (!(hardRestricted || softRestricted) || restrictionExempt) {
1306                                         if (restrictionApplied) {
1307                                             flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1308                                             // Dropping restriction on a legacy app implies a review
1309                                             if (!appSupportsRuntimePermissions) {
1310                                                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1311                                             }
1312                                             wasChanged = true;
1313                                         }
1314                                     }
1315                                 }
1316 
1317                                 if (wasChanged) {
1318                                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1319                                 }
1320 
1321                                 permissionsState.updatePermissionFlags(bp, userId,
1322                                         MASK_PERMISSION_FLAGS_ALL, flags);
1323                             }
1324                         } break;
1325 
1326                         default: {
1327                             if (packageOfInterest == null
1328                                     || packageOfInterest.equals(pkg.packageName)) {
1329                                 if (DEBUG_PERMISSIONS) {
1330                                     Slog.i(TAG, "Not granting permission " + perm
1331                                             + " to package " + pkg.packageName
1332                                             + " because it was previously installed without");
1333                                 }
1334                             }
1335                         } break;
1336                     }
1337                 } else {
1338                     if (permissionsState.revokeInstallPermission(bp) !=
1339                             PERMISSION_OPERATION_FAILURE) {
1340                         // Also drop the permission flags.
1341                         permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1342                                 MASK_PERMISSION_FLAGS_ALL, 0);
1343                         changedInstallPermission = true;
1344                         Slog.i(TAG, "Un-granting permission " + perm
1345                                 + " from package " + pkg.packageName
1346                                 + " (protectionLevel=" + bp.getProtectionLevel()
1347                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1348                                 + ")");
1349                     } else if (bp.isAppOp()) {
1350                         // Don't print warning for app op permissions, since it is fine for them
1351                         // not to be granted, there is a UI for the user to decide.
1352                         if (DEBUG_PERMISSIONS
1353                                 && (packageOfInterest == null
1354                                         || packageOfInterest.equals(pkg.packageName))) {
1355                             Slog.i(TAG, "Not granting permission " + perm
1356                                     + " to package " + pkg.packageName
1357                                     + " (protectionLevel=" + bp.getProtectionLevel()
1358                                     + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1359                                     + ")");
1360                         }
1361                     }
1362                 }
1363             }
1364 
1365             if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1366                     !ps.isSystem() || ps.isUpdatedSystem()) {
1367                 // This is the first that we have heard about this package, so the
1368                 // permissions we have now selected are fixed until explicitly
1369                 // changed.
1370                 ps.setInstallPermissionsFixed(true);
1371             }
1372 
1373             updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1374                     updatedUserIds);
1375             updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
1376                     permissionsState, pkg, newImplicitPermissions, updatedUserIds);
1377             updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
1378         }
1379 
1380         // Persist the runtime permissions state for users with changes. If permissions
1381         // were revoked because no app in the shared user declares them we have to
1382         // write synchronously to avoid losing runtime permissions state.
1383         if (callback != null) {
1384             callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1385         }
1386 
1387         for (int userId : updatedUserIds) {
1388             notifyRuntimePermissionStateChanged(pkg.packageName, userId);
1389         }
1390     }
1391 
1392     /**
1393      * Revoke permissions that are not implicit anymore and that have
1394      * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1395      *
1396      * @param ps The state of the permissions of the package
1397      * @param pkg The package that is currently looked at
1398      * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1399      *                       for a user is changed.
1400      *
1401      * @return The updated value of the {@code updatedUserIds} parameter
1402      */
revokePermissionsNoLongerImplicitLocked( @onNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull int[] updatedUserIds)1403     private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1404             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1405             @NonNull int[] updatedUserIds) {
1406         String pkgName = pkg.packageName;
1407         boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1408                 >= Build.VERSION_CODES.M;
1409 
1410         int[] users = UserManagerService.getInstance().getUserIds();
1411         int numUsers = users.length;
1412         for (int i = 0; i < numUsers; i++) {
1413             int userId = users[i];
1414 
1415             for (String permission : ps.getPermissions(userId)) {
1416                 if (!pkg.implicitPermissions.contains(permission)) {
1417                     if (!ps.hasInstallPermission(permission)) {
1418                         int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1419 
1420                         if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1421                             BasePermission bp = mSettings.getPermissionLocked(permission);
1422 
1423                             int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
1424 
1425                             if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
1426                                     && supportsRuntimePermissions) {
1427                                 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1428                                 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
1429                                     if (DEBUG_PERMISSIONS) {
1430                                         Slog.i(TAG, "Revoking runtime permission "
1431                                                 + permission + " for " + pkgName
1432                                                 + " as it is now requested");
1433                                     }
1434                                 }
1435 
1436                                 flagsToRemove |= USER_PERMISSION_FLAGS;
1437                             }
1438 
1439                             ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
1440                             updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1441                         }
1442                     }
1443                 }
1444             }
1445         }
1446 
1447         return updatedUserIds;
1448     }
1449 
1450     /**
1451      * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1452      *
1453      * <p>A single new permission can be split off from several source permissions. In this case
1454      * the most leniant state is inherited.
1455      *
1456      * <p>Warning: This does not handle foreground / background permissions
1457      *
1458      * @param sourcePerms The permissions to inherit from
1459      * @param newPerm The permission to inherit to
1460      * @param ps The permission state of the package
1461      * @param pkg The package requesting the permissions
1462      * @param userId The user the permission belongs to
1463      */
inheritPermissionStateToNewImplicitPermissionLocked( @onNull ArraySet<String> sourcePerms, @NonNull String newPerm, @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @UserIdInt int userId)1464     private void inheritPermissionStateToNewImplicitPermissionLocked(
1465             @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1466             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1467             @UserIdInt int userId) {
1468         String pkgName = pkg.packageName;
1469         boolean isGranted = false;
1470         int flags = 0;
1471 
1472         int numSourcePerm = sourcePerms.size();
1473         for (int i = 0; i < numSourcePerm; i++) {
1474             String sourcePerm = sourcePerms.valueAt(i);
1475             if ((ps.hasRuntimePermission(sourcePerm, userId))
1476                     || ps.hasInstallPermission(sourcePerm)) {
1477                 if (!isGranted) {
1478                     flags = 0;
1479                 }
1480 
1481                 isGranted = true;
1482                 flags |= ps.getPermissionFlags(sourcePerm, userId);
1483             } else {
1484                 if (!isGranted) {
1485                     flags |= ps.getPermissionFlags(sourcePerm, userId);
1486                 }
1487             }
1488         }
1489 
1490         if (isGranted) {
1491             if (DEBUG_PERMISSIONS) {
1492                 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1493                         + " for " + pkgName);
1494             }
1495 
1496             ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1497         }
1498 
1499         // Add permission flags
1500         ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
1501     }
1502 
1503     /**
1504      * When the app has requested legacy storage we might need to update
1505      * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
1506      * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
1507      *
1508      * @param pkg The package for which the permissions are updated
1509      * @param replace If the app is being replaced
1510      * @param updatedUserIds The ids of the users that already changed.
1511      *
1512      * @return The ids of the users that are changed
1513      */
checkIfLegacyStorageOpsNeedToBeUpdated( @onNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds)1514     private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
1515             @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
1516         if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
1517                 pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
1518                         || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
1519             return UserManagerService.getInstance().getUserIds();
1520         }
1521 
1522         return updatedUserIds;
1523     }
1524 
1525     /**
1526      * Set the state of a implicit permission that is seen for the first time.
1527      *
1528      * @param origPs The permission state of the package before the split
1529      * @param ps The new permission state
1530      * @param pkg The package the permission belongs to
1531      * @param updatedUserIds List of users for which the permission state has already been changed
1532      *
1533      * @return  List of users for which the permission state has been changed
1534      */
setInitialGrantForNewImplicitPermissionsLocked( @onNull PermissionsState origPs, @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull ArraySet<String> newImplicitPermissions, @NonNull int[] updatedUserIds)1535     private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1536             @NonNull PermissionsState origPs,
1537             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1538             @NonNull ArraySet<String> newImplicitPermissions,
1539             @NonNull int[] updatedUserIds) {
1540         String pkgName = pkg.packageName;
1541         ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1542 
1543         final List<PermissionManager.SplitPermissionInfo> permissionList = getSplitPermissions();
1544         int numSplitPerms = permissionList.size();
1545         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1546             PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum);
1547 
1548             List<String> newPerms = spi.getNewPermissions();
1549             int numNewPerms = newPerms.size();
1550             for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1551                 String newPerm = newPerms.get(newPermNum);
1552 
1553                 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1554                 if (splitPerms == null) {
1555                     splitPerms = new ArraySet<>();
1556                     newToSplitPerms.put(newPerm, splitPerms);
1557                 }
1558 
1559                 splitPerms.add(spi.getSplitPermission());
1560             }
1561         }
1562 
1563         int numNewImplicitPerms = newImplicitPermissions.size();
1564         for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1565                 newImplicitPermNum++) {
1566             String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1567             ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1568 
1569             if (sourcePerms != null) {
1570                 if (!ps.hasInstallPermission(newPerm)) {
1571                     BasePermission bp = mSettings.getPermissionLocked(newPerm);
1572 
1573                     int[] users = UserManagerService.getInstance().getUserIds();
1574                     int numUsers = users.length;
1575                     for (int userNum = 0; userNum < numUsers; userNum++) {
1576                         int userId = users[userNum];
1577 
1578                         if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
1579                             ps.updatePermissionFlags(bp, userId,
1580                                     FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1581                                     FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1582                         }
1583                         updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1584 
1585                         boolean inheritsFromInstallPerm = false;
1586                         for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1587                                 sourcePermNum++) {
1588                             if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1589                                 inheritsFromInstallPerm = true;
1590                                 break;
1591                             }
1592                         }
1593 
1594                         if (!origPs.hasRequestedPermission(sourcePerms)
1595                                 && !inheritsFromInstallPerm) {
1596                             // Both permissions are new so nothing to inherit.
1597                             if (DEBUG_PERMISSIONS) {
1598                                 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1599                                         + " for " + pkgName + " as split permission is also new");
1600                             }
1601                         } else {
1602                             // Inherit from new install or existing runtime permissions
1603                             inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1604                                     newPerm, ps, pkg, userId);
1605                         }
1606                     }
1607                 }
1608             }
1609         }
1610 
1611         return updatedUserIds;
1612     }
1613 
getSplitPermissions()1614     private List<PermissionManager.SplitPermissionInfo> getSplitPermissions() {
1615         return SystemConfig.getInstance().getSplitPermissions();
1616     }
1617 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)1618     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1619         boolean allowed = false;
1620         final int NP = PackageParser.NEW_PERMISSIONS.length;
1621         for (int ip=0; ip<NP; ip++) {
1622             final PackageParser.NewPermissionInfo npi
1623                     = PackageParser.NEW_PERMISSIONS[ip];
1624             if (npi.name.equals(perm)
1625                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1626                 allowed = true;
1627                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1628                         + pkg.packageName);
1629                 break;
1630             }
1631         }
1632         return allowed;
1633     }
1634 
1635     /**
1636      * Determines whether a package is whitelisted for a particular privapp permission.
1637      *
1638      * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1639      *
1640      * <p>This handles parent/child apps.
1641      */
hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg)1642     private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
1643         ArraySet<String> wlPermissions = null;
1644         if (pkg.isVendor()) {
1645             wlPermissions =
1646                     SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1647         } else if (pkg.isProduct()) {
1648             wlPermissions =
1649                     SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
1650         } else if (pkg.isSystemExt()) {
1651             wlPermissions =
1652                     SystemConfig.getInstance().getSystemExtPrivAppPermissions(
1653                             pkg.packageName);
1654         } else {
1655             wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1656         }
1657         // Let's check if this package is whitelisted...
1658         boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1659         // If it's not, we'll also tail-recurse to the parent.
1660         return whitelisted ||
1661                 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1662     }
1663 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)1664     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1665             BasePermission bp, PermissionsState origPermissions) {
1666         boolean oemPermission = bp.isOEM();
1667         boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1668         boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
1669         boolean privappPermissionsDisable =
1670                 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1671         boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1672         boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1673         if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1674                 && !platformPackage && platformPermission) {
1675             if (!hasPrivappWhitelistEntry(perm, pkg)) {
1676                 // Only report violations for apps on system image
1677                 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1678                     // it's only a reportable violation if the permission isn't explicitly denied
1679                     ArraySet<String> deniedPermissions = null;
1680                     if (pkg.isVendor()) {
1681                         deniedPermissions = SystemConfig.getInstance()
1682                                 .getVendorPrivAppDenyPermissions(pkg.packageName);
1683                     } else if (pkg.isProduct()) {
1684                         deniedPermissions = SystemConfig.getInstance()
1685                                 .getProductPrivAppDenyPermissions(pkg.packageName);
1686                     } else if (pkg.isSystemExt()) {
1687                         deniedPermissions = SystemConfig.getInstance()
1688                                 .getSystemExtPrivAppDenyPermissions(pkg.packageName);
1689                     } else {
1690                         deniedPermissions = SystemConfig.getInstance()
1691                                 .getPrivAppDenyPermissions(pkg.packageName);
1692                     }
1693                     final boolean permissionViolation =
1694                             deniedPermissions == null || !deniedPermissions.contains(perm);
1695                     if (permissionViolation) {
1696                         Slog.w(TAG, "Privileged permission " + perm + " for package "
1697                                 + pkg.packageName + " - not in privapp-permissions whitelist");
1698 
1699                         if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1700                             if (mPrivappPermissionsViolations == null) {
1701                                 mPrivappPermissionsViolations = new ArraySet<>();
1702                             }
1703                             mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
1704                         }
1705                     } else {
1706                         return false;
1707                     }
1708                 }
1709                 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1710                     return false;
1711                 }
1712             }
1713         }
1714         // expect single system package
1715         String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
1716                 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
1717         final PackageParser.Package systemPackage =
1718                 mPackageManagerInt.getPackage(systemPackageName);
1719 
1720         // check if the package is allow to use this signature permission.  A package is allowed to
1721         // use a signature permission if:
1722         //     - it has the same set of signing certificates as the source package
1723         //     - or its signing certificate was rotated from the source package's certificate
1724         //     - or its signing certificate is a previous signing certificate of the defining
1725         //       package, and the defining package still trusts the old certificate for permissions
1726         //     - or it shares the above relationships with the system package
1727         boolean allowed =
1728                 pkg.mSigningDetails.hasAncestorOrSelf(
1729                         bp.getSourcePackageSetting().getSigningDetails())
1730                 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1731                         pkg.mSigningDetails,
1732                         PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1733                 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1734                 || systemPackage.mSigningDetails.checkCapability(
1735                         pkg.mSigningDetails,
1736                         PackageParser.SigningDetails.CertCapabilities.PERMISSION);
1737         if (!allowed && (privilegedPermission || oemPermission)) {
1738             if (pkg.isSystem()) {
1739                 // For updated system applications, a privileged/oem permission
1740                 // is granted only if it had been defined by the original application.
1741                 if (pkg.isUpdatedSystemApp()) {
1742                     final PackageParser.Package disabledPkg =
1743                             mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
1744                     final PackageSetting disabledPs =
1745                             (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1746                     if (disabledPs != null
1747                             && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1748                         // If the original was granted this permission, we take
1749                         // that grant decision as read and propagate it to the
1750                         // update.
1751                         if ((privilegedPermission && disabledPs.isPrivileged())
1752                                 || (oemPermission && disabledPs.isOem()
1753                                         && canGrantOemPermission(disabledPs, perm))) {
1754                             allowed = true;
1755                         }
1756                     } else {
1757                         // The system apk may have been updated with an older
1758                         // version of the one on the data partition, but which
1759                         // granted a new system permission that it didn't have
1760                         // before.  In this case we do want to allow the app to
1761                         // now get the new permission if the ancestral apk is
1762                         // privileged to get it.
1763                         if (disabledPs != null && disabledPkg != null
1764                                 && isPackageRequestingPermission(disabledPkg, perm)
1765                                 && ((privilegedPermission && disabledPs.isPrivileged())
1766                                         || (oemPermission && disabledPs.isOem()
1767                                                 && canGrantOemPermission(disabledPs, perm)))) {
1768                             allowed = true;
1769                         }
1770                         // Also if a privileged parent package on the system image or any of
1771                         // its children requested a privileged/oem permission, the updated child
1772                         // packages can also get the permission.
1773                         if (pkg.parentPackage != null) {
1774                             final PackageParser.Package disabledParentPkg = mPackageManagerInt
1775                                     .getDisabledSystemPackage(pkg.parentPackage.packageName);
1776                             final PackageSetting disabledParentPs = (disabledParentPkg != null)
1777                                     ? (PackageSetting) disabledParentPkg.mExtras : null;
1778                             if (disabledParentPkg != null
1779                                     && ((privilegedPermission && disabledParentPs.isPrivileged())
1780                                             || (oemPermission && disabledParentPs.isOem()))) {
1781                                 if (isPackageRequestingPermission(disabledParentPkg, perm)
1782                                         && canGrantOemPermission(disabledParentPs, perm)) {
1783                                     allowed = true;
1784                                 } else if (disabledParentPkg.childPackages != null) {
1785                                     for (PackageParser.Package disabledChildPkg
1786                                             : disabledParentPkg.childPackages) {
1787                                         final PackageSetting disabledChildPs =
1788                                                 (disabledChildPkg != null)
1789                                                         ? (PackageSetting) disabledChildPkg.mExtras
1790                                                         : null;
1791                                         if (isPackageRequestingPermission(disabledChildPkg, perm)
1792                                                 && canGrantOemPermission(
1793                                                         disabledChildPs, perm)) {
1794                                             allowed = true;
1795                                             break;
1796                                         }
1797                                     }
1798                                 }
1799                             }
1800                         }
1801                     }
1802                 } else {
1803                     final PackageSetting ps = (PackageSetting) pkg.mExtras;
1804                     allowed = (privilegedPermission && pkg.isPrivileged())
1805                             || (oemPermission && pkg.isOem()
1806                                     && canGrantOemPermission(ps, perm));
1807                 }
1808                 // In any case, don't grant a privileged permission to privileged vendor apps, if
1809                 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1810                 // flag.
1811                 if (allowed && privilegedPermission &&
1812                         !vendorPrivilegedPermission && pkg.isVendor()) {
1813                    Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1814                            + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1815                    allowed = false;
1816                 }
1817             }
1818         }
1819         if (!allowed) {
1820             if (!allowed
1821                     && bp.isPre23()
1822                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1823                 // If this was a previously normal/dangerous permission that got moved
1824                 // to a system permission as part of the runtime permission redesign, then
1825                 // we still want to blindly grant it to old apps.
1826                 allowed = true;
1827             }
1828             // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1829             //                  need a separate flag anymore. Hence we need to check which
1830             //                  permissions are needed by the permission controller
1831             if (!allowed && bp.isInstaller()
1832                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1833                             PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
1834                     pkg.packageName) || ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1835                             PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1836                     UserHandle.USER_SYSTEM), pkg.packageName)) {
1837                 // If this permission is to be granted to the system installer and
1838                 // this app is an installer, then it gets the permission.
1839                 allowed = true;
1840             }
1841             if (!allowed && bp.isVerifier()
1842                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1843                             PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
1844                     pkg.packageName)) {
1845                 // If this permission is to be granted to the system verifier and
1846                 // this app is a verifier, then it gets the permission.
1847                 allowed = true;
1848             }
1849             if (!allowed && bp.isPreInstalled()
1850                     && pkg.isSystem()) {
1851                 // Any pre-installed system app is allowed to get this permission.
1852                 allowed = true;
1853             }
1854             if (!allowed && bp.isDevelopment()) {
1855                 // For development permissions, a development permission
1856                 // is granted only if it was already granted.
1857                 allowed = origPermissions.hasInstallPermission(perm);
1858             }
1859             if (!allowed && bp.isSetup()
1860                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1861                             PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
1862                     pkg.packageName)) {
1863                 // If this permission is to be granted to the system setup wizard and
1864                 // this app is a setup wizard, then it gets the permission.
1865                 allowed = true;
1866             }
1867             if (!allowed && bp.isSystemTextClassifier()
1868                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1869                             PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1870                     UserHandle.USER_SYSTEM), pkg.packageName)) {
1871                 // Special permissions for the system default text classifier.
1872                 allowed = true;
1873             }
1874             if (!allowed && bp.isConfigurator()
1875                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1876                             PackageManagerInternal.PACKAGE_CONFIGURATOR,
1877                     UserHandle.USER_SYSTEM), pkg.packageName)) {
1878                 // Special permissions for the device configurator.
1879                 allowed = true;
1880             }
1881             if (!allowed && bp.isWellbeing()
1882                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1883                             PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
1884                     pkg.packageName)) {
1885                 // Special permission granted only to the OEM specified wellbeing app
1886                 allowed = true;
1887             }
1888             if (!allowed && bp.isDocumenter()
1889                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1890                             PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
1891                     pkg.packageName)) {
1892                 // If this permission is to be granted to the documenter and
1893                 // this app is the documenter, then it gets the permission.
1894                 allowed = true;
1895             }
1896             if (!allowed && bp.isIncidentReportApprover()
1897                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1898                             PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
1899                     UserHandle.USER_SYSTEM), pkg.packageName)) {
1900                 // If this permission is to be granted to the incident report approver and
1901                 // this app is the incident report approver, then it gets the permission.
1902                 allowed = true;
1903             }
1904             if (!allowed && bp.isAppPredictor()
1905                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1906                             PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
1907                     pkg.packageName)) {
1908                 // Special permissions for the system app predictor.
1909                 allowed = true;
1910             }
1911             if (!allowed && bp.isTelephony()
1912                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1913                         PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM),
1914                     pkg.packageName)) {
1915                 // Special permissions for the system telephony apps.
1916                 allowed = true;
1917             }
1918         }
1919         return allowed;
1920     }
1921 
canGrantOemPermission(PackageSetting ps, String permission)1922     private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1923         if (!ps.isOem()) {
1924             return false;
1925         }
1926         // all oem permissions must explicitly be granted or denied
1927         final Boolean granted =
1928                 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1929         if (granted == null) {
1930             throw new IllegalStateException("OEM permission" + permission + " requested by package "
1931                     + ps.name + " must be explicitly declared granted or not");
1932         }
1933         return Boolean.TRUE == granted;
1934     }
1935 
isPermissionsReviewRequired(@onNull PackageParser.Package pkg, @UserIdInt int userId)1936     private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
1937             @UserIdInt int userId) {
1938         // Permission review applies only to apps not supporting the new permission model.
1939         if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1940             return false;
1941         }
1942 
1943         // Legacy apps have the permission and get user consent on launch.
1944         if (pkg.mExtras == null) {
1945             return false;
1946         }
1947         final PackageSetting ps = (PackageSetting) pkg.mExtras;
1948         final PermissionsState permissionsState = ps.getPermissionsState();
1949         return permissionsState.isPermissionReviewRequired(userId);
1950     }
1951 
isPackageRequestingPermission(PackageParser.Package pkg, String permission)1952     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1953         final int permCount = pkg.requestedPermissions.size();
1954         for (int j = 0; j < permCount; j++) {
1955             String requestedPermission = pkg.requestedPermissions.get(j);
1956             if (permission.equals(requestedPermission)) {
1957                 return true;
1958             }
1959         }
1960         return false;
1961     }
1962 
1963     @GuardedBy("mLock")
grantRuntimePermissionsGrantedToDisabledPackageLocked( PackageParser.Package pkg, int callingUid, PermissionCallback callback)1964     private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1965             PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1966         if (pkg.parentPackage == null) {
1967             return;
1968         }
1969         if (pkg.requestedPermissions == null) {
1970             return;
1971         }
1972         final PackageParser.Package disabledPkg =
1973                 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
1974         if (disabledPkg == null || disabledPkg.mExtras == null) {
1975             return;
1976         }
1977         final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1978         if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1979             return;
1980         }
1981         final int permCount = pkg.requestedPermissions.size();
1982         for (int i = 0; i < permCount; i++) {
1983             String permission = pkg.requestedPermissions.get(i);
1984             BasePermission bp = mSettings.getPermissionLocked(permission);
1985             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1986                 continue;
1987             }
1988             for (int userId : mUserManagerInt.getUserIds()) {
1989                 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1990                     grantRuntimePermission(
1991                             permission, pkg.packageName, false, callingUid, userId, callback);
1992                 }
1993             }
1994         }
1995     }
1996 
grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions, int callingUid, PermissionCallback callback)1997     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1998             String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1999         for (int userId : userIds) {
2000             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
2001                     callback);
2002         }
2003     }
2004 
getWhitelistedRestrictedPermissions( @onNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags, @UserIdInt int userId)2005     private @Nullable List<String> getWhitelistedRestrictedPermissions(
2006             @NonNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags,
2007             @UserIdInt int userId) {
2008         final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
2009         if (packageSetting == null) {
2010             return null;
2011         }
2012 
2013         final PermissionsState permissionsState = packageSetting.getPermissionsState();
2014 
2015         int queryFlags = 0;
2016         if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
2017             queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2018         }
2019         if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
2020             queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2021         }
2022         if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
2023             queryFlags |=  PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2024         }
2025 
2026         ArrayList<String> whitelistedPermissions = null;
2027 
2028         final int permissionCount = pkg.requestedPermissions.size();
2029         for (int i = 0; i < permissionCount; i++) {
2030             final String permissionName = pkg.requestedPermissions.get(i);
2031             final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId);
2032             if ((currentFlags & queryFlags) != 0) {
2033                 if (whitelistedPermissions == null) {
2034                     whitelistedPermissions = new ArrayList<>();
2035                 }
2036                 whitelistedPermissions.add(permissionName);
2037             }
2038         }
2039 
2040         return whitelistedPermissions;
2041     }
2042 
grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions, int callingUid, PermissionCallback callback)2043     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2044             String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2045         PackageSetting ps = (PackageSetting) pkg.mExtras;
2046         if (ps == null) {
2047             return;
2048         }
2049 
2050         PermissionsState permissionsState = ps.getPermissionsState();
2051 
2052         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2053                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2054 
2055         final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2056                 >= Build.VERSION_CODES.M;
2057 
2058         final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
2059 
2060         for (String permission : pkg.requestedPermissions) {
2061             final BasePermission bp;
2062             synchronized (mLock) {
2063                 bp = mSettings.getPermissionLocked(permission);
2064             }
2065             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2066                     && (!instantApp || bp.isInstant())
2067                     && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2068                     && (grantedPermissions == null
2069                            || ArrayUtils.contains(grantedPermissions, permission))) {
2070                 final int flags = permissionsState.getPermissionFlags(permission, userId);
2071                 if (supportsRuntimePermissions) {
2072                     // Installer cannot change immutable permissions.
2073                     if ((flags & immutableFlags) == 0) {
2074                         grantRuntimePermission(permission, pkg.packageName, false, callingUid,
2075                                 userId, callback);
2076                     }
2077                 } else {
2078                     // In permission review mode we clear the review flag when we
2079                     // are asked to install the app with all permissions granted.
2080                     if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2081                         updatePermissionFlags(permission, pkg.packageName,
2082                                 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
2083                                 userId, false, callback);
2084                     }
2085                 }
2086             }
2087         }
2088     }
2089 
grantRuntimePermission(String permName, String packageName, boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback)2090     private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
2091             int callingUid, final int userId, PermissionCallback callback) {
2092         if (!mUserManagerInt.exists(userId)) {
2093             Log.e(TAG, "No such user:" + userId);
2094             return;
2095         }
2096 
2097         mContext.enforceCallingOrSelfPermission(
2098                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
2099                 "grantRuntimePermission");
2100 
2101         enforceCrossUserPermission(callingUid, userId,
2102                 true,  // requireFullPermission
2103                 true,  // checkShell
2104                 false, // requirePermissionWhenSameUser
2105                 "grantRuntimePermission");
2106 
2107         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2108         if (pkg == null || pkg.mExtras == null) {
2109             Log.e(TAG, "Unknown package: " + packageName);
2110             return;
2111         }
2112         final BasePermission bp;
2113         synchronized(mLock) {
2114             bp = mSettings.getPermissionLocked(permName);
2115         }
2116         if (bp == null) {
2117             throw new IllegalArgumentException("Unknown permission: " + permName);
2118         }
2119         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2120             throw new IllegalArgumentException("Unknown package: " + packageName);
2121         }
2122 
2123         bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2124 
2125         // If a permission review is required for legacy apps we represent
2126         // their permissions as always granted runtime ones since we need
2127         // to keep the review required permission flag per user while an
2128         // install permission's state is shared across all users.
2129         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2130                 && bp.isRuntime()) {
2131             return;
2132         }
2133 
2134         final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2135 
2136         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2137         final PermissionsState permissionsState = ps.getPermissionsState();
2138 
2139         final int flags = permissionsState.getPermissionFlags(permName, userId);
2140         if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
2141             Log.e(TAG, "Cannot grant system fixed permission "
2142                     + permName + " for package " + packageName);
2143             return;
2144         }
2145         if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2146             Log.e(TAG, "Cannot grant policy fixed permission "
2147                     + permName + " for package " + packageName);
2148             return;
2149         }
2150 
2151         if (bp.isHardRestricted()
2152                 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
2153             Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
2154                     + permName + " for package " + packageName);
2155             return;
2156         }
2157 
2158         if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
2159                 pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
2160             Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
2161                     + packageName);
2162             return;
2163         }
2164 
2165         if (bp.isDevelopment()) {
2166             // Development permissions must be handled specially, since they are not
2167             // normal runtime permissions.  For now they apply to all users.
2168             if (permissionsState.grantInstallPermission(bp) !=
2169                     PERMISSION_OPERATION_FAILURE) {
2170                 if (callback != null) {
2171                     callback.onInstallPermissionGranted();
2172                 }
2173             }
2174             return;
2175         }
2176 
2177         if (ps.getInstantApp(userId) && !bp.isInstant()) {
2178             throw new SecurityException("Cannot grant non-ephemeral permission"
2179                     + permName + " for package " + packageName);
2180         }
2181 
2182         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2183             Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2184             return;
2185         }
2186 
2187         final int result = permissionsState.grantRuntimePermission(bp, userId);
2188         switch (result) {
2189             case PERMISSION_OPERATION_FAILURE: {
2190                 return;
2191             }
2192 
2193             case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2194                 if (callback != null) {
2195                     callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2196                 }
2197             }
2198             break;
2199         }
2200 
2201         if (bp.isRuntime()) {
2202             logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
2203         }
2204 
2205         if (callback != null) {
2206             callback.onPermissionGranted(uid, userId);
2207         }
2208 
2209         if (bp.isRuntime()) {
2210             notifyRuntimePermissionStateChanged(packageName, userId);
2211         }
2212 
2213         // Only need to do this if user is initialized. Otherwise it's a new user
2214         // and there are no processes running as the user yet and there's no need
2215         // to make an expensive call to remount processes for the changed permissions.
2216         if (READ_EXTERNAL_STORAGE.equals(permName)
2217                 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2218             final long token = Binder.clearCallingIdentity();
2219             try {
2220                 if (mUserManagerInt.isUserInitialized(userId)) {
2221                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
2222                             StorageManagerInternal.class);
2223                     storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2224                 }
2225             } finally {
2226                 Binder.restoreCallingIdentity(token);
2227             }
2228         }
2229 
2230     }
2231 
revokeRuntimePermission(String permName, String packageName, boolean overridePolicy, int userId, PermissionCallback callback)2232     private void revokeRuntimePermission(String permName, String packageName,
2233             boolean overridePolicy, int userId, PermissionCallback callback) {
2234         if (!mUserManagerInt.exists(userId)) {
2235             Log.e(TAG, "No such user:" + userId);
2236             return;
2237         }
2238 
2239         mContext.enforceCallingOrSelfPermission(
2240                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2241                 "revokeRuntimePermission");
2242 
2243         enforceCrossUserPermission(Binder.getCallingUid(), userId,
2244                 true,  // requireFullPermission
2245                 true,  // checkShell
2246                 false, // requirePermissionWhenSameUser
2247                 "revokeRuntimePermission");
2248 
2249         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2250         if (pkg == null || pkg.mExtras == null) {
2251             Log.e(TAG, "Unknown package: " + packageName);
2252             return;
2253         }
2254         if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2255             throw new IllegalArgumentException("Unknown package: " + packageName);
2256         }
2257         final BasePermission bp = mSettings.getPermissionLocked(permName);
2258         if (bp == null) {
2259             throw new IllegalArgumentException("Unknown permission: " + permName);
2260         }
2261 
2262         bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2263 
2264         // If a permission review is required for legacy apps we represent
2265         // their permissions as always granted runtime ones since we need
2266         // to keep the review required permission flag per user while an
2267         // install permission's state is shared across all users.
2268         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2269                 && bp.isRuntime()) {
2270             return;
2271         }
2272 
2273         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2274         final PermissionsState permissionsState = ps.getPermissionsState();
2275 
2276         final int flags = permissionsState.getPermissionFlags(permName, userId);
2277         // Only the system may revoke SYSTEM_FIXED permissions.
2278         if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2279                 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2280             throw new SecurityException("Non-System UID cannot revoke system fixed permission "
2281                     + permName + " for package " + packageName);
2282         }
2283         if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2284             throw new SecurityException("Cannot revoke policy fixed permission "
2285                     + permName + " for package " + packageName);
2286         }
2287 
2288         if (bp.isDevelopment()) {
2289             // Development permissions must be handled specially, since they are not
2290             // normal runtime permissions.  For now they apply to all users.
2291             if (permissionsState.revokeInstallPermission(bp) !=
2292                     PERMISSION_OPERATION_FAILURE) {
2293                 if (callback != null) {
2294                     callback.onInstallPermissionRevoked();
2295                 }
2296             }
2297             return;
2298         }
2299 
2300         // Permission is already revoked, no need to do anything.
2301         if (!permissionsState.hasRuntimePermission(permName, userId)) {
2302             return;
2303         }
2304 
2305         if (permissionsState.revokeRuntimePermission(bp, userId) ==
2306                 PERMISSION_OPERATION_FAILURE) {
2307             return;
2308         }
2309 
2310         if (bp.isRuntime()) {
2311             logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
2312         }
2313 
2314         if (callback != null) {
2315             callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2316         }
2317 
2318         if (bp.isRuntime()) {
2319             notifyRuntimePermissionStateChanged(packageName, userId);
2320         }
2321     }
2322 
setWhitelistedRestrictedPermissions(@onNull PackageParser.Package pkg, @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, @PackageManager.PermissionWhitelistFlags int whitelistFlags, @NonNull PermissionCallback callback)2323     private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
2324             @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
2325             @PackageManager.PermissionWhitelistFlags int whitelistFlags,
2326             @NonNull PermissionCallback callback) {
2327 
2328         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2329         if (ps == null) {
2330             return;
2331         }
2332 
2333         final PermissionsState permissionsState = ps.getPermissionsState();
2334         SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>();
2335         boolean updatePermissions = false;
2336 
2337         final int permissionCount = pkg.requestedPermissions.size();
2338         for (int userId : userIds) {
2339             for (int i = 0; i < permissionCount; i++) {
2340                 final String permissionName = pkg.requestedPermissions.get(i);
2341 
2342                 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
2343                 if (bp == null) {
2344                     Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
2345                     continue;
2346                 }
2347 
2348                 if (!bp.isHardOrSoftRestricted()) {
2349                     continue;
2350                 }
2351 
2352                 if (permissionsState.hasPermission(permissionName, userId)) {
2353                     if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) {
2354                         oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>());
2355                     }
2356                     oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName);
2357                 }
2358 
2359                 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
2360 
2361                 int newFlags = oldFlags;
2362                 int mask = 0;
2363                 int whitelistFlagsCopy = whitelistFlags;
2364                 while (whitelistFlagsCopy != 0) {
2365                     final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
2366                     whitelistFlagsCopy &= ~flag;
2367                     switch (flag) {
2368                         case FLAG_PERMISSION_WHITELIST_SYSTEM: {
2369                             mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2370                             if (permissions != null && permissions.contains(permissionName)) {
2371                                 newFlags |=
2372                                         PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2373                             } else {
2374                                 newFlags &=
2375                                         ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2376                             }
2377                         }
2378                         break;
2379                         case FLAG_PERMISSION_WHITELIST_UPGRADE: {
2380                             mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2381                             if (permissions != null && permissions.contains(permissionName)) {
2382                                 newFlags |=
2383                                         PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2384                             } else {
2385                                 newFlags &=
2386                                         ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2387                             }
2388                         }
2389                         break;
2390                         case FLAG_PERMISSION_WHITELIST_INSTALLER: {
2391                             mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2392                             if (permissions != null && permissions.contains(permissionName)) {
2393                                 newFlags |=
2394                                         PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2395                             } else {
2396                                 newFlags &= ~PackageManager
2397                                         .FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2398                             }
2399                         }
2400                         break;
2401                     }
2402                 }
2403 
2404                 if (oldFlags == newFlags) {
2405                     continue;
2406                 }
2407 
2408                 updatePermissions = true;
2409 
2410                 final boolean wasWhitelisted = (oldFlags
2411                         & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2412                 final boolean isWhitelisted = (newFlags
2413                         & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2414 
2415                 // If the permission is policy fixed as granted but it is no longer
2416                 // on any of the whitelists we need to clear the policy fixed flag
2417                 // as whitelisting trumps policy i.e. policy cannot grant a non
2418                 // grantable permission.
2419                 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2420                     final boolean isGranted = permissionsState.hasPermission(permissionName,
2421                             userId);
2422                     if (!isWhitelisted && isGranted) {
2423                         mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2424                         newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2425                     }
2426                 }
2427 
2428                 // If we are whitelisting an app that does not support runtime permissions
2429                 // we need to make sure it goes through the permission review UI at launch.
2430                 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2431                         && !wasWhitelisted && isWhitelisted) {
2432                     mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2433                     newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2434                 }
2435 
2436                 updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
2437                         callingUid, userId, false, null /*callback*/);
2438             }
2439         }
2440 
2441         if (updatePermissions) {
2442             // Update permission of this app to take into account the new whitelist state.
2443             restorePermissionState(pkg, false, pkg.packageName, callback);
2444 
2445             // If this resulted in losing a permission we need to kill the app.
2446             int oldGrantedRestrictedPermissionsByUserCount =
2447                     oldGrantedRestrictedPermissionsByUser.size();
2448             for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) {
2449                 final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j);
2450                 final ArraySet<String> oldGrantedRestrictedPermissions =
2451                         oldGrantedRestrictedPermissionsByUser.valueAt(j);
2452                 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
2453                 for (int i = 0; i < oldGrantedCount; i++) {
2454                     final String permission = oldGrantedRestrictedPermissions.valueAt(i);
2455                     // Sometimes we create a new permission state instance during update.
2456                     if (!ps.getPermissionsState().hasPermission(permission, userId)) {
2457                         callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2458                         break;
2459                     }
2460                 }
2461             }
2462         }
2463     }
2464 
2465     @GuardedBy("mLock")
revokeUnusedSharedUserPermissionsLocked( SharedUserSetting suSetting, int[] allUserIds)2466     private int[] revokeUnusedSharedUserPermissionsLocked(
2467             SharedUserSetting suSetting, int[] allUserIds) {
2468         // Collect all used permissions in the UID
2469         final ArraySet<String> usedPermissions = new ArraySet<>();
2470         final List<PackageParser.Package> pkgList = suSetting.getPackages();
2471         if (pkgList == null || pkgList.size() == 0) {
2472             return EmptyArray.INT;
2473         }
2474         for (PackageParser.Package pkg : pkgList) {
2475             if (pkg.requestedPermissions == null) {
2476                 continue;
2477             }
2478             final int requestedPermCount = pkg.requestedPermissions.size();
2479             for (int j = 0; j < requestedPermCount; j++) {
2480                 String permission = pkg.requestedPermissions.get(j);
2481                 BasePermission bp = mSettings.getPermissionLocked(permission);
2482                 if (bp != null) {
2483                     usedPermissions.add(permission);
2484                 }
2485             }
2486         }
2487 
2488         PermissionsState permissionsState = suSetting.getPermissionsState();
2489         // Prune install permissions
2490         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2491         final int installPermCount = installPermStates.size();
2492         for (int i = installPermCount - 1; i >= 0;  i--) {
2493             PermissionState permissionState = installPermStates.get(i);
2494             if (!usedPermissions.contains(permissionState.getName())) {
2495                 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2496                 if (bp != null) {
2497                     permissionsState.revokeInstallPermission(bp);
2498                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2499                             MASK_PERMISSION_FLAGS_ALL, 0);
2500                 }
2501             }
2502         }
2503 
2504         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2505 
2506         // Prune runtime permissions
2507         for (int userId : allUserIds) {
2508             List<PermissionState> runtimePermStates = permissionsState
2509                     .getRuntimePermissionStates(userId);
2510             final int runtimePermCount = runtimePermStates.size();
2511             for (int i = runtimePermCount - 1; i >= 0; i--) {
2512                 PermissionState permissionState = runtimePermStates.get(i);
2513                 if (!usedPermissions.contains(permissionState.getName())) {
2514                     BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2515                     if (bp != null) {
2516                         permissionsState.revokeRuntimePermission(bp, userId);
2517                         permissionsState.updatePermissionFlags(bp, userId,
2518                                 MASK_PERMISSION_FLAGS_ALL, 0);
2519                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2520                                 runtimePermissionChangedUserIds, userId);
2521                     }
2522                 }
2523             }
2524         }
2525 
2526         return runtimePermissionChangedUserIds;
2527     }
2528 
getAppOpPermissionPackages(String permName)2529     private String[] getAppOpPermissionPackages(String permName) {
2530         if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2531             return null;
2532         }
2533         synchronized (mLock) {
2534             final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2535             if (pkgs == null) {
2536                 return null;
2537             }
2538             return pkgs.toArray(new String[pkgs.size()]);
2539         }
2540     }
2541 
getPermissionFlags( String permName, String packageName, int callingUid, int userId)2542     private int getPermissionFlags(
2543             String permName, String packageName, int callingUid, int userId) {
2544         if (!mUserManagerInt.exists(userId)) {
2545             return 0;
2546         }
2547 
2548         enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
2549 
2550         enforceCrossUserPermission(callingUid, userId,
2551                 true,  // requireFullPermission
2552                 false, // checkShell
2553                 false, // requirePermissionWhenSameUser
2554                 "getPermissionFlags");
2555 
2556         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2557         if (pkg == null || pkg.mExtras == null) {
2558             return 0;
2559         }
2560         synchronized (mLock) {
2561             if (mSettings.getPermissionLocked(permName) == null) {
2562                 return 0;
2563             }
2564         }
2565         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2566             return 0;
2567         }
2568         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2569         PermissionsState permissionsState = ps.getPermissionsState();
2570         return permissionsState.getPermissionFlags(permName, userId);
2571     }
2572 
2573     private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2574     private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2575     private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2576 
updatePermissions(String packageName, PackageParser.Package pkg, boolean replaceGrant, Collection<PackageParser.Package> allPackages, PermissionCallback callback)2577     private void updatePermissions(String packageName, PackageParser.Package pkg,
2578             boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2579             PermissionCallback callback) {
2580         final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2581                 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2582         updatePermissions(
2583                 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2584         if (pkg != null && pkg.childPackages != null) {
2585             for (PackageParser.Package childPkg : pkg.childPackages) {
2586                 updatePermissions(childPkg.packageName, childPkg,
2587                         getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2588             }
2589         }
2590     }
2591 
updateAllPermissions(String volumeUuid, boolean sdkUpdated, Collection<PackageParser.Package> allPackages, PermissionCallback callback)2592     private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2593             Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2594         final int flags = UPDATE_PERMISSIONS_ALL |
2595                 (sdkUpdated
2596                         ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2597                         : 0);
2598         updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2599     }
2600 
updatePermissions(String changingPkgName, PackageParser.Package changingPkg, String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages, PermissionCallback callback)2601     private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2602             String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2603             PermissionCallback callback) {
2604         // TODO: Most of the methods exposing BasePermission internals [source package name,
2605         // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2606         // have package settings, we should make note of it elsewhere [map between
2607         // source package name and BasePermission] and cycle through that here. Then we
2608         // define a single method on BasePermission that takes a PackageSetting, changing
2609         // package name and a package.
2610         // NOTE: With this approach, we also don't need to tree trees differently than
2611         // normal permissions. Today, we need two separate loops because these BasePermission
2612         // objects are stored separately.
2613         // Make sure there are no dangling permission trees.
2614         flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2615 
2616         // Make sure all dynamic permissions have been assigned to a package,
2617         // and make sure there are no dangling permissions.
2618         flags = updatePermissions(changingPkgName, changingPkg, flags, callback);
2619 
2620         synchronized (mLock) {
2621             if (mBackgroundPermissions == null) {
2622                 // Cache background -> foreground permission mapping.
2623                 // Only system declares background permissions, hence mapping does never change.
2624                 mBackgroundPermissions = new ArrayMap<>();
2625                 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
2626                     if (bp.perm != null && bp.perm.info != null
2627                             && bp.perm.info.backgroundPermission != null) {
2628                         String fgPerm = bp.name;
2629                         String bgPerm = bp.perm.info.backgroundPermission;
2630 
2631                         List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2632                         if (fgPerms == null) {
2633                             fgPerms = new ArrayList<>();
2634                             mBackgroundPermissions.put(bgPerm, fgPerms);
2635                         }
2636 
2637                         fgPerms.add(fgPerm);
2638                     }
2639                 }
2640             }
2641         }
2642 
2643         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
2644         // Now update the permissions for all packages, in particular
2645         // replace the granted permissions of the system packages.
2646         if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2647             for (PackageParser.Package pkg : allPackages) {
2648                 if (pkg != changingPkg) {
2649                     // Only replace for packages on requested volume
2650                     final String volumeUuid = getVolumeUuidForPackage(pkg);
2651                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2652                             && Objects.equals(replaceVolumeUuid, volumeUuid);
2653                     restorePermissionState(pkg, replace, changingPkgName, callback);
2654                 }
2655             }
2656         }
2657 
2658         if (changingPkg != null) {
2659             // Only replace for packages on requested volume
2660             final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2661             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2662                     && Objects.equals(replaceVolumeUuid, volumeUuid);
2663             restorePermissionState(changingPkg, replace, changingPkgName, callback);
2664         }
2665         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2666     }
2667 
updatePermissions(String packageName, PackageParser.Package pkg, int flags, @Nullable PermissionCallback callback)2668     private int updatePermissions(String packageName, PackageParser.Package pkg, int flags,
2669             @Nullable PermissionCallback callback) {
2670         Set<BasePermission> needsUpdate = null;
2671         synchronized (mLock) {
2672             final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2673             while (it.hasNext()) {
2674                 final BasePermission bp = it.next();
2675                 if (bp.isDynamic()) {
2676                     bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2677                 }
2678                 if (bp.getSourcePackageSetting() != null) {
2679                     if (packageName != null && packageName.equals(bp.getSourcePackageName())
2680                         && (pkg == null || !hasPermission(pkg, bp.getName()))) {
2681                         Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2682                                 + " from package " + bp.getSourcePackageName());
2683                         if (bp.isRuntime()) {
2684                             final int[] userIds = mUserManagerInt.getUserIds();
2685                             final int numUserIds = userIds.length;
2686                             for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2687                                 final int userId = userIds[userIdNum];
2688 
2689                                 mPackageManagerInt.forEachPackage((Package p) -> {
2690                                     final String pName = p.packageName;
2691                                     final ApplicationInfo appInfo =
2692                                             mPackageManagerInt.getApplicationInfo(pName, 0,
2693                                                     Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
2694                                     if (appInfo != null
2695                                             && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2696                                         return;
2697                                     }
2698 
2699                                     final String permissionName = bp.getName();
2700                                     if (checkPermission(permissionName, pName, Process.SYSTEM_UID,
2701                                             userId) == PackageManager.PERMISSION_GRANTED) {
2702                                         try {
2703                                             revokeRuntimePermission(
2704                                                     permissionName,
2705                                                     pName,
2706                                                     false,
2707                                                     userId,
2708                                                     callback);
2709                                         } catch (IllegalArgumentException e) {
2710                                             Slog.e(TAG,
2711                                                     "Failed to revoke "
2712                                                             + permissionName
2713                                                             + " from "
2714                                                             + pName,
2715                                                     e);
2716                                         }
2717                                     }
2718                                 });
2719                             }
2720                         }
2721                         flags |= UPDATE_PERMISSIONS_ALL;
2722                         it.remove();
2723                     }
2724                     continue;
2725                 }
2726                 if (needsUpdate == null) {
2727                     needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2728                 }
2729                 needsUpdate.add(bp);
2730             }
2731         }
2732         if (needsUpdate != null) {
2733             for (final BasePermission bp : needsUpdate) {
2734                 final PackageParser.Package sourcePkg =
2735                         mPackageManagerInt.getPackage(bp.getSourcePackageName());
2736                 synchronized (mLock) {
2737                     if (sourcePkg != null && sourcePkg.mExtras != null) {
2738                         final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
2739                         if (bp.getSourcePackageSetting() == null) {
2740                             bp.setSourcePackageSetting(sourcePs);
2741                         }
2742                         continue;
2743                     }
2744                     Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2745                             + " from package " + bp.getSourcePackageName());
2746                     mSettings.removePermissionLocked(bp.getName());
2747                 }
2748             }
2749         }
2750         return flags;
2751     }
2752 
updatePermissionTrees(String packageName, PackageParser.Package pkg, int flags)2753     private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
2754             int flags) {
2755         Set<BasePermission> needsUpdate = null;
2756         synchronized (mLock) {
2757             final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2758             while (it.hasNext()) {
2759                 final BasePermission bp = it.next();
2760                 if (bp.getSourcePackageSetting() != null) {
2761                     if (packageName != null && packageName.equals(bp.getSourcePackageName())
2762                         && (pkg == null || !hasPermission(pkg, bp.getName()))) {
2763                         Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2764                                 + " from package " + bp.getSourcePackageName());
2765                         flags |= UPDATE_PERMISSIONS_ALL;
2766                         it.remove();
2767                     }
2768                     continue;
2769                 }
2770                 if (needsUpdate == null) {
2771                     needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2772                 }
2773                 needsUpdate.add(bp);
2774             }
2775         }
2776         if (needsUpdate != null) {
2777             for (final BasePermission bp : needsUpdate) {
2778                 final PackageParser.Package sourcePkg =
2779                         mPackageManagerInt.getPackage(bp.getSourcePackageName());
2780                 synchronized (mLock) {
2781                     if (sourcePkg != null && sourcePkg.mExtras != null) {
2782                         final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
2783                         if (bp.getSourcePackageSetting() == null) {
2784                             bp.setSourcePackageSetting(sourcePs);
2785                         }
2786                         continue;
2787                     }
2788                     Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2789                             + " from package " + bp.getSourcePackageName());
2790                     mSettings.removePermissionLocked(bp.getName());
2791                 }
2792             }
2793         }
2794         return flags;
2795     }
2796 
updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, int callingUid, int userId, boolean overridePolicy, PermissionCallback callback)2797     private void updatePermissionFlags(String permName, String packageName, int flagMask,
2798             int flagValues, int callingUid, int userId, boolean overridePolicy,
2799             PermissionCallback callback) {
2800         if (!mUserManagerInt.exists(userId)) {
2801             return;
2802         }
2803 
2804         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2805 
2806         enforceCrossUserPermission(callingUid, userId,
2807                 true,  // requireFullPermission
2808                 true,  // checkShell
2809                 false, // requirePermissionWhenSameUser
2810                 "updatePermissionFlags");
2811 
2812         if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2813             throw new SecurityException("updatePermissionFlags requires "
2814                     + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2815         }
2816 
2817         // Only the system can change these flags and nothing else.
2818         if (callingUid != Process.SYSTEM_UID) {
2819             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2820             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2821             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2822             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2823             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2824             flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2825             flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2826             flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2827             flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
2828         }
2829 
2830         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2831         if (pkg == null || pkg.mExtras == null) {
2832             Log.e(TAG, "Unknown package: " + packageName);
2833             return;
2834         }
2835         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2836             throw new IllegalArgumentException("Unknown package: " + packageName);
2837         }
2838 
2839         final BasePermission bp;
2840         synchronized (mLock) {
2841             bp = mSettings.getPermissionLocked(permName);
2842         }
2843         if (bp == null) {
2844             throw new IllegalArgumentException("Unknown permission: " + permName);
2845         }
2846 
2847         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2848         final PermissionsState permissionsState = ps.getPermissionsState();
2849         final boolean hadState =
2850                 permissionsState.getRuntimePermissionState(permName, userId) != null;
2851         final boolean permissionUpdated =
2852                 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
2853         if (permissionUpdated && bp.isRuntime()) {
2854             notifyRuntimePermissionStateChanged(packageName, userId);
2855         }
2856         if (permissionUpdated && callback != null) {
2857             // Install and runtime permissions are stored in different places,
2858             // so figure out what permission changed and persist the change.
2859             if (permissionsState.getInstallPermissionState(permName) != null) {
2860                 callback.onInstallPermissionUpdated();
2861             } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2862                     || hadState) {
2863                 callback.onPermissionUpdated(new int[] { userId }, false);
2864             }
2865         }
2866     }
2867 
updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid, int userId, Collection<Package> packages, PermissionCallback callback)2868     private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2869             int userId, Collection<Package> packages, PermissionCallback callback) {
2870         if (!mUserManagerInt.exists(userId)) {
2871             return false;
2872         }
2873 
2874         enforceGrantRevokeRuntimePermissionPermissions(
2875                 "updatePermissionFlagsForAllApps");
2876         enforceCrossUserPermission(callingUid, userId,
2877                 true,  // requireFullPermission
2878                 true,  // checkShell
2879                 false, // requirePermissionWhenSameUser
2880                 "updatePermissionFlagsForAllApps");
2881 
2882         // Only the system can change system fixed flags.
2883         if (callingUid != Process.SYSTEM_UID) {
2884             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2885             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2886         }
2887 
2888         boolean changed = false;
2889         for (PackageParser.Package pkg : packages) {
2890             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2891             if (ps == null) {
2892                 continue;
2893             }
2894             PermissionsState permissionsState = ps.getPermissionsState();
2895             changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2896                     userId, flagMask, flagValues);
2897         }
2898         return changed;
2899     }
2900 
enforceGrantRevokeRuntimePermissionPermissions(String message)2901     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2902         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2903                 != PackageManager.PERMISSION_GRANTED
2904             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2905                 != PackageManager.PERMISSION_GRANTED) {
2906             throw new SecurityException(message + " requires "
2907                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2908                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2909         }
2910     }
2911 
enforceGrantRevokeGetRuntimePermissionPermissions(@onNull String message)2912     private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
2913         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
2914                 != PackageManager.PERMISSION_GRANTED
2915             && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2916                 != PackageManager.PERMISSION_GRANTED
2917             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2918                 != PackageManager.PERMISSION_GRANTED) {
2919             throw new SecurityException(message + " requires "
2920                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2921                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
2922                     + Manifest.permission.GET_RUNTIME_PERMISSIONS);
2923         }
2924     }
2925 
2926     /**
2927      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2928      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2929      * @param checkShell whether to prevent shell from access if there's a debugging restriction
2930      * @param message the message to log on security exception
2931      */
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)2932     private void enforceCrossUserPermission(int callingUid, int userId,
2933             boolean requireFullPermission, boolean checkShell,
2934             boolean requirePermissionWhenSameUser, String message) {
2935         if (userId < 0) {
2936             throw new IllegalArgumentException("Invalid userId " + userId);
2937         }
2938         if (checkShell) {
2939             PackageManagerServiceUtils.enforceShellRestriction(
2940                     UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2941         }
2942         if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
2943         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
2944             if (requireFullPermission) {
2945                 mContext.enforceCallingOrSelfPermission(
2946                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2947             } else {
2948                 try {
2949                     mContext.enforceCallingOrSelfPermission(
2950                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2951                 } catch (SecurityException se) {
2952                     mContext.enforceCallingOrSelfPermission(
2953                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2954                 }
2955             }
2956         }
2957     }
2958 
2959     @GuardedBy({"mSettings.mLock", "mLock"})
calculateCurrentPermissionFootprintLocked(BasePermission tree)2960     private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2961         int size = 0;
2962         for (BasePermission perm : mSettings.mPermissions.values()) {
2963             size += tree.calculateFootprint(perm);
2964         }
2965         return size;
2966     }
2967 
2968     @GuardedBy({"mSettings.mLock", "mLock"})
enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)2969     private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2970         // We calculate the max size of permissions defined by this uid and throw
2971         // if that plus the size of 'info' would exceed our stated maximum.
2972         if (tree.getUid() != Process.SYSTEM_UID) {
2973             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2974             if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2975                 throw new SecurityException("Permission tree size cap exceeded");
2976             }
2977         }
2978     }
2979 
systemReady()2980     private void systemReady() {
2981         mSystemReady = true;
2982         if (mPrivappPermissionsViolations != null) {
2983             throw new IllegalStateException("Signature|privileged permissions not in "
2984                     + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2985         }
2986 
2987         mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
2988         mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
2989     }
2990 
getVolumeUuidForPackage(PackageParser.Package pkg)2991     private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2992         if (pkg == null) {
2993             return StorageManager.UUID_PRIVATE_INTERNAL;
2994         }
2995         if (pkg.isExternal()) {
2996             if (TextUtils.isEmpty(pkg.volumeUuid)) {
2997                 return StorageManager.UUID_PRIMARY_PHYSICAL;
2998             } else {
2999                 return pkg.volumeUuid;
3000             }
3001         } else {
3002             return StorageManager.UUID_PRIVATE_INTERNAL;
3003         }
3004     }
3005 
hasPermission(PackageParser.Package pkgInfo, String permName)3006     private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
3007         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
3008             if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
3009                 return true;
3010             }
3011         }
3012         return false;
3013     }
3014 
3015     /**
3016      * Log that a permission request was granted/revoked.
3017      *
3018      * @param action the action performed
3019      * @param name name of the permission
3020      * @param packageName package permission is for
3021      */
logPermission(int action, @NonNull String name, @NonNull String packageName)3022     private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
3023         final LogMaker log = new LogMaker(action);
3024         log.setPackageName(packageName);
3025         log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
3026 
3027         mMetricsLogger.write(log);
3028     }
3029 
3030     /**
3031      * Get the mapping of background permissions to their foreground permissions.
3032      *
3033      * <p>Only initialized in the system server.
3034      *
3035      * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
3036      */
getBackgroundPermissions()3037     public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
3038         return mBackgroundPermissions;
3039     }
3040 
3041     private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
3042         @Override
systemReady()3043         public void systemReady() {
3044             PermissionManagerService.this.systemReady();
3045         }
3046         @Override
isPermissionsReviewRequired(@onNull Package pkg, @UserIdInt int userId)3047         public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
3048             return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
3049         }
3050         @Override
revokeRuntimePermissionsIfGroupChanged( @onNull PackageParser.Package newPackage, @NonNull PackageParser.Package oldPackage, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback)3051         public void revokeRuntimePermissionsIfGroupChanged(
3052                 @NonNull PackageParser.Package newPackage,
3053                 @NonNull PackageParser.Package oldPackage,
3054                 @NonNull ArrayList<String> allPackageNames,
3055                 @NonNull PermissionCallback permissionCallback) {
3056             PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
3057                     oldPackage, allPackageNames, permissionCallback);
3058         }
3059         @Override
addAllPermissions(Package pkg, boolean chatty)3060         public void addAllPermissions(Package pkg, boolean chatty) {
3061             PermissionManagerService.this.addAllPermissions(pkg, chatty);
3062         }
3063         @Override
addAllPermissionGroups(Package pkg, boolean chatty)3064         public void addAllPermissionGroups(Package pkg, boolean chatty) {
3065             PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
3066         }
3067         @Override
removeAllPermissions(Package pkg, boolean chatty)3068         public void removeAllPermissions(Package pkg, boolean chatty) {
3069             PermissionManagerService.this.removeAllPermissions(pkg, chatty);
3070         }
3071         @Override
addDynamicPermission(PermissionInfo info, boolean async, int callingUid, PermissionCallback callback)3072         public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
3073                 PermissionCallback callback) {
3074             return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
3075         }
3076         @Override
removeDynamicPermission(String permName, int callingUid, PermissionCallback callback)3077         public void removeDynamicPermission(String permName, int callingUid,
3078                 PermissionCallback callback) {
3079             PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
3080         }
3081         @Override
grantRuntimePermission(String permName, String packageName, boolean overridePolicy, int callingUid, int userId, PermissionCallback callback)3082         public void grantRuntimePermission(String permName, String packageName,
3083                 boolean overridePolicy, int callingUid, int userId,
3084                 PermissionCallback callback) {
3085             PermissionManagerService.this.grantRuntimePermission(
3086                     permName, packageName, overridePolicy, callingUid, userId, callback);
3087         }
3088         @Override
grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions, int callingUid, PermissionCallback callback)3089         public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
3090                 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3091             PermissionManagerService.this.grantRequestedRuntimePermissions(
3092                     pkg, userIds, grantedPermissions, callingUid, callback);
3093         }
3094         @Override
getWhitelistedRestrictedPermissions(PackageParser.Package pkg, @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId)3095         public List<String> getWhitelistedRestrictedPermissions(PackageParser.Package pkg,
3096                 @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId) {
3097             return PermissionManagerService.this.getWhitelistedRestrictedPermissions(pkg,
3098                     whitelistFlags, userId);
3099         }
3100         @Override
setWhitelistedRestrictedPermissions(@onNull PackageParser.Package pkg, @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, @PackageManager.PermissionWhitelistFlags int whitelistFlags, @NonNull PermissionCallback callback)3101         public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
3102                 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
3103                 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
3104                 @NonNull PermissionCallback callback) {
3105             PermissionManagerService.this.setWhitelistedRestrictedPermissions(
3106                     pkg, userIds, permissions, callingUid, whitelistFlags, callback);
3107         }
3108         @Override
grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg, int callingUid, PermissionCallback callback)3109         public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
3110                 int callingUid, PermissionCallback callback) {
3111             PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
3112                     pkg, callingUid, callback);
3113         }
3114         @Override
revokeRuntimePermission(String permName, String packageName, boolean overridePolicy, int userId, PermissionCallback callback)3115         public void revokeRuntimePermission(String permName, String packageName,
3116                 boolean overridePolicy, int userId, PermissionCallback callback) {
3117             PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
3118                     overridePolicy, userId, callback);
3119         }
3120         @Override
updatePermissions(String packageName, Package pkg, boolean replaceGrant, Collection<PackageParser.Package> allPackages, PermissionCallback callback)3121         public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
3122                 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3123             PermissionManagerService.this.updatePermissions(
3124                     packageName, pkg, replaceGrant, allPackages, callback);
3125         }
3126         @Override
updateAllPermissions(String volumeUuid, boolean sdkUpdated, Collection<PackageParser.Package> allPackages, PermissionCallback callback)3127         public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
3128                 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3129             PermissionManagerService.this.updateAllPermissions(
3130                     volumeUuid, sdkUpdated, allPackages, callback);
3131         }
3132         @Override
getAppOpPermissionPackages(String permName)3133         public String[] getAppOpPermissionPackages(String permName) {
3134             return PermissionManagerService.this.getAppOpPermissionPackages(permName);
3135         }
3136         @Override
getPermissionFlags(String permName, String packageName, int callingUid, int userId)3137         public int getPermissionFlags(String permName, String packageName, int callingUid,
3138                 int userId) {
3139             return PermissionManagerService.this.getPermissionFlags(permName, packageName,
3140                     callingUid, userId);
3141         }
3142         @Override
updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, int callingUid, int userId, boolean overridePolicy, PermissionCallback callback)3143         public void updatePermissionFlags(String permName, String packageName, int flagMask,
3144                 int flagValues, int callingUid, int userId, boolean overridePolicy,
3145                 PermissionCallback callback) {
3146             PermissionManagerService.this.updatePermissionFlags(
3147                     permName, packageName, flagMask, flagValues, callingUid, userId,
3148                     overridePolicy, callback);
3149         }
3150         @Override
updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid, int userId, Collection<Package> packages, PermissionCallback callback)3151         public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
3152                 int userId, Collection<Package> packages, PermissionCallback callback) {
3153             return PermissionManagerService.this.updatePermissionFlagsForAllApps(
3154                     flagMask, flagValues, callingUid, userId, packages, callback);
3155         }
3156         @Override
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)3157         public void enforceCrossUserPermission(int callingUid, int userId,
3158                 boolean requireFullPermission, boolean checkShell, String message) {
3159             PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3160                     requireFullPermission, checkShell, false, message);
3161         }
3162         @Override
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)3163         public void enforceCrossUserPermission(int callingUid, int userId,
3164                 boolean requireFullPermission, boolean checkShell,
3165                 boolean requirePermissionWhenSameUser, String message) {
3166             PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3167                     requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
3168         }
3169         @Override
enforceGrantRevokeRuntimePermissionPermissions(String message)3170         public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3171             PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
3172         }
3173         @Override
checkPermission(String permName, String packageName, int callingUid, int userId)3174         public int checkPermission(String permName, String packageName, int callingUid,
3175                 int userId) {
3176             return PermissionManagerService.this.checkPermission(
3177                     permName, packageName, callingUid, userId);
3178         }
3179         @Override
checkUidPermission(String permName, PackageParser.Package pkg, int uid, int callingUid)3180         public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
3181                 int callingUid) {
3182             return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
3183         }
3184         @Override
getPermissionGroupInfo(String groupName, int flags, int callingUid)3185         public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
3186                 int callingUid) {
3187             return PermissionManagerService.this.getPermissionGroupInfo(
3188                     groupName, flags, callingUid);
3189         }
3190         @Override
getAllPermissionGroups(int flags, int callingUid)3191         public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
3192             return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
3193         }
3194         @Override
getPermissionInfo(String permName, String packageName, int flags, int callingUid)3195         public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
3196                 int callingUid) {
3197             return PermissionManagerService.this.getPermissionInfo(
3198                     permName, packageName, flags, callingUid);
3199         }
3200         @Override
getPermissionInfoByGroup(String group, int flags, int callingUid)3201         public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
3202                 int callingUid) {
3203             return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
3204         }
3205         @Override
getPermissionSettings()3206         public PermissionSettings getPermissionSettings() {
3207             return mSettings;
3208         }
3209         @Override
getDefaultPermissionGrantPolicy()3210         public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
3211             return mDefaultPermissionGrantPolicy;
3212         }
3213         @Override
getPermissionTEMP(String permName)3214         public BasePermission getPermissionTEMP(String permName) {
3215             synchronized (PermissionManagerService.this.mLock) {
3216                 return mSettings.getPermissionLocked(permName);
3217             }
3218         }
3219 
3220         @Override
getAllPermissionWithProtectionLevel( @ermissionInfo.Protection int protectionLevel)3221         public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
3222                 @PermissionInfo.Protection int protectionLevel) {
3223             ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
3224 
3225             synchronized (PermissionManagerService.this.mLock) {
3226                 int numTotalPermissions = mSettings.mPermissions.size();
3227 
3228                 for (int i = 0; i < numTotalPermissions; i++) {
3229                     BasePermission bp = mSettings.mPermissions.valueAt(i);
3230 
3231                     if (bp.perm != null && bp.perm.info != null
3232                             && bp.protectionLevel == protectionLevel) {
3233                         matchingPermissions.add(bp.perm.info);
3234                     }
3235                 }
3236             }
3237 
3238             return matchingPermissions;
3239         }
3240 
3241         @Override
backupRuntimePermissions(@onNull UserHandle user)3242         public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
3243             return PermissionManagerService.this.backupRuntimePermissions(user);
3244         }
3245 
3246         @Override
restoreRuntimePermissions(@onNull byte[] backup, @NonNull UserHandle user)3247         public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
3248             PermissionManagerService.this.restoreRuntimePermissions(backup, user);
3249         }
3250 
3251         @Override
restoreDelayedRuntimePermissions(@onNull String packageName, @NonNull UserHandle user)3252         public void restoreDelayedRuntimePermissions(@NonNull String packageName,
3253                 @NonNull UserHandle user) {
3254             PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
3255         }
3256 
3257         @Override
addOnRuntimePermissionStateChangedListener( OnRuntimePermissionStateChangedListener listener)3258         public void addOnRuntimePermissionStateChangedListener(
3259                 OnRuntimePermissionStateChangedListener listener) {
3260             PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
3261                     listener);
3262         }
3263 
3264         @Override
removeOnRuntimePermissionStateChangedListener( OnRuntimePermissionStateChangedListener listener)3265         public void removeOnRuntimePermissionStateChangedListener(
3266                 OnRuntimePermissionStateChangedListener listener) {
3267             PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
3268                     listener);
3269         }
3270     }
3271 }
3272