• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                         int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
972                         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
973                             PermissionManager.SplitPermissionInfo sp =
974                                     PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
975                             String splitPermName = sp.getSplitPermission();
976                             if (sp.getNewPermissions().contains(permName)
977                                     && origPermissions.hasInstallPermission(splitPermName)) {
978                                 upgradedActivityRecognitionPermission = splitPermName;
979                                 newImplicitPermissions.add(permName);
980 
981                                 if (DEBUG_PERMISSIONS) {
982                                     Slog.i(TAG, permName + " is newly added for "
983                                             + pkg.packageName);
984                                 }
985                                 break;
986                             }
987                         }
988                     }
989                 }
990 
991                 // Limit ephemeral apps to ephemeral allowed permissions.
992                 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
993                     if (DEBUG_PERMISSIONS) {
994                         Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
995                                 + " for package " + pkg.packageName);
996                     }
997                     continue;
998                 }
999 
1000                 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
1001                     if (DEBUG_PERMISSIONS) {
1002                         Log.i(TAG, "Denying runtime-only permission " + bp.getName()
1003                                 + " for package " + pkg.packageName);
1004                     }
1005                     continue;
1006                 }
1007 
1008                 final String perm = bp.getName();
1009                 boolean allowedSig = false;
1010                 int grant = GRANT_DENIED;
1011 
1012                 // Keep track of app op permissions.
1013                 if (bp.isAppOp()) {
1014                     mSettings.addAppOpPackage(perm, pkg.packageName);
1015                 }
1016 
1017                 if (bp.isNormal()) {
1018                     // For all apps normal permissions are install time ones.
1019                     grant = GRANT_INSTALL;
1020                 } else if (bp.isRuntime()) {
1021                     if (origPermissions.hasInstallPermission(bp.getName())
1022                             || upgradedActivityRecognitionPermission != null) {
1023                         // Before Q we represented some runtime permissions as install permissions,
1024                         // in Q we cannot do this anymore. Hence upgrade them all.
1025                         grant = GRANT_UPGRADE;
1026                     } else {
1027                         // For modern apps keep runtime permissions unchanged.
1028                         grant = GRANT_RUNTIME;
1029                     }
1030                 } else if (bp.isSignature()) {
1031                     // For all apps signature permissions are install time ones.
1032                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
1033                     if (allowedSig) {
1034                         grant = GRANT_INSTALL;
1035                     }
1036                 }
1037 
1038                 if (DEBUG_PERMISSIONS) {
1039                     Slog.i(TAG, "Considering granting permission " + perm + " to package "
1040                             + pkg.packageName);
1041                 }
1042 
1043                 if (grant != GRANT_DENIED) {
1044                     if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
1045                         // If this is an existing, non-system package, then
1046                         // we can't add any new permissions to it. Runtime
1047                         // permissions can be added any time - they ad dynamic.
1048                         if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
1049                             // Except...  if this is a permission that was added
1050                             // to the platform (note: need to only do this when
1051                             // updating the platform).
1052                             if (!isNewPlatformPermissionForPackage(perm, pkg)) {
1053                                 grant = GRANT_DENIED;
1054                             }
1055                         }
1056                     }
1057 
1058                     switch (grant) {
1059                         case GRANT_INSTALL: {
1060                             // Revoke this as runtime permission to handle the case of
1061                             // a runtime permission being downgraded to an install one.
1062                             // Also in permission review mode we keep dangerous permissions
1063                             // for legacy apps
1064                             for (int userId : UserManagerService.getInstance().getUserIds()) {
1065                                 if (origPermissions.getRuntimePermissionState(
1066                                         perm, userId) != null) {
1067                                     // Revoke the runtime permission and clear the flags.
1068                                     origPermissions.revokeRuntimePermission(bp, userId);
1069                                     origPermissions.updatePermissionFlags(bp, userId,
1070                                             PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
1071                                     // If we revoked a permission permission, we have to write.
1072                                     updatedUserIds = ArrayUtils.appendInt(
1073                                             updatedUserIds, userId);
1074                                 }
1075                             }
1076                             // Grant an install permission.
1077                             if (permissionsState.grantInstallPermission(bp) !=
1078                                     PERMISSION_OPERATION_FAILURE) {
1079                                 changedInstallPermission = true;
1080                             }
1081                         } break;
1082 
1083                         case GRANT_RUNTIME: {
1084                             boolean hardRestricted = bp.isHardRestricted();
1085                             boolean softRestricted = bp.isSoftRestricted();
1086 
1087                             for (int userId : currentUserIds) {
1088                                 // If permission policy is not ready we don't deal with restricted
1089                                 // permissions as the policy may whitelist some permissions. Once
1090                                 // the policy is initialized we would re-evaluate permissions.
1091                                 final boolean permissionPolicyInitialized =
1092                                         mPermissionPolicyInternal != null
1093                                                 && mPermissionPolicyInternal.isInitialized(userId);
1094 
1095                                 PermissionState permState = origPermissions
1096                                         .getRuntimePermissionState(perm, userId);
1097                                 int flags = permState != null ? permState.getFlags() : 0;
1098 
1099                                 boolean wasChanged = false;
1100 
1101                                 boolean restrictionExempt =
1102                                         (origPermissions.getPermissionFlags(bp.name, userId)
1103                                                 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1104                                 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1105                                         bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1106 
1107                                 if (appSupportsRuntimePermissions) {
1108                                     // If hard restricted we don't allow holding it
1109                                     if (permissionPolicyInitialized && hardRestricted) {
1110                                         if (!restrictionExempt) {
1111                                             if (permState != null && permState.isGranted()
1112                                                     && permissionsState.revokeRuntimePermission(
1113                                                     bp, userId) != PERMISSION_OPERATION_FAILURE) {
1114                                                 wasChanged = true;
1115                                             }
1116                                             if (!restrictionApplied) {
1117                                                 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1118                                                 wasChanged = true;
1119                                             }
1120                                         }
1121                                     // If soft restricted we allow holding in a restricted form
1122                                     } else if (permissionPolicyInitialized && softRestricted) {
1123                                         // Regardless if granted set the restriction flag as it
1124                                         // may affect app treatment based on this permission.
1125                                         if (!restrictionExempt && !restrictionApplied) {
1126                                             flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1127                                             wasChanged = true;
1128                                         }
1129                                     }
1130 
1131                                     // Remove review flag as it is not necessary anymore
1132                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1133                                         flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1134                                         wasChanged = true;
1135                                     }
1136 
1137                                     if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1138                                         flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1139                                         wasChanged = true;
1140                                     // Hard restricted permissions cannot be held.
1141                                     } else if (!permissionPolicyInitialized
1142                                             || (!hardRestricted || restrictionExempt)) {
1143                                         if (permState != null && permState.isGranted()) {
1144                                             if (permissionsState.grantRuntimePermission(bp, userId)
1145                                                     == PERMISSION_OPERATION_FAILURE) {
1146                                                 wasChanged = true;
1147                                             }
1148                                         }
1149                                     }
1150                                 } else {
1151                                     if (permState == null) {
1152                                         // New permission
1153                                         if (PLATFORM_PACKAGE_NAME.equals(
1154                                                 bp.getSourcePackageName())) {
1155                                             if (!bp.isRemoved()) {
1156                                                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
1157                                                         | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1158                                                 wasChanged = true;
1159                                             }
1160                                         }
1161                                     }
1162 
1163                                     if (!permissionsState.hasRuntimePermission(bp.name, userId)
1164                                             && permissionsState.grantRuntimePermission(bp, userId)
1165                                                     != PERMISSION_OPERATION_FAILURE) {
1166                                         wasChanged = true;
1167                                     }
1168 
1169                                     // If legacy app always grant the permission but if restricted
1170                                     // and not exempt take a note a restriction should be applied.
1171                                     if (permissionPolicyInitialized
1172                                             && (hardRestricted || softRestricted)
1173                                                     && !restrictionExempt && !restrictionApplied) {
1174                                         flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1175                                         wasChanged = true;
1176                                     }
1177                                 }
1178 
1179                                 // If unrestricted or restriction exempt, don't apply restriction.
1180                                 if (permissionPolicyInitialized) {
1181                                     if (!(hardRestricted || softRestricted) || restrictionExempt) {
1182                                         if (restrictionApplied) {
1183                                             flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1184                                             // Dropping restriction on a legacy app implies a review
1185                                             if (!appSupportsRuntimePermissions) {
1186                                                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1187                                             }
1188                                             wasChanged = true;
1189                                         }
1190                                     }
1191                                 }
1192 
1193                                 if (wasChanged) {
1194                                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1195                                 }
1196 
1197                                 permissionsState.updatePermissionFlags(bp, userId,
1198                                         MASK_PERMISSION_FLAGS_ALL, flags);
1199                             }
1200                         } break;
1201 
1202                         case GRANT_UPGRADE: {
1203                             // Upgrade from Pre-Q to Q permission model. Make all permissions
1204                             // runtime
1205                             PermissionState permState = origPermissions
1206                                     .getInstallPermissionState(perm);
1207                             int flags = (permState != null) ? permState.getFlags() : 0;
1208 
1209                             BasePermission bpToRevoke =
1210                                     upgradedActivityRecognitionPermission == null
1211                                     ? bp : mSettings.getPermissionLocked(
1212                                             upgradedActivityRecognitionPermission);
1213                             // Remove install permission
1214                             if (origPermissions.revokeInstallPermission(bpToRevoke)
1215                                     != PERMISSION_OPERATION_FAILURE) {
1216                                 origPermissions.updatePermissionFlags(bpToRevoke,
1217                                         UserHandle.USER_ALL,
1218                                         (MASK_PERMISSION_FLAGS_ALL
1219                                                 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
1220                                 changedInstallPermission = true;
1221                             }
1222 
1223                             boolean hardRestricted = bp.isHardRestricted();
1224                             boolean softRestricted = bp.isSoftRestricted();
1225 
1226                             for (int userId : currentUserIds) {
1227                                 // If permission policy is not ready we don't deal with restricted
1228                                 // permissions as the policy may whitelist some permissions. Once
1229                                 // the policy is initialized we would re-evaluate permissions.
1230                                 final boolean permissionPolicyInitialized =
1231                                         mPermissionPolicyInternal != null
1232                                                 && mPermissionPolicyInternal.isInitialized(userId);
1233 
1234                                 boolean wasChanged = false;
1235 
1236                                 boolean restrictionExempt =
1237                                         (origPermissions.getPermissionFlags(bp.name, userId)
1238                                                 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1239                                 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1240                                         bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1241 
1242                                 if (appSupportsRuntimePermissions) {
1243                                     // If hard restricted we don't allow holding it
1244                                     if (permissionPolicyInitialized && hardRestricted) {
1245                                         if (!restrictionExempt) {
1246                                             if (permState != null && permState.isGranted()
1247                                                     && permissionsState.revokeRuntimePermission(
1248                                                     bp, userId) != PERMISSION_OPERATION_FAILURE) {
1249                                                 wasChanged = true;
1250                                             }
1251                                             if (!restrictionApplied) {
1252                                                 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1253                                                 wasChanged = true;
1254                                             }
1255                                         }
1256                                     // If soft restricted we allow holding in a restricted form
1257                                     } else if (permissionPolicyInitialized && softRestricted) {
1258                                         // Regardless if granted set the  restriction flag as it
1259                                         // may affect app treatment based on this permission.
1260                                         if (!restrictionExempt && !restrictionApplied) {
1261                                             flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1262                                             wasChanged = true;
1263                                         }
1264                                     }
1265 
1266                                     // Remove review flag as it is not necessary anymore
1267                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1268                                         flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1269                                         wasChanged = true;
1270                                     }
1271 
1272                                     if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1273                                         flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1274                                         wasChanged = true;
1275                                     // Hard restricted permissions cannot be held.
1276                                     } else if (!permissionPolicyInitialized ||
1277                                             (!hardRestricted || restrictionExempt)) {
1278                                         if (permissionsState.grantRuntimePermission(bp, userId) !=
1279                                                 PERMISSION_OPERATION_FAILURE) {
1280                                              wasChanged = true;
1281                                         }
1282                                     }
1283                                 } else {
1284                                     if (!permissionsState.hasRuntimePermission(bp.name, userId)
1285                                             && permissionsState.grantRuntimePermission(bp,
1286                                                     userId) != PERMISSION_OPERATION_FAILURE) {
1287                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1288                                         wasChanged = true;
1289                                     }
1290 
1291                                     // If legacy app always grant the permission but if restricted
1292                                     // and not exempt take a note a restriction should be applied.
1293                                     if (permissionPolicyInitialized
1294                                             && (hardRestricted || softRestricted)
1295                                                     && !restrictionExempt && !restrictionApplied) {
1296                                         flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1297                                         wasChanged = true;
1298                                     }
1299                                 }
1300 
1301                                 // If unrestricted or restriction exempt, don't apply restriction.
1302                                 if (permissionPolicyInitialized) {
1303                                     if (!(hardRestricted || softRestricted) || restrictionExempt) {
1304                                         if (restrictionApplied) {
1305                                             flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1306                                             // Dropping restriction on a legacy app implies a review
1307                                             if (!appSupportsRuntimePermissions) {
1308                                                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1309                                             }
1310                                             wasChanged = true;
1311                                         }
1312                                     }
1313                                 }
1314 
1315                                 if (wasChanged) {
1316                                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1317                                 }
1318 
1319                                 permissionsState.updatePermissionFlags(bp, userId,
1320                                         MASK_PERMISSION_FLAGS_ALL, flags);
1321                             }
1322                         } break;
1323 
1324                         default: {
1325                             if (packageOfInterest == null
1326                                     || packageOfInterest.equals(pkg.packageName)) {
1327                                 if (DEBUG_PERMISSIONS) {
1328                                     Slog.i(TAG, "Not granting permission " + perm
1329                                             + " to package " + pkg.packageName
1330                                             + " because it was previously installed without");
1331                                 }
1332                             }
1333                         } break;
1334                     }
1335                 } else {
1336                     if (permissionsState.revokeInstallPermission(bp) !=
1337                             PERMISSION_OPERATION_FAILURE) {
1338                         // Also drop the permission flags.
1339                         permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1340                                 MASK_PERMISSION_FLAGS_ALL, 0);
1341                         changedInstallPermission = true;
1342                         Slog.i(TAG, "Un-granting permission " + perm
1343                                 + " from package " + pkg.packageName
1344                                 + " (protectionLevel=" + bp.getProtectionLevel()
1345                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1346                                 + ")");
1347                     } else if (bp.isAppOp()) {
1348                         // Don't print warning for app op permissions, since it is fine for them
1349                         // not to be granted, there is a UI for the user to decide.
1350                         if (DEBUG_PERMISSIONS
1351                                 && (packageOfInterest == null
1352                                         || packageOfInterest.equals(pkg.packageName))) {
1353                             Slog.i(TAG, "Not granting permission " + perm
1354                                     + " to package " + pkg.packageName
1355                                     + " (protectionLevel=" + bp.getProtectionLevel()
1356                                     + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1357                                     + ")");
1358                         }
1359                     }
1360                 }
1361             }
1362 
1363             if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1364                     !ps.isSystem() || ps.isUpdatedSystem()) {
1365                 // This is the first that we have heard about this package, so the
1366                 // permissions we have now selected are fixed until explicitly
1367                 // changed.
1368                 ps.setInstallPermissionsFixed(true);
1369             }
1370 
1371             updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1372                     updatedUserIds);
1373             updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
1374                     permissionsState, pkg, newImplicitPermissions, updatedUserIds);
1375             updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
1376         }
1377 
1378         // Persist the runtime permissions state for users with changes. If permissions
1379         // were revoked because no app in the shared user declares them we have to
1380         // write synchronously to avoid losing runtime permissions state.
1381         if (callback != null) {
1382             callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1383         }
1384 
1385         for (int userId : updatedUserIds) {
1386             notifyRuntimePermissionStateChanged(pkg.packageName, userId);
1387         }
1388     }
1389 
1390     /**
1391      * Revoke permissions that are not implicit anymore and that have
1392      * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1393      *
1394      * @param ps The state of the permissions of the package
1395      * @param pkg The package that is currently looked at
1396      * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1397      *                       for a user is changed.
1398      *
1399      * @return The updated value of the {@code updatedUserIds} parameter
1400      */
revokePermissionsNoLongerImplicitLocked( @onNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull int[] updatedUserIds)1401     private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1402             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1403             @NonNull int[] updatedUserIds) {
1404         String pkgName = pkg.packageName;
1405         boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1406                 >= Build.VERSION_CODES.M;
1407 
1408         int[] users = UserManagerService.getInstance().getUserIds();
1409         int numUsers = users.length;
1410         for (int i = 0; i < numUsers; i++) {
1411             int userId = users[i];
1412 
1413             for (String permission : ps.getPermissions(userId)) {
1414                 if (!pkg.implicitPermissions.contains(permission)) {
1415                     if (!ps.hasInstallPermission(permission)) {
1416                         int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1417 
1418                         if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1419                             BasePermission bp = mSettings.getPermissionLocked(permission);
1420 
1421                             int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
1422 
1423                             if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
1424                                     && supportsRuntimePermissions) {
1425                                 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1426                                 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
1427                                     if (DEBUG_PERMISSIONS) {
1428                                         Slog.i(TAG, "Revoking runtime permission "
1429                                                 + permission + " for " + pkgName
1430                                                 + " as it is now requested");
1431                                     }
1432                                 }
1433 
1434                                 flagsToRemove |= USER_PERMISSION_FLAGS;
1435                             }
1436 
1437                             ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
1438                             updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1439                         }
1440                     }
1441                 }
1442             }
1443         }
1444 
1445         return updatedUserIds;
1446     }
1447 
1448     /**
1449      * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1450      *
1451      * <p>A single new permission can be split off from several source permissions. In this case
1452      * the most leniant state is inherited.
1453      *
1454      * <p>Warning: This does not handle foreground / background permissions
1455      *
1456      * @param sourcePerms The permissions to inherit from
1457      * @param newPerm The permission to inherit to
1458      * @param ps The permission state of the package
1459      * @param pkg The package requesting the permissions
1460      * @param userId The user the permission belongs to
1461      */
inheritPermissionStateToNewImplicitPermissionLocked( @onNull ArraySet<String> sourcePerms, @NonNull String newPerm, @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @UserIdInt int userId)1462     private void inheritPermissionStateToNewImplicitPermissionLocked(
1463             @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1464             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1465             @UserIdInt int userId) {
1466         String pkgName = pkg.packageName;
1467         boolean isGranted = false;
1468         int flags = 0;
1469 
1470         int numSourcePerm = sourcePerms.size();
1471         for (int i = 0; i < numSourcePerm; i++) {
1472             String sourcePerm = sourcePerms.valueAt(i);
1473             if ((ps.hasRuntimePermission(sourcePerm, userId))
1474                     || ps.hasInstallPermission(sourcePerm)) {
1475                 if (!isGranted) {
1476                     flags = 0;
1477                 }
1478 
1479                 isGranted = true;
1480                 flags |= ps.getPermissionFlags(sourcePerm, userId);
1481             } else {
1482                 if (!isGranted) {
1483                     flags |= ps.getPermissionFlags(sourcePerm, userId);
1484                 }
1485             }
1486         }
1487 
1488         if (isGranted) {
1489             if (DEBUG_PERMISSIONS) {
1490                 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1491                         + " for " + pkgName);
1492             }
1493 
1494             ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1495         }
1496 
1497         // Add permission flags
1498         ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
1499     }
1500 
1501     /**
1502      * When the app has requested legacy storage we might need to update
1503      * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
1504      * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
1505      *
1506      * @param pkg The package for which the permissions are updated
1507      * @param replace If the app is being replaced
1508      * @param updatedUserIds The ids of the users that already changed.
1509      *
1510      * @return The ids of the users that are changed
1511      */
checkIfLegacyStorageOpsNeedToBeUpdated( @onNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds)1512     private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
1513             @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
1514         if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
1515                 pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
1516                         || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
1517             return UserManagerService.getInstance().getUserIds();
1518         }
1519 
1520         return updatedUserIds;
1521     }
1522 
1523     /**
1524      * Set the state of a implicit permission that is seen for the first time.
1525      *
1526      * @param origPs The permission state of the package before the split
1527      * @param ps The new permission state
1528      * @param pkg The package the permission belongs to
1529      * @param updatedUserIds List of users for which the permission state has already been changed
1530      *
1531      * @return  List of users for which the permission state has been changed
1532      */
setInitialGrantForNewImplicitPermissionsLocked( @onNull PermissionsState origPs, @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull ArraySet<String> newImplicitPermissions, @NonNull int[] updatedUserIds)1533     private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1534             @NonNull PermissionsState origPs,
1535             @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1536             @NonNull ArraySet<String> newImplicitPermissions,
1537             @NonNull int[] updatedUserIds) {
1538         String pkgName = pkg.packageName;
1539         ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1540 
1541         int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
1542         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1543             PermissionManager.SplitPermissionInfo spi =
1544                     PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
1545 
1546             List<String> newPerms = spi.getNewPermissions();
1547             int numNewPerms = newPerms.size();
1548             for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1549                 String newPerm = newPerms.get(newPermNum);
1550 
1551                 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1552                 if (splitPerms == null) {
1553                     splitPerms = new ArraySet<>();
1554                     newToSplitPerms.put(newPerm, splitPerms);
1555                 }
1556 
1557                 splitPerms.add(spi.getSplitPermission());
1558             }
1559         }
1560 
1561         int numNewImplicitPerms = newImplicitPermissions.size();
1562         for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1563                 newImplicitPermNum++) {
1564             String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1565             ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1566 
1567             if (sourcePerms != null) {
1568                 if (!ps.hasInstallPermission(newPerm)) {
1569                     BasePermission bp = mSettings.getPermissionLocked(newPerm);
1570 
1571                     int[] users = UserManagerService.getInstance().getUserIds();
1572                     int numUsers = users.length;
1573                     for (int userNum = 0; userNum < numUsers; userNum++) {
1574                         int userId = users[userNum];
1575 
1576                         if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
1577                             ps.updatePermissionFlags(bp, userId,
1578                                     FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1579                                     FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1580                         }
1581                         updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1582 
1583                         boolean inheritsFromInstallPerm = false;
1584                         for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1585                                 sourcePermNum++) {
1586                             if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1587                                 inheritsFromInstallPerm = true;
1588                                 break;
1589                             }
1590                         }
1591 
1592                         if (!origPs.hasRequestedPermission(sourcePerms)
1593                                 && !inheritsFromInstallPerm) {
1594                             // Both permissions are new so nothing to inherit.
1595                             if (DEBUG_PERMISSIONS) {
1596                                 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1597                                         + " for " + pkgName + " as split permission is also new");
1598                             }
1599 
1600                             break;
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 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)1614     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1615         boolean allowed = false;
1616         final int NP = PackageParser.NEW_PERMISSIONS.length;
1617         for (int ip=0; ip<NP; ip++) {
1618             final PackageParser.NewPermissionInfo npi
1619                     = PackageParser.NEW_PERMISSIONS[ip];
1620             if (npi.name.equals(perm)
1621                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1622                 allowed = true;
1623                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1624                         + pkg.packageName);
1625                 break;
1626             }
1627         }
1628         return allowed;
1629     }
1630 
1631     /**
1632      * Determines whether a package is whitelisted for a particular privapp permission.
1633      *
1634      * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1635      *
1636      * <p>This handles parent/child apps.
1637      */
hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg)1638     private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
1639         ArraySet<String> wlPermissions = null;
1640         if (pkg.isVendor()) {
1641             wlPermissions =
1642                     SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1643         } else if (pkg.isProduct()) {
1644             wlPermissions =
1645                     SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
1646         } else if (pkg.isProductServices()) {
1647             wlPermissions =
1648                     SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1649                             pkg.packageName);
1650         } else {
1651             wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1652         }
1653         // Let's check if this package is whitelisted...
1654         boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1655         // If it's not, we'll also tail-recurse to the parent.
1656         return whitelisted ||
1657                 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1658     }
1659 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)1660     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1661             BasePermission bp, PermissionsState origPermissions) {
1662         boolean oemPermission = bp.isOEM();
1663         boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1664         boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
1665         boolean privappPermissionsDisable =
1666                 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1667         boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1668         boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1669         if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1670                 && !platformPackage && platformPermission) {
1671             if (!hasPrivappWhitelistEntry(perm, pkg)) {
1672                 // Only report violations for apps on system image
1673                 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1674                     // it's only a reportable violation if the permission isn't explicitly denied
1675                     ArraySet<String> deniedPermissions = null;
1676                     if (pkg.isVendor()) {
1677                         deniedPermissions = SystemConfig.getInstance()
1678                                 .getVendorPrivAppDenyPermissions(pkg.packageName);
1679                     } else if (pkg.isProduct()) {
1680                         deniedPermissions = SystemConfig.getInstance()
1681                                 .getProductPrivAppDenyPermissions(pkg.packageName);
1682                     } else if (pkg.isProductServices()) {
1683                         deniedPermissions = SystemConfig.getInstance()
1684                                 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
1685                     } else {
1686                         deniedPermissions = SystemConfig.getInstance()
1687                                 .getPrivAppDenyPermissions(pkg.packageName);
1688                     }
1689                     final boolean permissionViolation =
1690                             deniedPermissions == null || !deniedPermissions.contains(perm);
1691                     if (permissionViolation) {
1692                         Slog.w(TAG, "Privileged permission " + perm + " for package "
1693                                 + pkg.packageName + " - not in privapp-permissions whitelist");
1694 
1695                         if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1696                             if (mPrivappPermissionsViolations == null) {
1697                                 mPrivappPermissionsViolations = new ArraySet<>();
1698                             }
1699                             mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
1700                         }
1701                     } else {
1702                         return false;
1703                     }
1704                 }
1705                 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1706                     return false;
1707                 }
1708             }
1709         }
1710         final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1711                 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1712         final PackageParser.Package systemPackage =
1713                 mPackageManagerInt.getPackage(systemPackageName);
1714 
1715         // check if the package is allow to use this signature permission.  A package is allowed to
1716         // use a signature permission if:
1717         //     - it has the same set of signing certificates as the source package
1718         //     - or its signing certificate was rotated from the source package's certificate
1719         //     - or its signing certificate is a previous signing certificate of the defining
1720         //       package, and the defining package still trusts the old certificate for permissions
1721         //     - or it shares the above relationships with the system package
1722         boolean allowed =
1723                 pkg.mSigningDetails.hasAncestorOrSelf(
1724                         bp.getSourcePackageSetting().getSigningDetails())
1725                 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1726                         pkg.mSigningDetails,
1727                         PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1728                 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1729                 || systemPackage.mSigningDetails.checkCapability(
1730                         pkg.mSigningDetails,
1731                         PackageParser.SigningDetails.CertCapabilities.PERMISSION);
1732         if (!allowed && (privilegedPermission || oemPermission)) {
1733             if (pkg.isSystem()) {
1734                 // For updated system applications, a privileged/oem permission
1735                 // is granted only if it had been defined by the original application.
1736                 if (pkg.isUpdatedSystemApp()) {
1737                     final PackageParser.Package disabledPkg =
1738                             mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
1739                     final PackageSetting disabledPs =
1740                             (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1741                     if (disabledPs != null
1742                             && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1743                         // If the original was granted this permission, we take
1744                         // that grant decision as read and propagate it to the
1745                         // update.
1746                         if ((privilegedPermission && disabledPs.isPrivileged())
1747                                 || (oemPermission && disabledPs.isOem()
1748                                         && canGrantOemPermission(disabledPs, perm))) {
1749                             allowed = true;
1750                         }
1751                     } else {
1752                         // The system apk may have been updated with an older
1753                         // version of the one on the data partition, but which
1754                         // granted a new system permission that it didn't have
1755                         // before.  In this case we do want to allow the app to
1756                         // now get the new permission if the ancestral apk is
1757                         // privileged to get it.
1758                         if (disabledPs != null && disabledPkg != null
1759                                 && isPackageRequestingPermission(disabledPkg, perm)
1760                                 && ((privilegedPermission && disabledPs.isPrivileged())
1761                                         || (oemPermission && disabledPs.isOem()
1762                                                 && canGrantOemPermission(disabledPs, perm)))) {
1763                             allowed = true;
1764                         }
1765                         // Also if a privileged parent package on the system image or any of
1766                         // its children requested a privileged/oem permission, the updated child
1767                         // packages can also get the permission.
1768                         if (pkg.parentPackage != null) {
1769                             final PackageParser.Package disabledParentPkg = mPackageManagerInt
1770                                     .getDisabledSystemPackage(pkg.parentPackage.packageName);
1771                             final PackageSetting disabledParentPs = (disabledParentPkg != null)
1772                                     ? (PackageSetting) disabledParentPkg.mExtras : null;
1773                             if (disabledParentPkg != null
1774                                     && ((privilegedPermission && disabledParentPs.isPrivileged())
1775                                             || (oemPermission && disabledParentPs.isOem()))) {
1776                                 if (isPackageRequestingPermission(disabledParentPkg, perm)
1777                                         && canGrantOemPermission(disabledParentPs, perm)) {
1778                                     allowed = true;
1779                                 } else if (disabledParentPkg.childPackages != null) {
1780                                     for (PackageParser.Package disabledChildPkg
1781                                             : disabledParentPkg.childPackages) {
1782                                         final PackageSetting disabledChildPs =
1783                                                 (disabledChildPkg != null)
1784                                                         ? (PackageSetting) disabledChildPkg.mExtras
1785                                                         : null;
1786                                         if (isPackageRequestingPermission(disabledChildPkg, perm)
1787                                                 && canGrantOemPermission(
1788                                                         disabledChildPs, perm)) {
1789                                             allowed = true;
1790                                             break;
1791                                         }
1792                                     }
1793                                 }
1794                             }
1795                         }
1796                     }
1797                 } else {
1798                     final PackageSetting ps = (PackageSetting) pkg.mExtras;
1799                     allowed = (privilegedPermission && pkg.isPrivileged())
1800                             || (oemPermission && pkg.isOem()
1801                                     && canGrantOemPermission(ps, perm));
1802                 }
1803                 // In any case, don't grant a privileged permission to privileged vendor apps, if
1804                 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1805                 // flag.
1806                 if (allowed && privilegedPermission &&
1807                         !vendorPrivilegedPermission && pkg.isVendor()) {
1808                    Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1809                            + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1810                    allowed = false;
1811                 }
1812             }
1813         }
1814         if (!allowed) {
1815             if (!allowed
1816                     && bp.isPre23()
1817                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1818                 // If this was a previously normal/dangerous permission that got moved
1819                 // to a system permission as part of the runtime permission redesign, then
1820                 // we still want to blindly grant it to old apps.
1821                 allowed = true;
1822             }
1823             // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1824             //                  need a separate flag anymore. Hence we need to check which
1825             //                  permissions are needed by the permission controller
1826             if (!allowed && bp.isInstaller()
1827                     && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1828                             PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1829                     || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1830                             PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1831                             UserHandle.USER_SYSTEM)))) {
1832                 // If this permission is to be granted to the system installer and
1833                 // this app is an installer, then it gets the permission.
1834                 allowed = true;
1835             }
1836             if (!allowed && bp.isVerifier()
1837                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1838                             PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1839                 // If this permission is to be granted to the system verifier and
1840                 // this app is a verifier, then it gets the permission.
1841                 allowed = true;
1842             }
1843             if (!allowed && bp.isPreInstalled()
1844                     && pkg.isSystem()) {
1845                 // Any pre-installed system app is allowed to get this permission.
1846                 allowed = true;
1847             }
1848             if (!allowed && bp.isDevelopment()) {
1849                 // For development permissions, a development permission
1850                 // is granted only if it was already granted.
1851                 allowed = origPermissions.hasInstallPermission(perm);
1852             }
1853             if (!allowed && bp.isSetup()
1854                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1855                             PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1856                 // If this permission is to be granted to the system setup wizard and
1857                 // this app is a setup wizard, then it gets the permission.
1858                 allowed = true;
1859             }
1860             if (!allowed && bp.isSystemTextClassifier()
1861                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1862                             PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1863                             UserHandle.USER_SYSTEM))) {
1864                 // Special permissions for the system default text classifier.
1865                 allowed = true;
1866             }
1867             if (!allowed && bp.isConfigurator()
1868                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1869                     PackageManagerInternal.PACKAGE_CONFIGURATOR,
1870                     UserHandle.USER_SYSTEM))) {
1871                 // Special permissions for the device configurator.
1872                 allowed = true;
1873             }
1874             if (!allowed && bp.isWellbeing()
1875                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1876                     PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
1877                 // Special permission granted only to the OEM specified wellbeing app
1878                 allowed = true;
1879             }
1880             if (!allowed && bp.isDocumenter()
1881                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1882                             PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
1883                 // If this permission is to be granted to the documenter and
1884                 // this app is the documenter, then it gets the permission.
1885                 allowed = true;
1886             }
1887             if (!allowed && bp.isIncidentReportApprover()
1888                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1889                             PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
1890                             UserHandle.USER_SYSTEM))) {
1891                 // If this permission is to be granted to the incident report approver and
1892                 // this app is the incident report approver, then it gets the permission.
1893                 allowed = true;
1894             }
1895             if (!allowed && bp.isAppPredictor()
1896                     && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1897                         PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
1898                 // Special permissions for the system app predictor.
1899                 allowed = true;
1900             }
1901         }
1902         return allowed;
1903     }
1904 
canGrantOemPermission(PackageSetting ps, String permission)1905     private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1906         if (!ps.isOem()) {
1907             return false;
1908         }
1909         // all oem permissions must explicitly be granted or denied
1910         final Boolean granted =
1911                 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1912         if (granted == null) {
1913             throw new IllegalStateException("OEM permission" + permission + " requested by package "
1914                     + ps.name + " must be explicitly declared granted or not");
1915         }
1916         return Boolean.TRUE == granted;
1917     }
1918 
isPermissionsReviewRequired(@onNull PackageParser.Package pkg, @UserIdInt int userId)1919     private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
1920             @UserIdInt int userId) {
1921         // Permission review applies only to apps not supporting the new permission model.
1922         if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1923             return false;
1924         }
1925 
1926         // Legacy apps have the permission and get user consent on launch.
1927         if (pkg.mExtras == null) {
1928             return false;
1929         }
1930         final PackageSetting ps = (PackageSetting) pkg.mExtras;
1931         final PermissionsState permissionsState = ps.getPermissionsState();
1932         return permissionsState.isPermissionReviewRequired(userId);
1933     }
1934 
isPackageRequestingPermission(PackageParser.Package pkg, String permission)1935     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1936         final int permCount = pkg.requestedPermissions.size();
1937         for (int j = 0; j < permCount; j++) {
1938             String requestedPermission = pkg.requestedPermissions.get(j);
1939             if (permission.equals(requestedPermission)) {
1940                 return true;
1941             }
1942         }
1943         return false;
1944     }
1945 
1946     @GuardedBy("mLock")
grantRuntimePermissionsGrantedToDisabledPackageLocked( PackageParser.Package pkg, int callingUid, PermissionCallback callback)1947     private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1948             PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1949         if (pkg.parentPackage == null) {
1950             return;
1951         }
1952         if (pkg.requestedPermissions == null) {
1953             return;
1954         }
1955         final PackageParser.Package disabledPkg =
1956                 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
1957         if (disabledPkg == null || disabledPkg.mExtras == null) {
1958             return;
1959         }
1960         final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1961         if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1962             return;
1963         }
1964         final int permCount = pkg.requestedPermissions.size();
1965         for (int i = 0; i < permCount; i++) {
1966             String permission = pkg.requestedPermissions.get(i);
1967             BasePermission bp = mSettings.getPermissionLocked(permission);
1968             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1969                 continue;
1970             }
1971             for (int userId : mUserManagerInt.getUserIds()) {
1972                 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1973                     grantRuntimePermission(
1974                             permission, pkg.packageName, false, callingUid, userId, callback);
1975                 }
1976             }
1977         }
1978     }
1979 
grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions, int callingUid, PermissionCallback callback)1980     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1981             String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1982         for (int userId : userIds) {
1983             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1984                     callback);
1985         }
1986     }
1987 
getWhitelistedRestrictedPermissions( @onNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags, @UserIdInt int userId)1988     private @Nullable List<String> getWhitelistedRestrictedPermissions(
1989             @NonNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags,
1990             @UserIdInt int userId) {
1991         final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
1992         if (packageSetting == null) {
1993             return null;
1994         }
1995 
1996         final PermissionsState permissionsState = packageSetting.getPermissionsState();
1997 
1998         int queryFlags = 0;
1999         if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
2000             queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2001         }
2002         if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
2003             queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2004         }
2005         if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
2006             queryFlags |=  PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2007         }
2008 
2009         ArrayList<String> whitelistedPermissions = null;
2010 
2011         final int permissionCount = pkg.requestedPermissions.size();
2012         for (int i = 0; i < permissionCount; i++) {
2013             final String permissionName = pkg.requestedPermissions.get(i);
2014             final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId);
2015             if ((currentFlags & queryFlags) != 0) {
2016                 if (whitelistedPermissions == null) {
2017                     whitelistedPermissions = new ArrayList<>();
2018                 }
2019                 whitelistedPermissions.add(permissionName);
2020             }
2021         }
2022 
2023         return whitelistedPermissions;
2024     }
2025 
setWhitelistedRestrictedPermissions(@onNull PackageParser.Package pkg, @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, @PackageManager.PermissionWhitelistFlags int whitelistFlags, @NonNull PermissionCallback callback)2026     private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
2027             @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
2028             @PackageManager.PermissionWhitelistFlags int whitelistFlags,
2029             @NonNull PermissionCallback callback) {
2030         for (int userId : userIds) {
2031             setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
2032                     callingUid, whitelistFlags, callback);
2033         }
2034     }
2035 
grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions, int callingUid, PermissionCallback callback)2036     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2037             String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2038         PackageSetting ps = (PackageSetting) pkg.mExtras;
2039         if (ps == null) {
2040             return;
2041         }
2042 
2043         PermissionsState permissionsState = ps.getPermissionsState();
2044 
2045         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2046                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2047 
2048         final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2049                 >= Build.VERSION_CODES.M;
2050 
2051         final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
2052 
2053         for (String permission : pkg.requestedPermissions) {
2054             final BasePermission bp;
2055             synchronized (mLock) {
2056                 bp = mSettings.getPermissionLocked(permission);
2057             }
2058             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2059                     && (!instantApp || bp.isInstant())
2060                     && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2061                     && (grantedPermissions == null
2062                            || ArrayUtils.contains(grantedPermissions, permission))) {
2063                 final int flags = permissionsState.getPermissionFlags(permission, userId);
2064                 if (supportsRuntimePermissions) {
2065                     // Installer cannot change immutable permissions.
2066                     if ((flags & immutableFlags) == 0) {
2067                         grantRuntimePermission(permission, pkg.packageName, false, callingUid,
2068                                 userId, callback);
2069                     }
2070                 } else {
2071                     // In permission review mode we clear the review flag when we
2072                     // are asked to install the app with all permissions granted.
2073                     if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2074                         updatePermissionFlags(permission, pkg.packageName,
2075                                 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
2076                                 userId, false, callback);
2077                     }
2078                 }
2079             }
2080         }
2081     }
2082 
grantRuntimePermission(String permName, String packageName, boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback)2083     private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
2084             int callingUid, final int userId, PermissionCallback callback) {
2085         if (!mUserManagerInt.exists(userId)) {
2086             Log.e(TAG, "No such user:" + userId);
2087             return;
2088         }
2089 
2090         mContext.enforceCallingOrSelfPermission(
2091                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
2092                 "grantRuntimePermission");
2093 
2094         enforceCrossUserPermission(callingUid, userId,
2095                 true,  // requireFullPermission
2096                 true,  // checkShell
2097                 false, // requirePermissionWhenSameUser
2098                 "grantRuntimePermission");
2099 
2100         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2101         if (pkg == null || pkg.mExtras == null) {
2102             throw new IllegalArgumentException("Unknown package: " + packageName);
2103         }
2104         final BasePermission bp;
2105         synchronized(mLock) {
2106             bp = mSettings.getPermissionLocked(permName);
2107         }
2108         if (bp == null) {
2109             throw new IllegalArgumentException("Unknown permission: " + permName);
2110         }
2111         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2112             throw new IllegalArgumentException("Unknown package: " + packageName);
2113         }
2114 
2115         bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2116 
2117         // If a permission review is required for legacy apps we represent
2118         // their permissions as always granted runtime ones since we need
2119         // to keep the review required permission flag per user while an
2120         // install permission's state is shared across all users.
2121         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2122                 && bp.isRuntime()) {
2123             return;
2124         }
2125 
2126         final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2127 
2128         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2129         final PermissionsState permissionsState = ps.getPermissionsState();
2130 
2131         final int flags = permissionsState.getPermissionFlags(permName, userId);
2132         if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
2133             Log.e(TAG, "Cannot grant system fixed permission "
2134                     + permName + " for package " + packageName);
2135             return;
2136         }
2137         if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2138             Log.e(TAG, "Cannot grant policy fixed permission "
2139                     + permName + " for package " + packageName);
2140             return;
2141         }
2142 
2143         if (bp.isHardRestricted()
2144                 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
2145             Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
2146                     + permName + " for package " + packageName);
2147             return;
2148         }
2149 
2150         if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
2151                 pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
2152             Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
2153                     + packageName);
2154             return;
2155         }
2156 
2157         if (bp.isDevelopment()) {
2158             // Development permissions must be handled specially, since they are not
2159             // normal runtime permissions.  For now they apply to all users.
2160             if (permissionsState.grantInstallPermission(bp) !=
2161                     PERMISSION_OPERATION_FAILURE) {
2162                 if (callback != null) {
2163                     callback.onInstallPermissionGranted();
2164                 }
2165             }
2166             return;
2167         }
2168 
2169         if (ps.getInstantApp(userId) && !bp.isInstant()) {
2170             throw new SecurityException("Cannot grant non-ephemeral permission"
2171                     + permName + " for package " + packageName);
2172         }
2173 
2174         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2175             Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2176             return;
2177         }
2178 
2179         final int result = permissionsState.grantRuntimePermission(bp, userId);
2180         switch (result) {
2181             case PERMISSION_OPERATION_FAILURE: {
2182                 return;
2183             }
2184 
2185             case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2186                 if (callback != null) {
2187                     callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2188                 }
2189             }
2190             break;
2191         }
2192 
2193         if (bp.isRuntime()) {
2194             logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
2195         }
2196 
2197         if (callback != null) {
2198             callback.onPermissionGranted(uid, userId);
2199         }
2200 
2201         if (bp.isRuntime()) {
2202             notifyRuntimePermissionStateChanged(packageName, userId);
2203         }
2204 
2205         // Only need to do this if user is initialized. Otherwise it's a new user
2206         // and there are no processes running as the user yet and there's no need
2207         // to make an expensive call to remount processes for the changed permissions.
2208         if (READ_EXTERNAL_STORAGE.equals(permName)
2209                 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2210             final long token = Binder.clearCallingIdentity();
2211             try {
2212                 if (mUserManagerInt.isUserInitialized(userId)) {
2213                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
2214                             StorageManagerInternal.class);
2215                     storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2216                 }
2217             } finally {
2218                 Binder.restoreCallingIdentity(token);
2219             }
2220         }
2221 
2222     }
2223 
revokeRuntimePermission(String permName, String packageName, boolean overridePolicy, int userId, PermissionCallback callback)2224     private void revokeRuntimePermission(String permName, String packageName,
2225             boolean overridePolicy, int userId, PermissionCallback callback) {
2226         if (!mUserManagerInt.exists(userId)) {
2227             Log.e(TAG, "No such user:" + userId);
2228             return;
2229         }
2230 
2231         mContext.enforceCallingOrSelfPermission(
2232                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2233                 "revokeRuntimePermission");
2234 
2235         enforceCrossUserPermission(Binder.getCallingUid(), userId,
2236                 true,  // requireFullPermission
2237                 true,  // checkShell
2238                 false, // requirePermissionWhenSameUser
2239                 "revokeRuntimePermission");
2240 
2241         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2242         if (pkg == null || pkg.mExtras == null) {
2243             throw new IllegalArgumentException("Unknown package: " + packageName);
2244         }
2245         if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2246             throw new IllegalArgumentException("Unknown package: " + packageName);
2247         }
2248         final BasePermission bp = mSettings.getPermissionLocked(permName);
2249         if (bp == null) {
2250             throw new IllegalArgumentException("Unknown permission: " + permName);
2251         }
2252 
2253         bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2254 
2255         // If a permission review is required for legacy apps we represent
2256         // their permissions as always granted runtime ones since we need
2257         // to keep the review required permission flag per user while an
2258         // install permission's state is shared across all users.
2259         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2260                 && bp.isRuntime()) {
2261             return;
2262         }
2263 
2264         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2265         final PermissionsState permissionsState = ps.getPermissionsState();
2266 
2267         final int flags = permissionsState.getPermissionFlags(permName, userId);
2268         // Only the system may revoke SYSTEM_FIXED permissions.
2269         if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2270                 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2271             throw new SecurityException("Non-System UID cannot revoke system fixed permission "
2272                     + permName + " for package " + packageName);
2273         }
2274         if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2275             throw new SecurityException("Cannot revoke policy fixed permission "
2276                     + permName + " for package " + packageName);
2277         }
2278 
2279         if (bp.isDevelopment()) {
2280             // Development permissions must be handled specially, since they are not
2281             // normal runtime permissions.  For now they apply to all users.
2282             if (permissionsState.revokeInstallPermission(bp) !=
2283                     PERMISSION_OPERATION_FAILURE) {
2284                 if (callback != null) {
2285                     callback.onInstallPermissionRevoked();
2286                 }
2287             }
2288             return;
2289         }
2290 
2291         // Permission is already revoked, no need to do anything.
2292         if (!permissionsState.hasRuntimePermission(permName, userId)) {
2293             return;
2294         }
2295 
2296         if (permissionsState.revokeRuntimePermission(bp, userId) ==
2297                 PERMISSION_OPERATION_FAILURE) {
2298             return;
2299         }
2300 
2301         if (bp.isRuntime()) {
2302             logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
2303         }
2304 
2305         if (callback != null) {
2306             callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2307         }
2308 
2309         if (bp.isRuntime()) {
2310             notifyRuntimePermissionStateChanged(packageName, userId);
2311         }
2312     }
2313 
setWhitelistedRestrictedPermissionsForUser(@onNull PackageParser.Package pkg, @UserIdInt int userId, @Nullable List<String> permissions, int callingUid, @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback)2314     private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
2315             @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
2316             @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
2317         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2318         if (ps == null) {
2319             return;
2320         }
2321 
2322         final PermissionsState permissionsState = ps.getPermissionsState();
2323 
2324         ArraySet<String> oldGrantedRestrictedPermissions = null;
2325         boolean updatePermissions = false;
2326 
2327         final int permissionCount = pkg.requestedPermissions.size();
2328         for (int i = 0; i < permissionCount; i++) {
2329             final String permissionName = pkg.requestedPermissions.get(i);
2330 
2331             final BasePermission bp = mSettings.getPermissionLocked(permissionName);
2332             if (bp == null) {
2333                 Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
2334                 continue;
2335             }
2336 
2337             if (!bp.isHardOrSoftRestricted()) {
2338                 continue;
2339             }
2340 
2341             if (permissionsState.hasPermission(permissionName, userId)) {
2342                 if (oldGrantedRestrictedPermissions == null) {
2343                     oldGrantedRestrictedPermissions = new ArraySet<>();
2344                 }
2345                 oldGrantedRestrictedPermissions.add(permissionName);
2346             }
2347 
2348             final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
2349 
2350             int newFlags = oldFlags;
2351             int mask = 0;
2352             int whitelistFlagsCopy = whitelistFlags;
2353             while (whitelistFlagsCopy != 0) {
2354                 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
2355                 whitelistFlagsCopy &= ~flag;
2356                 switch (flag) {
2357                     case FLAG_PERMISSION_WHITELIST_SYSTEM: {
2358                         mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2359                         if (permissions != null && permissions.contains(permissionName)) {
2360                             newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2361                         } else {
2362                             newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2363                         }
2364                     } break;
2365                     case FLAG_PERMISSION_WHITELIST_UPGRADE: {
2366                         mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2367                         if (permissions != null && permissions.contains(permissionName)) {
2368                             newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2369                         } else {
2370                             newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2371                         }
2372                     } break;
2373                     case FLAG_PERMISSION_WHITELIST_INSTALLER: {
2374                         mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2375                         if (permissions != null && permissions.contains(permissionName)) {
2376                             newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2377                         } else {
2378                             newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2379                         }
2380                     } break;
2381                 }
2382             }
2383 
2384             if (oldFlags == newFlags) {
2385                 continue;
2386             }
2387 
2388             updatePermissions = true;
2389 
2390             final boolean wasWhitelisted = (oldFlags
2391                     & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2392             final boolean isWhitelisted = (newFlags
2393                     & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2394 
2395             // If the permission is policy fixed as granted but it is no longer
2396             // on any of the whitelists we need to clear the policy fixed flag
2397             // as whitelisting trumps policy i.e. policy cannot grant a non
2398             // grantable permission.
2399             if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2400                 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
2401                 if (!isWhitelisted && isGranted) {
2402                     mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2403                     newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2404                 }
2405             }
2406 
2407             // If we are whitelisting an app that does not support runtime permissions
2408             // we need to make sure it goes through the permission review UI at launch.
2409             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2410                     && !wasWhitelisted && isWhitelisted) {
2411                 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2412                 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2413             }
2414 
2415             updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
2416                     callingUid, userId, false, null /*callback*/);
2417         }
2418 
2419         if (updatePermissions) {
2420             // Update permission of this app to take into account the new whitelist state.
2421             restorePermissionState(pkg, false, pkg.packageName, callback);
2422 
2423             // If this resulted in losing a permission we need to kill the app.
2424             if (oldGrantedRestrictedPermissions != null) {
2425                 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
2426                 for (int i = 0; i < oldGrantedCount; i++) {
2427                     final String permission = oldGrantedRestrictedPermissions.valueAt(i);
2428                     // Sometimes we create a new permission state instance during update.
2429                     if (!ps.getPermissionsState().hasPermission(permission, userId)) {
2430                         callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2431                         break;
2432                     }
2433                 }
2434             }
2435         }
2436     }
2437 
2438     @GuardedBy("mLock")
revokeUnusedSharedUserPermissionsLocked( SharedUserSetting suSetting, int[] allUserIds)2439     private int[] revokeUnusedSharedUserPermissionsLocked(
2440             SharedUserSetting suSetting, int[] allUserIds) {
2441         // Collect all used permissions in the UID
2442         final ArraySet<String> usedPermissions = new ArraySet<>();
2443         final List<PackageParser.Package> pkgList = suSetting.getPackages();
2444         if (pkgList == null || pkgList.size() == 0) {
2445             return EmptyArray.INT;
2446         }
2447         for (PackageParser.Package pkg : pkgList) {
2448             if (pkg.requestedPermissions == null) {
2449                 continue;
2450             }
2451             final int requestedPermCount = pkg.requestedPermissions.size();
2452             for (int j = 0; j < requestedPermCount; j++) {
2453                 String permission = pkg.requestedPermissions.get(j);
2454                 BasePermission bp = mSettings.getPermissionLocked(permission);
2455                 if (bp != null) {
2456                     usedPermissions.add(permission);
2457                 }
2458             }
2459         }
2460 
2461         PermissionsState permissionsState = suSetting.getPermissionsState();
2462         // Prune install permissions
2463         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2464         final int installPermCount = installPermStates.size();
2465         for (int i = installPermCount - 1; i >= 0;  i--) {
2466             PermissionState permissionState = installPermStates.get(i);
2467             if (!usedPermissions.contains(permissionState.getName())) {
2468                 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2469                 if (bp != null) {
2470                     permissionsState.revokeInstallPermission(bp);
2471                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2472                             MASK_PERMISSION_FLAGS_ALL, 0);
2473                 }
2474             }
2475         }
2476 
2477         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2478 
2479         // Prune runtime permissions
2480         for (int userId : allUserIds) {
2481             List<PermissionState> runtimePermStates = permissionsState
2482                     .getRuntimePermissionStates(userId);
2483             final int runtimePermCount = runtimePermStates.size();
2484             for (int i = runtimePermCount - 1; i >= 0; i--) {
2485                 PermissionState permissionState = runtimePermStates.get(i);
2486                 if (!usedPermissions.contains(permissionState.getName())) {
2487                     BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2488                     if (bp != null) {
2489                         permissionsState.revokeRuntimePermission(bp, userId);
2490                         permissionsState.updatePermissionFlags(bp, userId,
2491                                 MASK_PERMISSION_FLAGS_ALL, 0);
2492                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2493                                 runtimePermissionChangedUserIds, userId);
2494                     }
2495                 }
2496             }
2497         }
2498 
2499         return runtimePermissionChangedUserIds;
2500     }
2501 
getAppOpPermissionPackages(String permName)2502     private String[] getAppOpPermissionPackages(String permName) {
2503         if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2504             return null;
2505         }
2506         synchronized (mLock) {
2507             final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2508             if (pkgs == null) {
2509                 return null;
2510             }
2511             return pkgs.toArray(new String[pkgs.size()]);
2512         }
2513     }
2514 
getPermissionFlags( String permName, String packageName, int callingUid, int userId)2515     private int getPermissionFlags(
2516             String permName, String packageName, int callingUid, int userId) {
2517         if (!mUserManagerInt.exists(userId)) {
2518             return 0;
2519         }
2520 
2521         enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
2522 
2523         enforceCrossUserPermission(callingUid, userId,
2524                 true,  // requireFullPermission
2525                 false, // checkShell
2526                 false, // requirePermissionWhenSameUser
2527                 "getPermissionFlags");
2528 
2529         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2530         if (pkg == null || pkg.mExtras == null) {
2531             return 0;
2532         }
2533         synchronized (mLock) {
2534             if (mSettings.getPermissionLocked(permName) == null) {
2535                 return 0;
2536             }
2537         }
2538         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2539             return 0;
2540         }
2541         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2542         PermissionsState permissionsState = ps.getPermissionsState();
2543         return permissionsState.getPermissionFlags(permName, userId);
2544     }
2545 
2546     private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2547     private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2548     private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2549 
updatePermissions(String packageName, PackageParser.Package pkg, boolean replaceGrant, Collection<PackageParser.Package> allPackages, PermissionCallback callback)2550     private void updatePermissions(String packageName, PackageParser.Package pkg,
2551             boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2552             PermissionCallback callback) {
2553         final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2554                 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2555         updatePermissions(
2556                 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2557         if (pkg != null && pkg.childPackages != null) {
2558             for (PackageParser.Package childPkg : pkg.childPackages) {
2559                 updatePermissions(childPkg.packageName, childPkg,
2560                         getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2561             }
2562         }
2563     }
2564 
updateAllPermissions(String volumeUuid, boolean sdkUpdated, Collection<PackageParser.Package> allPackages, PermissionCallback callback)2565     private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2566             Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2567         final int flags = UPDATE_PERMISSIONS_ALL |
2568                 (sdkUpdated
2569                         ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2570                         : 0);
2571         updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2572     }
2573 
updatePermissions(String changingPkgName, PackageParser.Package changingPkg, String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages, PermissionCallback callback)2574     private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2575             String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2576             PermissionCallback callback) {
2577         // TODO: Most of the methods exposing BasePermission internals [source package name,
2578         // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2579         // have package settings, we should make note of it elsewhere [map between
2580         // source package name and BasePermission] and cycle through that here. Then we
2581         // define a single method on BasePermission that takes a PackageSetting, changing
2582         // package name and a package.
2583         // NOTE: With this approach, we also don't need to tree trees differently than
2584         // normal permissions. Today, we need two separate loops because these BasePermission
2585         // objects are stored separately.
2586         // Make sure there are no dangling permission trees.
2587         flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2588 
2589         // Make sure all dynamic permissions have been assigned to a package,
2590         // and make sure there are no dangling permissions.
2591         flags = updatePermissions(changingPkgName, changingPkg, flags, callback);
2592 
2593         synchronized (mLock) {
2594             if (mBackgroundPermissions == null) {
2595                 // Cache background -> foreground permission mapping.
2596                 // Only system declares background permissions, hence mapping does never change.
2597                 mBackgroundPermissions = new ArrayMap<>();
2598                 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
2599                     if (bp.perm != null && bp.perm.info != null
2600                             && bp.perm.info.backgroundPermission != null) {
2601                         String fgPerm = bp.name;
2602                         String bgPerm = bp.perm.info.backgroundPermission;
2603 
2604                         List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2605                         if (fgPerms == null) {
2606                             fgPerms = new ArrayList<>();
2607                             mBackgroundPermissions.put(bgPerm, fgPerms);
2608                         }
2609 
2610                         fgPerms.add(fgPerm);
2611                     }
2612                 }
2613             }
2614         }
2615 
2616         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
2617         // Now update the permissions for all packages, in particular
2618         // replace the granted permissions of the system packages.
2619         if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2620             for (PackageParser.Package pkg : allPackages) {
2621                 if (pkg != changingPkg) {
2622                     // Only replace for packages on requested volume
2623                     final String volumeUuid = getVolumeUuidForPackage(pkg);
2624                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2625                             && Objects.equals(replaceVolumeUuid, volumeUuid);
2626                     restorePermissionState(pkg, replace, changingPkgName, callback);
2627                 }
2628             }
2629         }
2630 
2631         if (changingPkg != null) {
2632             // Only replace for packages on requested volume
2633             final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2634             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2635                     && Objects.equals(replaceVolumeUuid, volumeUuid);
2636             restorePermissionState(changingPkg, replace, changingPkgName, callback);
2637         }
2638         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2639     }
2640 
updatePermissions(String packageName, PackageParser.Package pkg, int flags, @Nullable PermissionCallback callback)2641     private int updatePermissions(String packageName, PackageParser.Package pkg, int flags,
2642             @Nullable PermissionCallback callback) {
2643         Set<BasePermission> needsUpdate = null;
2644         synchronized (mLock) {
2645             final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2646             while (it.hasNext()) {
2647                 final BasePermission bp = it.next();
2648                 if (bp.isDynamic()) {
2649                     bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2650                 }
2651                 if (bp.getSourcePackageSetting() != null) {
2652                     if (packageName != null && packageName.equals(bp.getSourcePackageName())
2653                         && (pkg == null || !hasPermission(pkg, bp.getName()))) {
2654                         Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2655                                 + " from package " + bp.getSourcePackageName());
2656                         if (bp.isRuntime()) {
2657                             final int[] userIds = mUserManagerInt.getUserIds();
2658                             final int numUserIds = userIds.length;
2659                             for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2660                                 final int userId = userIds[userIdNum];
2661 
2662                                 mPackageManagerInt.forEachPackage((Package p) -> {
2663                                     final String pName = p.packageName;
2664                                     final ApplicationInfo appInfo =
2665                                             mPackageManagerInt.getApplicationInfo(pName, 0,
2666                                                     Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
2667                                     if (appInfo != null
2668                                             && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2669                                         return;
2670                                     }
2671 
2672                                     final String permissionName = bp.getName();
2673                                     if (checkPermission(permissionName, pName, Process.SYSTEM_UID,
2674                                             userId) == PackageManager.PERMISSION_GRANTED) {
2675                                         try {
2676                                             revokeRuntimePermission(
2677                                                     permissionName,
2678                                                     pName,
2679                                                     false,
2680                                                     userId,
2681                                                     callback);
2682                                         } catch (IllegalArgumentException e) {
2683                                             Slog.e(TAG,
2684                                                     "Failed to revoke "
2685                                                             + permissionName
2686                                                             + " from "
2687                                                             + pName,
2688                                                     e);
2689                                         }
2690                                     }
2691                                 });
2692                             }
2693                         }
2694                         flags |= UPDATE_PERMISSIONS_ALL;
2695                         it.remove();
2696                     }
2697                     continue;
2698                 }
2699                 if (needsUpdate == null) {
2700                     needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2701                 }
2702                 needsUpdate.add(bp);
2703             }
2704         }
2705         if (needsUpdate != null) {
2706             for (final BasePermission bp : needsUpdate) {
2707                 final PackageParser.Package sourcePkg =
2708                         mPackageManagerInt.getPackage(bp.getSourcePackageName());
2709                 synchronized (mLock) {
2710                     if (sourcePkg != null && sourcePkg.mExtras != null) {
2711                         final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
2712                         if (bp.getSourcePackageSetting() == null) {
2713                             bp.setSourcePackageSetting(sourcePs);
2714                         }
2715                         continue;
2716                     }
2717                     Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2718                             + " from package " + bp.getSourcePackageName());
2719                     mSettings.removePermissionLocked(bp.getName());
2720                 }
2721             }
2722         }
2723         return flags;
2724     }
2725 
updatePermissionTrees(String packageName, PackageParser.Package pkg, int flags)2726     private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
2727             int flags) {
2728         Set<BasePermission> needsUpdate = null;
2729         synchronized (mLock) {
2730             final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2731             while (it.hasNext()) {
2732                 final BasePermission bp = it.next();
2733                 if (bp.getSourcePackageSetting() != null) {
2734                     if (packageName != null && packageName.equals(bp.getSourcePackageName())
2735                         && (pkg == null || !hasPermission(pkg, bp.getName()))) {
2736                         Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2737                                 + " from package " + bp.getSourcePackageName());
2738                         flags |= UPDATE_PERMISSIONS_ALL;
2739                         it.remove();
2740                     }
2741                     continue;
2742                 }
2743                 if (needsUpdate == null) {
2744                     needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2745                 }
2746                 needsUpdate.add(bp);
2747             }
2748         }
2749         if (needsUpdate != null) {
2750             for (final BasePermission bp : needsUpdate) {
2751                 final PackageParser.Package sourcePkg =
2752                         mPackageManagerInt.getPackage(bp.getSourcePackageName());
2753                 synchronized (mLock) {
2754                     if (sourcePkg != null && sourcePkg.mExtras != null) {
2755                         final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
2756                         if (bp.getSourcePackageSetting() == null) {
2757                             bp.setSourcePackageSetting(sourcePs);
2758                         }
2759                         continue;
2760                     }
2761                     Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2762                             + " from package " + bp.getSourcePackageName());
2763                     mSettings.removePermissionLocked(bp.getName());
2764                 }
2765             }
2766         }
2767         return flags;
2768     }
2769 
updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, int callingUid, int userId, boolean overridePolicy, PermissionCallback callback)2770     private void updatePermissionFlags(String permName, String packageName, int flagMask,
2771             int flagValues, int callingUid, int userId, boolean overridePolicy,
2772             PermissionCallback callback) {
2773         if (!mUserManagerInt.exists(userId)) {
2774             return;
2775         }
2776 
2777         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2778 
2779         enforceCrossUserPermission(callingUid, userId,
2780                 true,  // requireFullPermission
2781                 true,  // checkShell
2782                 false, // requirePermissionWhenSameUser
2783                 "updatePermissionFlags");
2784 
2785         if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2786             throw new SecurityException("updatePermissionFlags requires "
2787                     + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2788         }
2789 
2790         // Only the system can change these flags and nothing else.
2791         if (callingUid != Process.SYSTEM_UID) {
2792             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2793             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2794             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2795             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2796             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2797             flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2798             flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2799             flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2800             flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
2801         }
2802 
2803         final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2804         if (pkg == null || pkg.mExtras == null) {
2805             Log.e(TAG, "Unknown package: " + packageName);
2806             return;
2807         }
2808         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2809             throw new IllegalArgumentException("Unknown package: " + packageName);
2810         }
2811 
2812         final BasePermission bp;
2813         synchronized (mLock) {
2814             bp = mSettings.getPermissionLocked(permName);
2815         }
2816         if (bp == null) {
2817             throw new IllegalArgumentException("Unknown permission: " + permName);
2818         }
2819 
2820         final PackageSetting ps = (PackageSetting) pkg.mExtras;
2821         final PermissionsState permissionsState = ps.getPermissionsState();
2822         final boolean hadState =
2823                 permissionsState.getRuntimePermissionState(permName, userId) != null;
2824         final boolean permissionUpdated =
2825                 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
2826         if (permissionUpdated && bp.isRuntime()) {
2827             notifyRuntimePermissionStateChanged(packageName, userId);
2828         }
2829         if (permissionUpdated && callback != null) {
2830             // Install and runtime permissions are stored in different places,
2831             // so figure out what permission changed and persist the change.
2832             if (permissionsState.getInstallPermissionState(permName) != null) {
2833                 callback.onInstallPermissionUpdated();
2834             } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2835                     || hadState) {
2836                 callback.onPermissionUpdated(new int[] { userId }, false);
2837             }
2838         }
2839     }
2840 
updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid, int userId, Collection<Package> packages, PermissionCallback callback)2841     private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2842             int userId, Collection<Package> packages, PermissionCallback callback) {
2843         if (!mUserManagerInt.exists(userId)) {
2844             return false;
2845         }
2846 
2847         enforceGrantRevokeRuntimePermissionPermissions(
2848                 "updatePermissionFlagsForAllApps");
2849         enforceCrossUserPermission(callingUid, userId,
2850                 true,  // requireFullPermission
2851                 true,  // checkShell
2852                 false, // requirePermissionWhenSameUser
2853                 "updatePermissionFlagsForAllApps");
2854 
2855         // Only the system can change system fixed flags.
2856         if (callingUid != Process.SYSTEM_UID) {
2857             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2858             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2859         }
2860 
2861         boolean changed = false;
2862         for (PackageParser.Package pkg : packages) {
2863             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2864             if (ps == null) {
2865                 continue;
2866             }
2867             PermissionsState permissionsState = ps.getPermissionsState();
2868             changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2869                     userId, flagMask, flagValues);
2870         }
2871         return changed;
2872     }
2873 
enforceGrantRevokeRuntimePermissionPermissions(String message)2874     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2875         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2876                 != PackageManager.PERMISSION_GRANTED
2877             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2878                 != PackageManager.PERMISSION_GRANTED) {
2879             throw new SecurityException(message + " requires "
2880                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2881                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2882         }
2883     }
2884 
enforceGrantRevokeGetRuntimePermissionPermissions(@onNull String message)2885     private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
2886         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
2887                 != PackageManager.PERMISSION_GRANTED
2888             && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2889                 != PackageManager.PERMISSION_GRANTED
2890             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2891                 != PackageManager.PERMISSION_GRANTED) {
2892             throw new SecurityException(message + " requires "
2893                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2894                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
2895                     + Manifest.permission.GET_RUNTIME_PERMISSIONS);
2896         }
2897     }
2898 
2899     /**
2900      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2901      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2902      * @param checkShell whether to prevent shell from access if there's a debugging restriction
2903      * @param message the message to log on security exception
2904      */
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)2905     private void enforceCrossUserPermission(int callingUid, int userId,
2906             boolean requireFullPermission, boolean checkShell,
2907             boolean requirePermissionWhenSameUser, String message) {
2908         if (userId < 0) {
2909             throw new IllegalArgumentException("Invalid userId " + userId);
2910         }
2911         if (checkShell) {
2912             PackageManagerServiceUtils.enforceShellRestriction(
2913                     UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2914         }
2915         if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
2916         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
2917             if (requireFullPermission) {
2918                 mContext.enforceCallingOrSelfPermission(
2919                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2920             } else {
2921                 try {
2922                     mContext.enforceCallingOrSelfPermission(
2923                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2924                 } catch (SecurityException se) {
2925                     mContext.enforceCallingOrSelfPermission(
2926                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2927                 }
2928             }
2929         }
2930     }
2931 
2932     @GuardedBy({"mSettings.mLock", "mLock"})
calculateCurrentPermissionFootprintLocked(BasePermission tree)2933     private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2934         int size = 0;
2935         for (BasePermission perm : mSettings.mPermissions.values()) {
2936             size += tree.calculateFootprint(perm);
2937         }
2938         return size;
2939     }
2940 
2941     @GuardedBy({"mSettings.mLock", "mLock"})
enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)2942     private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2943         // We calculate the max size of permissions defined by this uid and throw
2944         // if that plus the size of 'info' would exceed our stated maximum.
2945         if (tree.getUid() != Process.SYSTEM_UID) {
2946             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2947             if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2948                 throw new SecurityException("Permission tree size cap exceeded");
2949             }
2950         }
2951     }
2952 
systemReady()2953     private void systemReady() {
2954         mSystemReady = true;
2955         if (mPrivappPermissionsViolations != null) {
2956             throw new IllegalStateException("Signature|privileged permissions not in "
2957                     + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2958         }
2959 
2960         mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
2961         mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
2962     }
2963 
getVolumeUuidForPackage(PackageParser.Package pkg)2964     private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2965         if (pkg == null) {
2966             return StorageManager.UUID_PRIVATE_INTERNAL;
2967         }
2968         if (pkg.isExternal()) {
2969             if (TextUtils.isEmpty(pkg.volumeUuid)) {
2970                 return StorageManager.UUID_PRIMARY_PHYSICAL;
2971             } else {
2972                 return pkg.volumeUuid;
2973             }
2974         } else {
2975             return StorageManager.UUID_PRIVATE_INTERNAL;
2976         }
2977     }
2978 
hasPermission(PackageParser.Package pkgInfo, String permName)2979     private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2980         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2981             if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2982                 return true;
2983             }
2984         }
2985         return false;
2986     }
2987 
2988     /**
2989      * Log that a permission request was granted/revoked.
2990      *
2991      * @param action the action performed
2992      * @param name name of the permission
2993      * @param packageName package permission is for
2994      */
logPermission(int action, @NonNull String name, @NonNull String packageName)2995     private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2996         final LogMaker log = new LogMaker(action);
2997         log.setPackageName(packageName);
2998         log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
2999 
3000         mMetricsLogger.write(log);
3001     }
3002 
3003     /**
3004      * Get the mapping of background permissions to their foreground permissions.
3005      *
3006      * <p>Only initialized in the system server.
3007      *
3008      * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
3009      */
getBackgroundPermissions()3010     public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
3011         return mBackgroundPermissions;
3012     }
3013 
3014     private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
3015         @Override
systemReady()3016         public void systemReady() {
3017             PermissionManagerService.this.systemReady();
3018         }
3019         @Override
isPermissionsReviewRequired(@onNull Package pkg, @UserIdInt int userId)3020         public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
3021             return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
3022         }
3023         @Override
revokeRuntimePermissionsIfGroupChanged( @onNull PackageParser.Package newPackage, @NonNull PackageParser.Package oldPackage, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback)3024         public void revokeRuntimePermissionsIfGroupChanged(
3025                 @NonNull PackageParser.Package newPackage,
3026                 @NonNull PackageParser.Package oldPackage,
3027                 @NonNull ArrayList<String> allPackageNames,
3028                 @NonNull PermissionCallback permissionCallback) {
3029             PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
3030                     oldPackage, allPackageNames, permissionCallback);
3031         }
3032         @Override
addAllPermissions(Package pkg, boolean chatty)3033         public void addAllPermissions(Package pkg, boolean chatty) {
3034             PermissionManagerService.this.addAllPermissions(pkg, chatty);
3035         }
3036         @Override
addAllPermissionGroups(Package pkg, boolean chatty)3037         public void addAllPermissionGroups(Package pkg, boolean chatty) {
3038             PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
3039         }
3040         @Override
removeAllPermissions(Package pkg, boolean chatty)3041         public void removeAllPermissions(Package pkg, boolean chatty) {
3042             PermissionManagerService.this.removeAllPermissions(pkg, chatty);
3043         }
3044         @Override
addDynamicPermission(PermissionInfo info, boolean async, int callingUid, PermissionCallback callback)3045         public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
3046                 PermissionCallback callback) {
3047             return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
3048         }
3049         @Override
removeDynamicPermission(String permName, int callingUid, PermissionCallback callback)3050         public void removeDynamicPermission(String permName, int callingUid,
3051                 PermissionCallback callback) {
3052             PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
3053         }
3054         @Override
grantRuntimePermission(String permName, String packageName, boolean overridePolicy, int callingUid, int userId, PermissionCallback callback)3055         public void grantRuntimePermission(String permName, String packageName,
3056                 boolean overridePolicy, int callingUid, int userId,
3057                 PermissionCallback callback) {
3058             PermissionManagerService.this.grantRuntimePermission(
3059                     permName, packageName, overridePolicy, callingUid, userId, callback);
3060         }
3061         @Override
grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions, int callingUid, PermissionCallback callback)3062         public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
3063                 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3064             PermissionManagerService.this.grantRequestedRuntimePermissions(
3065                     pkg, userIds, grantedPermissions, callingUid, callback);
3066         }
3067         @Override
getWhitelistedRestrictedPermissions(PackageParser.Package pkg, @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId)3068         public List<String> getWhitelistedRestrictedPermissions(PackageParser.Package pkg,
3069                 @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId) {
3070             return PermissionManagerService.this.getWhitelistedRestrictedPermissions(pkg,
3071                     whitelistFlags, userId);
3072         }
3073         @Override
setWhitelistedRestrictedPermissions(@onNull PackageParser.Package pkg, @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, @PackageManager.PermissionWhitelistFlags int whitelistFlags, @NonNull PermissionCallback callback)3074         public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
3075                 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
3076                 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
3077                 @NonNull PermissionCallback callback) {
3078             PermissionManagerService.this.setWhitelistedRestrictedPermissions(
3079                     pkg, userIds, permissions, callingUid, whitelistFlags, callback);
3080         }
3081         @Override
grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg, int callingUid, PermissionCallback callback)3082         public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
3083                 int callingUid, PermissionCallback callback) {
3084             PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
3085                     pkg, callingUid, callback);
3086         }
3087         @Override
revokeRuntimePermission(String permName, String packageName, boolean overridePolicy, int userId, PermissionCallback callback)3088         public void revokeRuntimePermission(String permName, String packageName,
3089                 boolean overridePolicy, int userId, PermissionCallback callback) {
3090             PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
3091                     overridePolicy, userId, callback);
3092         }
3093         @Override
updatePermissions(String packageName, Package pkg, boolean replaceGrant, Collection<PackageParser.Package> allPackages, PermissionCallback callback)3094         public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
3095                 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3096             PermissionManagerService.this.updatePermissions(
3097                     packageName, pkg, replaceGrant, allPackages, callback);
3098         }
3099         @Override
updateAllPermissions(String volumeUuid, boolean sdkUpdated, Collection<PackageParser.Package> allPackages, PermissionCallback callback)3100         public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
3101                 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3102             PermissionManagerService.this.updateAllPermissions(
3103                     volumeUuid, sdkUpdated, allPackages, callback);
3104         }
3105         @Override
getAppOpPermissionPackages(String permName)3106         public String[] getAppOpPermissionPackages(String permName) {
3107             return PermissionManagerService.this.getAppOpPermissionPackages(permName);
3108         }
3109         @Override
getPermissionFlags(String permName, String packageName, int callingUid, int userId)3110         public int getPermissionFlags(String permName, String packageName, int callingUid,
3111                 int userId) {
3112             return PermissionManagerService.this.getPermissionFlags(permName, packageName,
3113                     callingUid, userId);
3114         }
3115         @Override
updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, int callingUid, int userId, boolean overridePolicy, PermissionCallback callback)3116         public void updatePermissionFlags(String permName, String packageName, int flagMask,
3117                 int flagValues, int callingUid, int userId, boolean overridePolicy,
3118                 PermissionCallback callback) {
3119             PermissionManagerService.this.updatePermissionFlags(
3120                     permName, packageName, flagMask, flagValues, callingUid, userId,
3121                     overridePolicy, callback);
3122         }
3123         @Override
updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid, int userId, Collection<Package> packages, PermissionCallback callback)3124         public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
3125                 int userId, Collection<Package> packages, PermissionCallback callback) {
3126             return PermissionManagerService.this.updatePermissionFlagsForAllApps(
3127                     flagMask, flagValues, callingUid, userId, packages, callback);
3128         }
3129         @Override
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)3130         public void enforceCrossUserPermission(int callingUid, int userId,
3131                 boolean requireFullPermission, boolean checkShell, String message) {
3132             PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3133                     requireFullPermission, checkShell, false, message);
3134         }
3135         @Override
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, boolean requirePermissionWhenSameUser, String message)3136         public void enforceCrossUserPermission(int callingUid, int userId,
3137                 boolean requireFullPermission, boolean checkShell,
3138                 boolean requirePermissionWhenSameUser, String message) {
3139             PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3140                     requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
3141         }
3142         @Override
enforceGrantRevokeRuntimePermissionPermissions(String message)3143         public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3144             PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
3145         }
3146         @Override
checkPermission(String permName, String packageName, int callingUid, int userId)3147         public int checkPermission(String permName, String packageName, int callingUid,
3148                 int userId) {
3149             return PermissionManagerService.this.checkPermission(
3150                     permName, packageName, callingUid, userId);
3151         }
3152         @Override
checkUidPermission(String permName, PackageParser.Package pkg, int uid, int callingUid)3153         public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
3154                 int callingUid) {
3155             return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
3156         }
3157         @Override
getPermissionGroupInfo(String groupName, int flags, int callingUid)3158         public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
3159                 int callingUid) {
3160             return PermissionManagerService.this.getPermissionGroupInfo(
3161                     groupName, flags, callingUid);
3162         }
3163         @Override
getAllPermissionGroups(int flags, int callingUid)3164         public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
3165             return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
3166         }
3167         @Override
getPermissionInfo(String permName, String packageName, int flags, int callingUid)3168         public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
3169                 int callingUid) {
3170             return PermissionManagerService.this.getPermissionInfo(
3171                     permName, packageName, flags, callingUid);
3172         }
3173         @Override
getPermissionInfoByGroup(String group, int flags, int callingUid)3174         public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
3175                 int callingUid) {
3176             return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
3177         }
3178         @Override
getPermissionSettings()3179         public PermissionSettings getPermissionSettings() {
3180             return mSettings;
3181         }
3182         @Override
getDefaultPermissionGrantPolicy()3183         public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
3184             return mDefaultPermissionGrantPolicy;
3185         }
3186         @Override
getPermissionTEMP(String permName)3187         public BasePermission getPermissionTEMP(String permName) {
3188             synchronized (PermissionManagerService.this.mLock) {
3189                 return mSettings.getPermissionLocked(permName);
3190             }
3191         }
3192 
3193         @Override
getAllPermissionWithProtectionLevel( @ermissionInfo.Protection int protectionLevel)3194         public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
3195                 @PermissionInfo.Protection int protectionLevel) {
3196             ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
3197 
3198             synchronized (PermissionManagerService.this.mLock) {
3199                 int numTotalPermissions = mSettings.mPermissions.size();
3200 
3201                 for (int i = 0; i < numTotalPermissions; i++) {
3202                     BasePermission bp = mSettings.mPermissions.valueAt(i);
3203 
3204                     if (bp.perm != null && bp.perm.info != null
3205                             && bp.protectionLevel == protectionLevel) {
3206                         matchingPermissions.add(bp.perm.info);
3207                     }
3208                 }
3209             }
3210 
3211             return matchingPermissions;
3212         }
3213 
3214         @Override
backupRuntimePermissions(@onNull UserHandle user)3215         public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
3216             return PermissionManagerService.this.backupRuntimePermissions(user);
3217         }
3218 
3219         @Override
restoreRuntimePermissions(@onNull byte[] backup, @NonNull UserHandle user)3220         public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
3221             PermissionManagerService.this.restoreRuntimePermissions(backup, user);
3222         }
3223 
3224         @Override
restoreDelayedRuntimePermissions(@onNull String packageName, @NonNull UserHandle user)3225         public void restoreDelayedRuntimePermissions(@NonNull String packageName,
3226                 @NonNull UserHandle user) {
3227             PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
3228         }
3229 
3230         @Override
addOnRuntimePermissionStateChangedListener( OnRuntimePermissionStateChangedListener listener)3231         public void addOnRuntimePermissionStateChangedListener(
3232                 OnRuntimePermissionStateChangedListener listener) {
3233             PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
3234                     listener);
3235         }
3236 
3237         @Override
removeOnRuntimePermissionStateChangedListener( OnRuntimePermissionStateChangedListener listener)3238         public void removeOnRuntimePermissionStateChangedListener(
3239                 OnRuntimePermissionStateChangedListener listener) {
3240             PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
3241                     listener);
3242         }
3243     }
3244 }
3245