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