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