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