1 /*
2  * Copyright (C) 2018 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 android.permission;
18 
19 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
20 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
21 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
22 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
23 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
24 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
25 import static android.os.Build.VERSION_CODES.S;
26 import static android.permission.flags.Flags.FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE;
27 import static android.permission.flags.Flags.serverSideAttributionRegistration;
28 
29 import android.Manifest;
30 import android.annotation.CheckResult;
31 import android.annotation.DurationMillisLong;
32 import android.annotation.FlaggedApi;
33 import android.annotation.IntDef;
34 import android.annotation.IntRange;
35 import android.annotation.NonNull;
36 import android.annotation.Nullable;
37 import android.annotation.RequiresPermission;
38 import android.annotation.SdkConstant;
39 import android.annotation.SdkConstant.SdkConstantType;
40 import android.annotation.SystemApi;
41 import android.annotation.SystemService;
42 import android.annotation.TestApi;
43 import android.annotation.UserIdInt;
44 import android.app.ActivityManager;
45 import android.app.ActivityThread;
46 import android.app.AppGlobals;
47 import android.app.AppOpsManager;
48 import android.app.IActivityManager;
49 import android.app.PropertyInvalidatedCache;
50 import android.companion.virtual.VirtualDevice;
51 import android.companion.virtual.VirtualDeviceManager;
52 import android.compat.annotation.ChangeId;
53 import android.compat.annotation.EnabledAfter;
54 import android.content.AttributionSource;
55 import android.content.Context;
56 import android.content.PermissionChecker;
57 import android.content.pm.IPackageManager;
58 import android.content.pm.PackageManager;
59 import android.content.pm.ParceledListSlice;
60 import android.content.pm.PermissionGroupInfo;
61 import android.content.pm.PermissionInfo;
62 import android.content.pm.permission.SplitPermissionInfoParcelable;
63 import android.media.AudioManager;
64 import android.os.Binder;
65 import android.os.Build;
66 import android.os.Handler;
67 import android.os.IBinder;
68 import android.os.Looper;
69 import android.os.Message;
70 import android.os.Parcel;
71 import android.os.Parcelable;
72 import android.os.Process;
73 import android.os.RemoteException;
74 import android.os.ServiceManager;
75 import android.os.SystemClock;
76 import android.os.UserHandle;
77 import android.permission.flags.Flags;
78 import android.text.TextUtils;
79 import android.util.ArrayMap;
80 import android.util.ArraySet;
81 import android.util.DebugUtils;
82 import android.util.Log;
83 import android.util.Slog;
84 
85 import com.android.internal.R;
86 import com.android.internal.annotations.Immutable;
87 import com.android.internal.util.CollectionUtils;
88 import com.android.modules.utils.build.SdkLevel;
89 
90 import java.lang.annotation.Retention;
91 import java.lang.annotation.RetentionPolicy;
92 import java.util.ArrayList;
93 import java.util.Collections;
94 import java.util.List;
95 import java.util.Map;
96 import java.util.Objects;
97 import java.util.Set;
98 
99 /**
100  * System level service for accessing the permission capabilities of the platform.
101  *
102  * @hide
103  */
104 @SystemApi
105 @SystemService(Context.PERMISSION_SERVICE)
106 public final class PermissionManager {
107     private static final String LOG_TAG = PermissionManager.class.getName();
108 
109     /**
110      * The permission is granted.
111      */
112     public static final int PERMISSION_GRANTED = 0;
113 
114     /**
115      * The permission is denied. Applicable only to runtime permissions.
116      * <p>
117      * The app isn't expecting the permission to be denied so that a "no-op" action should be taken,
118      * such as returning an empty result.
119      */
120     public static final int PERMISSION_SOFT_DENIED = 1;
121 
122     /**
123      * The permission is denied.
124      * <p>
125      * The app should receive a {@code SecurityException}, or an error through a relevant callback.
126      */
127     public static final int PERMISSION_HARD_DENIED = 2;
128 
129     /** @hide */
130     @IntDef(prefix = { "PERMISSION_" }, value = {
131             PERMISSION_GRANTED,
132             PERMISSION_SOFT_DENIED,
133             PERMISSION_HARD_DENIED
134     })
135     @Retention(RetentionPolicy.SOURCE)
136     public @interface PermissionResult {}
137 
138     /**
139      * The set of flags that indicate that a permission state has been explicitly set
140      *
141      * @hide
142      */
143     public static final int EXPLICIT_SET_FLAGS = FLAG_PERMISSION_USER_SET
144             | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_POLICY_FIXED
145             | FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_GRANTED_BY_DEFAULT
146             | FLAG_PERMISSION_GRANTED_BY_ROLE;
147 
148     /**
149      * Activity action: Launch UI to review permission decisions.
150      * <p>
151      * <strong>Important:</strong>You must protect the activity that handles this action with the
152      * {@link android.Manifest.permission#START_REVIEW_PERMISSION_DECISIONS} permission to ensure
153      * that only the system can launch this activity. The system will not launch activities that are
154      * not properly protected.
155      * <p>
156      * Input: Nothing.
157      * </p>
158      * <p>
159      * Output: Nothing.
160      * </p>
161      */
162     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
163     @RequiresPermission(android.Manifest.permission.START_REVIEW_PERMISSION_DECISIONS)
164     public static final String ACTION_REVIEW_PERMISSION_DECISIONS =
165             "android.permission.action.REVIEW_PERMISSION_DECISIONS";
166 
167 
168     /** @hide */
169     public static final String LOG_TAG_TRACE_GRANTS = "PermissionGrantTrace";
170 
171     /** @hide */
172     public static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
173             "permissions revoked";
174     /** @hide */
175     public static final String KILL_APP_REASON_GIDS_CHANGED =
176             "permission grant or revoke changed gids";
177 
178     private static final String SYSTEM_PKG = "android";
179 
180     /**
181      * Refuse to install package if groups of permissions are bad
182      * - Permission groups should only be shared between apps sharing a certificate
183      * - If a permission belongs to a group that group should be defined
184      *
185      * @hide
186      */
187     @ChangeId
188     @EnabledAfter(targetSdkVersion = S)
189     public static final long CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS = 146211400;
190 
191     /**
192      * Whether to use the new {@link com.android.server.permission.access.AccessCheckingService}.
193      *
194      * @hide
195      */
196     public static final boolean USE_ACCESS_CHECKING_SERVICE = SdkLevel.isAtLeastV();
197 
198     /**
199      * The time to wait in between refreshing the exempted indicator role packages
200      */
201     private static final long EXEMPTED_INDICATOR_ROLE_UPDATE_FREQUENCY_MS = 15000;
202 
203     private static long sLastIndicatorUpdateTime = -1;
204 
205     private static final int[] EXEMPTED_ROLES = {R.string.config_systemAmbientAudioIntelligence,
206         R.string.config_systemUiIntelligence, R.string.config_systemAudioIntelligence,
207         R.string.config_systemNotificationIntelligence, R.string.config_systemTextIntelligence,
208         R.string.config_systemVisualIntelligence};
209 
210     private static final String[] INDICATOR_EXEMPTED_PACKAGES = new String[EXEMPTED_ROLES.length];
211 
212     /**
213      * Note: Changing this won't do anything on its own - you should also change the filtering in
214      * {@link #shouldTraceGrant}.
215      *
216      * See log output for tag {@link #LOG_TAG_TRACE_GRANTS}
217      *
218      * @hide
219      */
220     public static final boolean DEBUG_TRACE_GRANTS = false;
221     /**
222      * @hide
223      */
224     public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false;
225 
226     /**
227      * Additional debug log for virtual device permissions.
228      * @hide
229      */
230     public static final boolean DEBUG_DEVICE_PERMISSIONS = false;
231 
232     /**
233      * Intent extra: List of PermissionGroupUsages
234      * <p>
235      * Type: {@code List<PermissionGroupUsage>}
236      * </p>
237      * @hide
238      */
239     @SystemApi
240     public static final String EXTRA_PERMISSION_USAGES =
241             "android.permission.extra.PERMISSION_USAGES";
242 
243     /**
244      * Specify what permissions are device aware. Only device aware permissions can be granted to
245      * a remote device.
246      * @hide
247      */
248     public static final Set<String> DEVICE_AWARE_PERMISSIONS =
249             Flags.deviceAwarePermissionsEnabled()
250                     ? Set.of(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
251                     : Collections.emptySet();
252 
253     private final @NonNull Context mContext;
254 
255     private final IPackageManager mPackageManager;
256 
257     private final IPermissionManager mPermissionManager;
258 
259     private final LegacyPermissionManager mLegacyPermissionManager;
260 
261     private final ArrayMap<PackageManager.OnPermissionsChangedListener,
262             IOnPermissionsChangeListener> mPermissionListeners = new ArrayMap<>();
263     private PermissionUsageHelper mUsageHelper;
264 
265     private List<SplitPermissionInfo> mSplitPermissionInfos;
266 
267     /**
268      * Creates a new instance.
269      *
270      * @param context The current context in which to operate
271      *
272      * @hide
273      */
PermissionManager(@onNull Context context)274     public PermissionManager(@NonNull Context context)
275             throws ServiceManager.ServiceNotFoundException {
276         mContext = context;
277         mPackageManager = AppGlobals.getPackageManager();
278         mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
279                 "permissionmgr"));
280         mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class);
281     }
282 
283     /**
284      * Checks whether a given data access chain described by the given {@link AttributionSource}
285      * has a given permission.
286      *
287      * <strong>NOTE:</strong> Use this method only for permission checks at the
288      * point where you will deliver the permission protected data to clients.
289      *
290      * <p>For example, if an app registers a location listener it should have the location
291      * permission but no data is actually sent to the app at the moment of registration
292      * and you should use {@link #checkPermissionForPreflight(String, AttributionSource)}
293      * to determine if the app has or may have location permission (if app has only foreground
294      * location the grant state depends on the app's fg/gb state) and this check will not
295      * leave a trace that permission protected data was delivered. When you are about to
296      * deliver the location data to a registered listener you should use this method which
297      * will evaluate the permission access based on the current fg/bg state of the app and
298      * leave a record that the data was accessed.
299      *
300      * <p>Requires the start of the AttributionSource chain to have the UPDATE_APP_OPS_STATS
301      * permission for the app op accesses to be given the TRUSTED_PROXY/PROXIED flags, otherwise the
302      * accesses will have the UNTRUSTED flags.
303      *
304      * @param permission The permission to check.
305      * @param attributionSource the permission identity
306      * @param message A message describing the reason the permission was checked
307      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
308      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
309      *
310      * @see #checkPermissionForPreflight(String, AttributionSource)
311      */
312     @PermissionResult
313     @RequiresPermission(value = Manifest.permission.UPDATE_APP_OPS_STATS, conditional = true)
checkPermissionForDataDelivery(@onNull String permission, @NonNull AttributionSource attributionSource, @Nullable String message)314     public int checkPermissionForDataDelivery(@NonNull String permission,
315             @NonNull AttributionSource attributionSource, @Nullable String message) {
316         return PermissionChecker.checkPermissionForDataDelivery(mContext, permission,
317                 // FIXME(b/199526514): PID should be passed inside AttributionSource.
318                 PermissionChecker.PID_UNKNOWN, attributionSource, message);
319     }
320 
321     /**
322      *
323      * Similar to checkPermissionForDataDelivery, except it results in an app op start, rather than
324      * a note. If this method is used, then {@link #finishDataDelivery(String, AttributionSource)}
325      * must be used when access is finished.
326      *
327      * @param permission The permission to check.
328      * @param attributionSource the permission identity
329      * @param message A message describing the reason the permission was checked
330      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
331      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
332      *
333      * <p>Requires the start of the AttributionSource chain to have the UPDATE_APP_OPS_STATS
334      * permission for the app op accesses to be given the TRUSTED_PROXY/PROXIED flags, otherwise the
335      * accesses will have the UNTRUSTED flags.
336      *
337      * @see #checkPermissionForDataDelivery(String, AttributionSource, String)
338      */
339     @PermissionResult
340     @RequiresPermission(value = Manifest.permission.UPDATE_APP_OPS_STATS, conditional = true)
checkPermissionForStartDataDelivery(@onNull String permission, @NonNull AttributionSource attributionSource, @Nullable String message)341     public int checkPermissionForStartDataDelivery(@NonNull String permission,
342             @NonNull AttributionSource attributionSource, @Nullable String message) {
343         return PermissionChecker.checkPermissionForDataDelivery(mContext, permission,
344                 // FIXME(b/199526514): PID should be passed inside AttributionSource.
345                 PermissionChecker.PID_UNKNOWN, attributionSource, message, true);
346     }
347 
348     /**
349      * Indicate that usage has finished for an {@link AttributionSource} started with
350      * {@link #checkPermissionForStartDataDelivery(String, AttributionSource, String)}
351      *
352      * @param permission The permission to check.
353      * @param attributionSource the permission identity to finish
354      */
finishDataDelivery(@onNull String permission, @NonNull AttributionSource attributionSource)355     public void finishDataDelivery(@NonNull String permission,
356             @NonNull AttributionSource attributionSource) {
357         PermissionChecker.finishDataDelivery(mContext, AppOpsManager.permissionToOp(permission),
358                 attributionSource);
359     }
360 
361     /**
362      * Checks whether a given data access chain described by the given {@link AttributionSource}
363      * has a given permission. Call this method if you are the datasource which would not blame you
364      * for access to the data since you are the data. Use this API if you are the datasource of the
365      * protected state.
366      *
367      * <strong>NOTE:</strong> Use this method only for permission checks at the
368      * point where you will deliver the permission protected data to clients.
369      *
370      * <p>For example, if an app registers a location listener it should have the location
371      * permission but no data is actually sent to the app at the moment of registration
372      * and you should use {@link #checkPermissionForPreflight(String, AttributionSource)}
373      * to determine if the app has or may have location permission (if app has only foreground
374      * location the grant state depends on the app's fg/gb state) and this check will not
375      * leave a trace that permission protected data was delivered. When you are about to
376      * deliver the location data to a registered listener you should use this method which
377      * will evaluate the permission access based on the current fg/bg state of the app and
378      * leave a record that the data was accessed.
379      *
380      * <p>Requires the start of the AttributionSource chain to have the UPDATE_APP_OPS_STATS
381      * permission for the app op accesses to be given the TRUSTED_PROXY/PROXIED flags, otherwise the
382      * accesses will have the UNTRUSTED flags.
383      *
384      * @param permission The permission to check.
385      * @param attributionSource the permission identity
386      * @param message A message describing the reason the permission was checked
387      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
388      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
389      *
390      * @see #checkPermissionForPreflight(String, AttributionSource)
391      */
392     @PermissionResult
393     @RequiresPermission(value = Manifest.permission.UPDATE_APP_OPS_STATS, conditional = true)
checkPermissionForDataDeliveryFromDataSource(@onNull String permission, @NonNull AttributionSource attributionSource, @Nullable String message)394     public int checkPermissionForDataDeliveryFromDataSource(@NonNull String permission,
395             @NonNull AttributionSource attributionSource, @Nullable String message) {
396         return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(mContext, permission,
397                 PermissionChecker.PID_UNKNOWN, attributionSource, message);
398     }
399 
400     /**
401      * Checks whether a given data access chain described by the given {@link AttributionSource}
402      * has a given permission.
403      *
404      * <strong>NOTE:</strong> Use this method only for permission checks at the
405      * preflight point where you will not deliver the permission protected data
406      * to clients but schedule permission data delivery, apps register listeners,
407      * etc.
408      *
409      * <p>For example, if an app registers a data listener it should have the required
410      * permission but no data is actually sent to the app at the moment of registration
411      * and you should use this method to determine if the app has or may have the
412      * permission and this check will not leave a trace that permission protected data
413      * was delivered. When you are about to deliver the protected data to a registered
414      * listener you should use {@link #checkPermissionForDataDelivery(String,
415      * AttributionSource, String)} which will evaluate the permission access based
416      * on the current fg/bg state of the app and leave a record that the data was accessed.
417      *
418      * @param permission The permission to check.
419      * @param attributionSource The identity for which to check the permission.
420      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
421      *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
422      */
423     @PermissionResult
checkPermissionForPreflight(@onNull String permission, @NonNull AttributionSource attributionSource)424     public int checkPermissionForPreflight(@NonNull String permission,
425             @NonNull AttributionSource attributionSource) {
426         return PermissionChecker.checkPermissionForPreflight(mContext, permission,
427                 attributionSource);
428     }
429 
430     /**
431      * Retrieve all of the information we know about a particular permission.
432      *
433      * @param permissionName the fully qualified name (e.g. com.android.permission.LOGIN) of the
434      *                       permission you are interested in
435      * @param flags additional option flags to modify the data returned
436      * @return a {@link PermissionInfo} containing information about the permission, or {@code null}
437      *         if not found
438      *
439      * @hide Pending API
440      */
441     @Nullable
getPermissionInfo(@onNull String permissionName, @PackageManager.PermissionInfoFlags int flags)442     public PermissionInfo getPermissionInfo(@NonNull String permissionName,
443             @PackageManager.PermissionInfoFlags int flags) {
444         try {
445             final String packageName = mContext.getOpPackageName();
446             return mPermissionManager.getPermissionInfo(permissionName, packageName, flags);
447         } catch (RemoteException e) {
448             throw e.rethrowFromSystemServer();
449         }
450     }
451 
452     /**
453      * Query for all of the permissions associated with a particular group.
454      *
455      * @param groupName the fully qualified name (e.g. com.android.permission.LOGIN) of the
456      *                  permission group you are interested in. Use {@code null} to find all of the
457      *                  permissions not associated with a group
458      * @param flags additional option flags to modify the data returned
459      * @return a list of {@link PermissionInfo} containing information about all of the permissions
460      *         in the given group, or {@code null} if the group is not found
461      *
462      * @hide Pending API
463      */
464     @Nullable
queryPermissionsByGroup(@ullable String groupName, @PackageManager.PermissionInfoFlags int flags)465     public List<PermissionInfo> queryPermissionsByGroup(@Nullable String groupName,
466             @PackageManager.PermissionInfoFlags int flags) {
467         try {
468             final ParceledListSlice<PermissionInfo> parceledList =
469                     mPermissionManager.queryPermissionsByGroup(groupName, flags);
470             if (parceledList == null) {
471                 return null;
472             }
473             return parceledList.getList();
474         } catch (RemoteException e) {
475             throw e.rethrowFromSystemServer();
476         }
477     }
478 
479     /**
480      * Add a new dynamic permission to the system. For this to work, your package must have defined
481      * a permission tree through the
482      * {@link android.R.styleable#AndroidManifestPermissionTree &lt;permission-tree&gt;} tag in its
483      * manifest. A package can only add permissions to trees that were defined by either its own
484      * package or another with the same user id; a permission is in a tree if it matches the name of
485      * the permission tree + ".": for example, "com.foo.bar" is a member of the permission tree
486      * "com.foo".
487      * <p>
488      * It is good to make your permission tree name descriptive, because you are taking possession
489      * of that entire set of permission names. Thus, it must be under a domain you control, with a
490      * suffix that will not match any normal permissions that may be declared in any applications
491      * that are part of that domain.
492      * <p>
493      * New permissions must be added before any .apks are installed that use those permissions.
494      * Permissions you add through this method are remembered across reboots of the device. If the
495      * given permission already exists, the info you supply here will be used to update it.
496      *
497      * @param permissionInfo description of the permission to be added
498      * @param async whether the persistence of the permission should be asynchronous, allowing it to
499      *              return quicker and batch a series of adds, at the expense of no guarantee the
500      *              added permission will be retained if the device is rebooted before it is
501      *              written.
502      * @return {@code true} if a new permission was created, {@code false} if an existing one was
503      *         updated
504      * @throws SecurityException if you are not allowed to add the given permission name
505      *
506      * @see #removePermission(String)
507      *
508      * @hide Pending API
509      */
addPermission(@onNull PermissionInfo permissionInfo, boolean async)510     public boolean addPermission(@NonNull PermissionInfo permissionInfo, boolean async) {
511         try {
512             return mPermissionManager.addPermission(permissionInfo, async);
513         } catch (RemoteException e) {
514             throw e.rethrowFromSystemServer();
515         }
516     }
517 
518     /**
519      * Removes a permission that was previously added with
520      * {@link #addPermission(PermissionInfo, boolean)}. The same ownership rules apply -- you are
521      * only allowed to remove permissions that you are allowed to add.
522      *
523      * @param permissionName the name of the permission to remove
524      * @throws SecurityException if you are not allowed to remove the given permission name
525      *
526      * @see #addPermission(PermissionInfo, boolean)
527      *
528      * @hide Pending API
529      */
removePermission(@onNull String permissionName)530     public void removePermission(@NonNull String permissionName) {
531         try {
532             mPermissionManager.removePermission(permissionName);
533         } catch (RemoteException e) {
534             throw e.rethrowFromSystemServer();
535         }
536     }
537 
538     /**
539      * Retrieve all of the information we know about a particular group of permissions.
540      *
541      * @param groupName the fully qualified name (e.g. com.android.permission_group.APPS) of the
542      *                  permission you are interested in
543      * @param flags additional option flags to modify the data returned
544      * @return a {@link PermissionGroupInfo} containing information about the permission, or
545      *         {@code null} if not found
546      *
547      * @hide Pending API
548      */
549     @Nullable
getPermissionGroupInfo(@onNull String groupName, @PackageManager.PermissionGroupInfoFlags int flags)550     public PermissionGroupInfo getPermissionGroupInfo(@NonNull String groupName,
551             @PackageManager.PermissionGroupInfoFlags int flags) {
552         try {
553             return mPermissionManager.getPermissionGroupInfo(groupName, flags);
554         } catch (RemoteException e) {
555             throw e.rethrowFromSystemServer();
556         }
557     }
558 
559     /**
560      * Retrieve all of the known permission groups in the system.
561      *
562      * @param flags additional option flags to modify the data returned
563      * @return a list of {@link PermissionGroupInfo} containing information about all of the known
564      *         permission groups
565      *
566      * @hide Pending API
567      */
568     @NonNull
getAllPermissionGroups( @ackageManager.PermissionGroupInfoFlags int flags)569     public List<PermissionGroupInfo> getAllPermissionGroups(
570             @PackageManager.PermissionGroupInfoFlags int flags) {
571         try {
572             final ParceledListSlice<PermissionGroupInfo> parceledList =
573                     mPermissionManager.getAllPermissionGroups(flags);
574             if (parceledList == null) {
575                 return Collections.emptyList();
576             }
577             return parceledList.getList();
578         } catch (RemoteException e) {
579             throw e.rethrowFromSystemServer();
580         }
581     }
582 
583     /**
584      * Checks whether a particular permissions has been revoked for a package by policy. Typically
585      * the device owner or the profile owner may apply such a policy. The user cannot grant policy
586      * revoked permissions, hence the only way for an app to get such a permission is by a policy
587      * change.
588      *
589      * @param packageName the name of the package you are checking against
590      * @param permissionName the name of the permission you are checking for
591      *
592      * @return whether the permission is restricted by policy
593      *
594      * @hide Pending API
595      */
596     @CheckResult
isPermissionRevokedByPolicy(@onNull String packageName, @NonNull String permissionName)597     public boolean isPermissionRevokedByPolicy(@NonNull String packageName,
598             @NonNull String permissionName) {
599         try {
600             return mPermissionManager.isPermissionRevokedByPolicy(packageName, permissionName,
601                     mContext.getDeviceId(), mContext.getUserId());
602         } catch (RemoteException e) {
603             throw e.rethrowFromSystemServer();
604         }
605     }
606 
607     /** @hide */
shouldTraceGrant( @onNull String packageName, @NonNull String permissionName, int userId)608     public static boolean shouldTraceGrant(
609             @NonNull String packageName, @NonNull String permissionName, int userId) {
610         // To be modified when debugging
611         // template: if ("".equals(packageName) && "".equals(permissionName)) return true;
612         return false;
613     }
614 
615     /**
616      * Grant a runtime permission to an application which the application does not already have. The
617      * permission must have been requested by the application. If the application is not allowed to
618      * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
619      * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
620      * <p>
621      * <strong>Note: </strong>Using this API requires holding
622      * {@code android.permission.GRANT_RUNTIME_PERMISSIONS} and if the user ID is not the current
623      * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
624      *
625      * @param packageName the package to which to grant the permission
626      * @param permissionName the permission name to grant
627      * @param user the user for which to grant the permission
628      *
629      * @see #revokeRuntimePermission(String, String, android.os.UserHandle, String)
630      *
631      * @hide
632      */
633     @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
634     //@SystemApi
grantRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull UserHandle user)635     public void grantRuntimePermission(@NonNull String packageName,
636             @NonNull String permissionName, @NonNull UserHandle user) {
637         String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
638         if (persistentDeviceId == null) {
639             return;
640         }
641 
642         grantRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, user);
643     }
644 
645     /**
646      * Grant a runtime permission to an application which the application does not already have. The
647      * permission must have been requested by the application. If the application is not allowed to
648      * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
649      * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
650      *
651      * @param packageName the package to which to grant the permission
652      * @param permissionName the permission name to grant
653      * @param persistentDeviceId the device Id to which to grant the permission
654      *
655      * @see #revokeRuntimePermission(String, String, String, String)
656      *
657      * @hide
658      */
659     @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
660     @SystemApi
661     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
grantRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId)662     public void grantRuntimePermission(@NonNull String packageName,
663             @NonNull String permissionName, @NonNull String persistentDeviceId) {
664         grantRuntimePermissionInternal(packageName, permissionName, persistentDeviceId,
665                 mContext.getUser());
666     }
667 
grantRuntimePermissionInternal(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull UserHandle user)668     private void grantRuntimePermissionInternal(@NonNull String packageName,
669             @NonNull String permissionName, @NonNull String persistentDeviceId,
670             @NonNull UserHandle user) {
671         if (DEBUG_TRACE_GRANTS
672                 && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
673             Log.i(LOG_TAG_TRACE_GRANTS, "App " + mContext.getPackageName() + " is granting "
674                     + packageName + " "
675                     + permissionName + " for user " + user.getIdentifier()
676                     + " for persistent device " + persistentDeviceId, new RuntimeException());
677         }
678         try {
679             mPermissionManager.grantRuntimePermission(packageName, permissionName,
680                     persistentDeviceId, user.getIdentifier());
681         } catch (RemoteException e) {
682             throw e.rethrowFromSystemServer();
683         }
684     }
685 
686     /**
687      * Revoke a runtime permission that was previously granted by
688      * {@link #grantRuntimePermission(String, String, android.os.UserHandle)}. The permission must
689      * have been requested by and granted to the application. If the application is not allowed to
690      * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
691      * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
692      * <p>
693      * <strong>Note: </strong>Using this API requires holding
694      * {@code android.permission.REVOKE_RUNTIME_PERMISSIONS} and if the user ID is not the current
695      * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
696      *
697      * @param packageName the package from which to revoke the permission
698      * @param permissionName the permission name to revoke
699      * @param user the user for which to revoke the permission
700      * @param reason the reason for the revoke, or {@code null} for unspecified
701      *
702      * @see #grantRuntimePermission(String, String, android.os.UserHandle)
703      *
704      * @hide
705      */
706     @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
707     //@SystemApi
revokeRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull UserHandle user, @Nullable String reason)708     public void revokeRuntimePermission(@NonNull String packageName,
709             @NonNull String permissionName, @NonNull UserHandle user, @Nullable String reason) {
710         String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
711         if (persistentDeviceId == null) {
712             return;
713         }
714 
715         revokeRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, user,
716                 reason);
717     }
718 
719     /**
720      * Revoke a runtime permission that was previously granted by
721      * {@link #grantRuntimePermission(String, String, String)}. The permission must
722      * have been requested by and granted to the application. If the application is not allowed to
723      * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
724      * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
725      *
726      * @param packageName the package from which to revoke the permission
727      * @param permissionName the permission name to revoke
728      * @param persistentDeviceId the persistent device id for which to revoke the permission
729      * @param reason the reason for the revoke, or {@code null} for unspecified
730      *
731      * @see #grantRuntimePermission(String, String, String)
732      *
733      * @hide
734      */
735     @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
736     @SystemApi
737     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
revokeRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @Nullable String reason)738     public void revokeRuntimePermission(@NonNull String packageName,
739             @NonNull String permissionName, @NonNull String persistentDeviceId,
740             @Nullable String reason) {
741         revokeRuntimePermissionInternal(packageName, permissionName, persistentDeviceId,
742                 mContext.getUser(), reason);
743     }
744 
revokeRuntimePermissionInternal(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull UserHandle user, @Nullable String reason)745     private void revokeRuntimePermissionInternal(@NonNull String packageName,
746             @NonNull String permissionName, @NonNull String persistentDeviceId,
747             @NonNull UserHandle user, @Nullable String reason) {
748         if (DEBUG_TRACE_PERMISSION_UPDATES
749                 && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
750             Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " "
751                     + permissionName + " for user " + user.getIdentifier()
752                     + " for persistent device "
753                     + persistentDeviceId + " with reason "
754                     + reason, new RuntimeException());
755         }
756         try {
757             mPermissionManager.revokeRuntimePermission(packageName, permissionName,
758                     persistentDeviceId, user.getIdentifier(), reason);
759         } catch (RemoteException e) {
760             throw e.rethrowFromSystemServer();
761         }
762     }
763 
764     /**
765      * Gets the state flags associated with a permission.
766      *
767      * @param packageName the package name for which to get the flags
768      * @param permissionName the permission for which to get the flags
769      * @param user the user for which to get permission flags
770      * @return the permission flags
771      *
772      * @hide
773      */
774     @PackageManager.PermissionFlags
775     @RequiresPermission(anyOf = {
776             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
777             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
778             android.Manifest.permission.GET_RUNTIME_PERMISSIONS
779     })
780     //@SystemApi
getPermissionFlags(@onNull String packageName, @NonNull String permissionName, @NonNull UserHandle user)781     public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName,
782             @NonNull UserHandle user) {
783         String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
784         if (persistentDeviceId == null) {
785             return 0;
786         }
787 
788         return getPermissionFlagsInternal(packageName, permissionName, persistentDeviceId, user);
789     }
790 
791     /**
792      * Gets the state flags associated with a permission.
793      *
794      * @param packageName the package name for which to get the flags
795      * @param permissionName the permission for which to get the flags
796      * @param persistentDeviceId the persistent device Id for which to get permission flags
797      * @return the permission flags
798      *
799      * @hide
800      */
801     @PackageManager.PermissionFlags
802     @RequiresPermission(anyOf = {
803             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
804             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
805             android.Manifest.permission.GET_RUNTIME_PERMISSIONS
806     })
807     @SystemApi
808     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
getPermissionFlags(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId)809     public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName,
810             @NonNull String persistentDeviceId) {
811         return getPermissionFlagsInternal(packageName, permissionName, persistentDeviceId,
812                 mContext.getUser());
813     }
814 
getPermissionFlagsInternal(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull UserHandle user)815     private int getPermissionFlagsInternal(@NonNull String packageName,
816             @NonNull String permissionName, @NonNull String persistentDeviceId,
817             @NonNull UserHandle user) {
818         try {
819             return mPermissionManager.getPermissionFlags(packageName, permissionName,
820                     persistentDeviceId, user.getIdentifier());
821         } catch (RemoteException e) {
822             throw e.rethrowFromSystemServer();
823         }
824     }
825 
826     /**
827      * Updates the flags associated with a permission by replacing the flags in the specified mask
828      * with the provided flag values.
829      *
830      * @param packageName The package name for which to update the flags
831      * @param permissionName The permission for which to update the flags
832      * @param flagMask The flags which to replace
833      * @param flagValues The flags with which to replace
834      * @param user The user for which to update the permission flags
835      *
836      * @hide
837      */
838     @RequiresPermission(anyOf = {
839             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
840             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
841     })
842     //@SystemApi
updatePermissionFlags(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionFlags int flagMask, @PackageManager.PermissionFlags int flagValues, @NonNull UserHandle user)843     public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName,
844             @PackageManager.PermissionFlags int flagMask,
845             @PackageManager.PermissionFlags int flagValues, @NonNull UserHandle user) {
846         String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
847         if (persistentDeviceId == null) {
848             return;
849         }
850 
851         updatePermissionFlagsInternal(packageName, permissionName, flagMask, flagValues,
852                 persistentDeviceId, user);
853     }
854 
855     /**
856      * Updates the flags associated with a permission by replacing the flags in the specified mask
857      * with the provided flag values.
858      *
859      * @param packageName The package name for which to update the flags
860      * @param permissionName The permission for which to update the flags
861      * @param persistentDeviceId The persistent device for which to update the permission flags
862      * @param flagMask The flags which to replace
863      * @param flagValues The flags with which to replace
864      *
865      * @hide
866      */
867     @RequiresPermission(anyOf = {
868             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
869             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
870     })
871     @SystemApi
872     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
updatePermissionFlags(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @PackageManager.PermissionFlags int flagMask, @PackageManager.PermissionFlags int flagValues )873     public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName,
874             @NonNull String persistentDeviceId,
875             @PackageManager.PermissionFlags int flagMask,
876             @PackageManager.PermissionFlags int flagValues
877     ) {
878         updatePermissionFlagsInternal(packageName, permissionName, flagMask, flagValues,
879                 persistentDeviceId, mContext.getUser());
880     }
881 
updatePermissionFlagsInternal(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionFlags int flagMask, @PackageManager.PermissionFlags int flagValues, @NonNull String persistentDeviceId, @NonNull UserHandle user )882     private void updatePermissionFlagsInternal(@NonNull String packageName,
883             @NonNull String permissionName,
884             @PackageManager.PermissionFlags int flagMask,
885             @PackageManager.PermissionFlags int flagValues, @NonNull String persistentDeviceId,
886             @NonNull UserHandle user
887     ) {
888         if (DEBUG_TRACE_PERMISSION_UPDATES && shouldTraceGrant(packageName, permissionName,
889                 user.getIdentifier())) {
890             Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is updating flags for "
891                     + packageName + " " + permissionName + " for user "
892                     + user.getIdentifier() + " for persistentDeviceId " + persistentDeviceId + ": "
893                     + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
894                     + " := " + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_",
895                             flagValues), new RuntimeException());
896         }
897         try {
898             final boolean checkAdjustPolicyFlagPermission =
899                     mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
900             mPermissionManager.updatePermissionFlags(packageName, permissionName, flagMask,
901                     flagValues, checkAdjustPolicyFlagPermission,
902                     persistentDeviceId, user.getIdentifier());
903         } catch (RemoteException e) {
904             throw e.rethrowFromSystemServer();
905         }
906     }
907 
908     /**
909      * Gets the restricted permissions that have been allowlisted and the app is allowed to have
910      * them granted in their full form.
911      * <p>
912      * Permissions can be hard restricted which means that the app cannot hold them or soft
913      * restricted where the app can hold the permission but in a weaker form. Whether a permission
914      * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or
915      * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission
916      * declaration. Allowlisting a hard restricted permission allows for the to hold that permission
917      * and allowlisting a soft restricted permission allows the app to hold the permission in its
918      * full, unrestricted form.
919      * <p>
920      * There are four allowlists:
921      * <ol>
922      * <li>
923      * One for cases where the system permission policy allowlists a permission. This list
924      * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be
925      * accessed by pre-installed holders of a dedicated permission.
926      * <li>
927      * One for cases where the system allowlists the permission when upgrading from an OS version in
928      * which the permission was not restricted to an OS version in which the permission is
929      * restricted. This list corresponds to the
930      * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by
931      * pre-installed holders of a dedicated permission or the installer on record.
932      * <li>
933      * One for cases where the installer of the package allowlists a permission. This list
934      * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be
935      * accessed by pre-installed holders of a dedicated permission or the installer on record.
936      * </ol>
937      *
938      * @param packageName the app for which to get allowlisted permissions
939      * @param allowlistFlag the flag to determine which allowlist to query. Only one flag can be
940      *                      passed.
941      * @return the allowlisted permissions that are on any of the allowlists you query for
942      * @throws SecurityException if you try to access a allowlist that you have no access to
943      *
944      * @see #addAllowlistedRestrictedPermission(String, String, int)
945      * @see #removeAllowlistedRestrictedPermission(String, String, int)
946      * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM
947      * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE
948      * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER
949      *
950      * @hide Pending API
951      */
952     @NonNull
953     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
954             conditional = true)
getAllowlistedRestrictedPermissions(@onNull String packageName, @PackageManager.PermissionWhitelistFlags int allowlistFlag)955     public Set<String> getAllowlistedRestrictedPermissions(@NonNull String packageName,
956             @PackageManager.PermissionWhitelistFlags int allowlistFlag) {
957         try {
958             final List<String> allowlist = mPermissionManager.getAllowlistedRestrictedPermissions(
959                     packageName, allowlistFlag, mContext.getUserId());
960             if (allowlist == null) {
961                 return Collections.emptySet();
962             }
963             return new ArraySet<>(allowlist);
964         } catch (RemoteException e) {
965             throw e.rethrowFromSystemServer();
966         }
967     }
968 
969     /**
970      * Adds a allowlisted restricted permission for an app.
971      * <p>
972      * Permissions can be hard restricted which means that the app cannot hold them or soft
973      * restricted where the app can hold the permission but in a weaker form. Whether a permission
974      * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or
975      * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission
976      * declaration. Allowlisting a hard restricted permission allows for the to hold that permission
977      * and allowlisting a soft restricted permission allows the app to hold the permission in its
978      * full, unrestricted form.
979      * <p>There are four allowlists:
980      * <ol>
981      * <li>
982      * One for cases where the system permission policy allowlists a permission. This list
983      * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be
984      * accessed by pre-installed holders of a dedicated permission.
985      * <li>
986      * One for cases where the system allowlists the permission when upgrading from an OS version in
987      * which the permission was not restricted to an OS version in which the permission is
988      * restricted. This list corresponds to the
989      * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by
990      * pre-installed holders of a dedicated permission or the installer on record.
991      * <li>
992      * One for cases where the installer of the package allowlists a permission. This list
993      * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be
994      * accessed by pre-installed holders of a dedicated permission or the installer on record.
995      * </ol>
996      * <p>
997      * You need to specify the allowlists for which to set the allowlisted permissions which will
998      * clear the previous allowlisted permissions and replace them with the provided ones.
999      *
1000      * @param packageName the app for which to get allowlisted permissions
1001      * @param permissionName the allowlisted permission to add
1002      * @param allowlistFlags the allowlists to which to add. Passing multiple flags updates all
1003      *                       specified allowlists.
1004      * @return whether the permission was added to the allowlist
1005      * @throws SecurityException if you try to modify a allowlist that you have no access to.
1006      *
1007      * @see #getAllowlistedRestrictedPermissions(String, int)
1008      * @see #removeAllowlistedRestrictedPermission(String, String, int)
1009      * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM
1010      * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE
1011      * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER
1012      *
1013      * @hide Pending API
1014      */
1015     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
1016             conditional = true)
addAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionWhitelistFlags int allowlistFlags)1017     public boolean addAllowlistedRestrictedPermission(@NonNull String packageName,
1018             @NonNull String permissionName,
1019             @PackageManager.PermissionWhitelistFlags int allowlistFlags) {
1020         try {
1021             return mPermissionManager.addAllowlistedRestrictedPermission(packageName,
1022                     permissionName, allowlistFlags, mContext.getUserId());
1023         } catch (RemoteException e) {
1024             throw e.rethrowFromSystemServer();
1025         }
1026     }
1027 
1028     /**
1029      * Removes a allowlisted restricted permission for an app.
1030      * <p>
1031      * Permissions can be hard restricted which means that the app cannot hold them or soft
1032      * restricted where the app can hold the permission but in a weaker form. Whether a permission
1033      * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or
1034      * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission
1035      * declaration. Allowlisting a hard restricted permission allows for the to hold that permission
1036      * and allowlisting a soft restricted permission allows the app to hold the permission in its
1037      * full, unrestricted form.
1038      * <p>There are four allowlists:
1039      * <ol>
1040      * <li>
1041      * One for cases where the system permission policy allowlists a permission. This list
1042      * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be
1043      * accessed by pre-installed holders of a dedicated permission.
1044      * <li>
1045      * One for cases where the system allowlists the permission when upgrading from an OS version in
1046      * which the permission was not restricted to an OS version in which the permission is
1047      * restricted. This list corresponds to the
1048      * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by
1049      * pre-installed holders of a dedicated permission or the installer on record.
1050      * <li>
1051      * One for cases where the installer of the package allowlists a permission. This list
1052      * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be
1053      * accessed by pre-installed holders of a dedicated permission or the installer on record.
1054      * </ol>
1055      * <p>
1056      * You need to specify the allowlists for which to set the allowlisted permissions which will
1057      * clear the previous allowlisted permissions and replace them with the provided ones.
1058      *
1059      * @param packageName the app for which to get allowlisted permissions
1060      * @param permissionName the allowlisted permission to remove
1061      * @param allowlistFlags the allowlists from which to remove. Passing multiple flags updates all
1062      *                       specified allowlists.
1063      * @return whether the permission was removed from the allowlist
1064      * @throws SecurityException if you try to modify a allowlist that you have no access to.
1065      *
1066      * @see #getAllowlistedRestrictedPermissions(String, int)
1067      * @see #addAllowlistedRestrictedPermission(String, String, int)
1068      * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM
1069      * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE
1070      * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER
1071      *
1072      * @hide Pending API
1073      */
1074     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
1075             conditional = true)
removeAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionWhitelistFlags int allowlistFlags)1076     public boolean removeAllowlistedRestrictedPermission(@NonNull String packageName,
1077             @NonNull String permissionName,
1078             @PackageManager.PermissionWhitelistFlags int allowlistFlags) {
1079         try {
1080             return mPermissionManager.removeAllowlistedRestrictedPermission(packageName,
1081                     permissionName, allowlistFlags, mContext.getUserId());
1082         } catch (RemoteException e) {
1083             throw e.rethrowFromSystemServer();
1084         }
1085     }
1086 
1087     /**
1088      * Checks whether an application is exempted from having its permissions be automatically
1089      * revoked when the app is unused for an extended period of time.
1090      * <p>
1091      * Only the installer on record that installed the given package, or a holder of
1092      * {@code WHITELIST_AUTO_REVOKE_PERMISSIONS} is allowed to call this.
1093      *
1094      * @param packageName the app for which to set exemption
1095      * @return whether the app is exempted
1096      * @throws SecurityException if you you have no access to this
1097      *
1098      * @see #setAutoRevokeExempted
1099      *
1100      * @hide Pending API
1101      */
1102     @RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
1103             conditional = true)
isAutoRevokeExempted(@onNull String packageName)1104     public boolean isAutoRevokeExempted(@NonNull String packageName) {
1105         try {
1106             return mPermissionManager.isAutoRevokeExempted(packageName, mContext.getUserId());
1107         } catch (RemoteException e) {
1108             throw e.rethrowFromSystemServer();
1109         }
1110     }
1111 
1112     /**
1113      * Marks an application exempted from having its permissions be automatically revoked when the
1114      * app is unused for an extended period of time.
1115      * <p>
1116      * Only the installer on record that installed the given package is allowed to call this.
1117      * <p>
1118      * Packages start in exempted state, and it is the installer's responsibility to un-exempt the
1119      * packages it installs, unless auto-revoking permissions from that package would cause
1120      * breakages beyond having to re-request the permission(s).
1121      *
1122      * @param packageName the app for which to set exemption
1123      * @param exempted whether the app should be exempted
1124      * @return whether any change took effect
1125      * @throws SecurityException if you you have no access to modify this
1126      *
1127      * @see #isAutoRevokeExempted
1128      *
1129      * @hide Pending API
1130      */
1131     @RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
1132             conditional = true)
setAutoRevokeExempted(@onNull String packageName, boolean exempted)1133     public boolean setAutoRevokeExempted(@NonNull String packageName, boolean exempted) {
1134         try {
1135             return mPermissionManager.setAutoRevokeExempted(packageName, exempted,
1136                     mContext.getUserId());
1137         } catch (RemoteException e) {
1138             throw e.rethrowFromSystemServer();
1139         }
1140     }
1141 
1142     /**
1143      * Get whether you should show UI with rationale for requesting a permission. You should do this
1144      * only if you do not have the permission and the context in which the permission is requested
1145      * does not clearly communicate to the user what would be the benefit from grating this
1146      * permission.
1147      *
1148      * @param permissionName a permission your app wants to request
1149      * @return whether you can show permission rationale UI
1150      *
1151      * @hide
1152      */
1153     //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
shouldShowRequestPermissionRationale(@onNull String permissionName)1154     public boolean shouldShowRequestPermissionRationale(@NonNull String permissionName) {
1155         try {
1156             final String packageName = mContext.getPackageName();
1157             return mPermissionManager.shouldShowRequestPermissionRationale(packageName,
1158                     permissionName, mContext.getDeviceId(), mContext.getUserId());
1159         } catch (RemoteException e) {
1160             throw e.rethrowFromSystemServer();
1161         }
1162     }
1163 
1164     /**
1165      * Add a listener for permission changes for installed packages.
1166      *
1167      * @param listener the listener to add
1168      *
1169      * @hide
1170      */
1171     //@SystemApi
1172     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
addOnPermissionsChangeListener( @onNull PackageManager.OnPermissionsChangedListener listener)1173     public void addOnPermissionsChangeListener(
1174             @NonNull PackageManager.OnPermissionsChangedListener listener) {
1175         synchronized (mPermissionListeners) {
1176             if (mPermissionListeners.get(listener) != null) {
1177                 return;
1178             }
1179             final OnPermissionsChangeListenerDelegate delegate =
1180                     new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
1181             try {
1182                 mPermissionManager.addOnPermissionsChangeListener(delegate);
1183                 mPermissionListeners.put(listener, delegate);
1184             } catch (RemoteException e) {
1185                 throw e.rethrowFromSystemServer();
1186             }
1187         }
1188     }
1189 
1190     /**
1191      * Remove a listener for permission changes for installed packages.
1192      *
1193      * @param listener the listener to remove
1194      *
1195      * @hide
1196      */
1197     //@SystemApi
1198     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
removeOnPermissionsChangeListener( @onNull PackageManager.OnPermissionsChangedListener listener)1199     public void removeOnPermissionsChangeListener(
1200             @NonNull PackageManager.OnPermissionsChangedListener listener) {
1201         synchronized (mPermissionListeners) {
1202             final IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
1203             if (delegate != null) {
1204                 try {
1205                     mPermissionManager.removeOnPermissionsChangeListener(delegate);
1206                     mPermissionListeners.remove(listener);
1207                 } catch (RemoteException e) {
1208                     throw e.rethrowFromSystemServer();
1209                 }
1210             }
1211         }
1212     }
1213 
1214     /**
1215      * Gets the version of the runtime permission database.
1216      *
1217      * @return The database version, -1 when this is an upgrade from pre-Q, 0 when this is a fresh
1218      * install.
1219      *
1220      * @hide
1221      */
1222     @SystemApi
1223     @RequiresPermission(anyOf = {
1224             Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
1225             Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS
1226     })
getRuntimePermissionsVersion()1227     public @IntRange(from = 0) int getRuntimePermissionsVersion() {
1228         try {
1229             return mPackageManager.getRuntimePermissionsVersion(mContext.getUserId());
1230         } catch (RemoteException e) {
1231             throw e.rethrowFromSystemServer();
1232         }
1233     }
1234 
1235     /**
1236      * Sets the version of the runtime permission database.
1237      *
1238      * @param version The new version.
1239      *
1240      * @hide
1241      */
1242     @SystemApi
1243     @RequiresPermission(anyOf = {
1244             Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
1245             Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS
1246     })
setRuntimePermissionsVersion(@ntRangefrom = 0) int version)1247     public void setRuntimePermissionsVersion(@IntRange(from = 0) int version) {
1248         try {
1249             mPackageManager.setRuntimePermissionsVersion(version, mContext.getUserId());
1250         } catch (RemoteException e) {
1251             throw e.rethrowFromSystemServer();
1252         }
1253     }
1254 
1255     /**
1256      * Get set of permissions that have been split into more granular or dependent permissions.
1257      *
1258      * <p>E.g. before {@link android.os.Build.VERSION_CODES#Q} an app that was granted
1259      * {@link Manifest.permission#ACCESS_COARSE_LOCATION} could access the location while it was in
1260      * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#Q}
1261      * the location permission only grants location access while the app is in foreground. This
1262      * would break apps that target before {@link android.os.Build.VERSION_CODES#Q}. Hence whenever
1263      * such an old app asks for a location permission (i.e. the
1264      * {@link SplitPermissionInfo#getSplitPermission()}), then the
1265      * {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside
1266      * {@link SplitPermissionInfo#getNewPermissions}) is added.
1267      *
1268      * <p>Note: Regular apps do not have to worry about this. The platform and permission controller
1269      * automatically add the new permissions where needed.
1270      *
1271      * @return All permissions that are split.
1272      */
getSplitPermissions()1273     public @NonNull List<SplitPermissionInfo> getSplitPermissions() {
1274         if (mSplitPermissionInfos != null) {
1275             return mSplitPermissionInfos;
1276         }
1277 
1278         List<SplitPermissionInfoParcelable> parcelableList;
1279         try {
1280             parcelableList = ActivityThread.getPermissionManager().getSplitPermissions();
1281         } catch (RemoteException e) {
1282             Slog.e(LOG_TAG, "Error getting split permissions", e);
1283             return Collections.emptyList();
1284         }
1285 
1286         mSplitPermissionInfos = splitPermissionInfoListToNonParcelableList(parcelableList);
1287 
1288         return mSplitPermissionInfos;
1289     }
1290 
1291     /**
1292      * Initialize the PermissionUsageHelper, which will register active app op listeners
1293      *
1294      * @hide
1295      */
initializeUsageHelper()1296     public void initializeUsageHelper() {
1297         if (mUsageHelper == null) {
1298             mUsageHelper = new PermissionUsageHelper(mContext);
1299         }
1300     }
1301 
1302     /**
1303      * Teardown the PermissionUsageHelper, removing listeners
1304      *
1305      * @hide
1306      */
tearDownUsageHelper()1307     public void tearDownUsageHelper() {
1308         if (mUsageHelper != null) {
1309             mUsageHelper.tearDown();
1310             mUsageHelper = null;
1311         }
1312     }
1313 
1314     /**
1315      * @return A list of permission groups currently or recently used by all apps by all users in
1316      * the current profile group.
1317      *
1318      * @hide
1319      */
1320     @TestApi
1321     @NonNull
1322     @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
getIndicatorAppOpUsageData()1323     public List<PermissionGroupUsage> getIndicatorAppOpUsageData() {
1324         return getIndicatorAppOpUsageData(new AudioManager().isMicrophoneMute());
1325     }
1326 
1327     /**
1328      * @param micMuted whether to consider the microphone muted when retrieving audio ops
1329      * @return A list of permission groups currently or recently used by all apps by all users in
1330      * the current profile group.
1331      *
1332      * @hide
1333      */
1334     @TestApi
1335     @NonNull
1336     @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
getIndicatorAppOpUsageData(boolean micMuted)1337     public List<PermissionGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) {
1338         // Lazily initialize the usage helper
1339         initializeUsageHelper();
1340         boolean includeMicrophoneUsage = !micMuted;
1341         return mUsageHelper.getOpUsageDataByDevice(includeMicrophoneUsage,
1342                 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
1343     }
1344 
1345     /**
1346      * Determine if a package should be shown in indicators. Only a select few roles, and the
1347      * system app itself, are hidden. These values are updated at most every 15 seconds.
1348      * @hide
1349      */
shouldShowPackageForIndicatorCached(@onNull Context context, @NonNull String packageName)1350     public static boolean shouldShowPackageForIndicatorCached(@NonNull Context context,
1351             @NonNull String packageName) {
1352         return !getIndicatorExemptedPackages(context).contains(packageName);
1353     }
1354 
1355     /**
1356      * Get the list of packages that are not shown by the indicators. Only a select few roles, and
1357      * the system app itself, are hidden. These values are updated at most every 15 seconds.
1358      * @hide
1359      */
getIndicatorExemptedPackages(@onNull Context context)1360     public static Set<String> getIndicatorExemptedPackages(@NonNull Context context) {
1361         updateIndicatorExemptedPackages(context);
1362         ArraySet<String> pkgNames = new ArraySet<>();
1363         pkgNames.add(SYSTEM_PKG);
1364         for (int i = 0; i < INDICATOR_EXEMPTED_PACKAGES.length; i++) {
1365             String exemptedPackage = INDICATOR_EXEMPTED_PACKAGES[i];
1366             if (exemptedPackage != null) {
1367                 pkgNames.add(exemptedPackage);
1368             }
1369         }
1370         return pkgNames;
1371     }
1372 
1373     /**
1374      * Update the cached indicator exempted packages
1375      * @hide
1376      */
updateIndicatorExemptedPackages(@onNull Context context)1377     public static void updateIndicatorExemptedPackages(@NonNull Context context) {
1378         long now = SystemClock.elapsedRealtime();
1379         if (sLastIndicatorUpdateTime == -1
1380                 || (now - sLastIndicatorUpdateTime) > EXEMPTED_INDICATOR_ROLE_UPDATE_FREQUENCY_MS) {
1381             sLastIndicatorUpdateTime = now;
1382             for (int i = 0; i < EXEMPTED_ROLES.length; i++) {
1383                 INDICATOR_EXEMPTED_PACKAGES[i] = context.getString(EXEMPTED_ROLES[i]);
1384             }
1385         }
1386     }
1387     /**
1388      * Gets the list of packages that have permissions that specified
1389      * {@code requestDontAutoRevokePermissions=true} in their
1390      * {@code application} manifest declaration.
1391      *
1392      * @return the list of packages for current user
1393      * @hide
1394      */
1395     @SystemApi
1396     @NonNull
1397     @RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
getAutoRevokeExemptionRequestedPackages()1398     public Set<String> getAutoRevokeExemptionRequestedPackages() {
1399         try {
1400             return CollectionUtils.toSet(mPermissionManager.getAutoRevokeExemptionRequestedPackages(
1401                     mContext.getUser().getIdentifier()));
1402         } catch (RemoteException e) {
1403             throw e.rethrowFromSystemServer();
1404         }
1405     }
1406 
1407     /**
1408      * Gets the list of packages that have permissions that specified
1409      * {@code autoRevokePermissions=disallowed} in their
1410      * {@code application} manifest declaration.
1411      *
1412      * @return the list of packages for current user
1413      * @hide
1414      */
1415     @SystemApi
1416     @NonNull
1417     @RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
getAutoRevokeExemptionGrantedPackages()1418     public Set<String> getAutoRevokeExemptionGrantedPackages() {
1419         try {
1420             return CollectionUtils.toSet(mPermissionManager.getAutoRevokeExemptionGrantedPackages(
1421                     mContext.getUser().getIdentifier()));
1422         } catch (RemoteException e) {
1423             throw e.rethrowFromSystemServer();
1424         }
1425     }
1426 
splitPermissionInfoListToNonParcelableList( List<SplitPermissionInfoParcelable> parcelableList)1427     private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList(
1428             List<SplitPermissionInfoParcelable> parcelableList) {
1429         final int size = parcelableList.size();
1430         List<SplitPermissionInfo> list = new ArrayList<>(size);
1431         for (int i = 0; i < size; i++) {
1432             list.add(new SplitPermissionInfo(parcelableList.get(i)));
1433         }
1434         return list;
1435     }
1436 
1437     /**
1438      * Converts a {@link List} of {@link SplitPermissionInfo} into a List of
1439      * {@link SplitPermissionInfoParcelable} and returns it.
1440      * @hide
1441      */
splitPermissionInfoListToParcelableList( List<SplitPermissionInfo> splitPermissionsList)1442     public static List<SplitPermissionInfoParcelable> splitPermissionInfoListToParcelableList(
1443             List<SplitPermissionInfo> splitPermissionsList) {
1444         final int size = splitPermissionsList.size();
1445         List<SplitPermissionInfoParcelable> outList = new ArrayList<>(size);
1446         for (int i = 0; i < size; i++) {
1447             SplitPermissionInfo info = splitPermissionsList.get(i);
1448             outList.add(new SplitPermissionInfoParcelable(
1449                     info.getSplitPermission(), info.getNewPermissions(), info.getTargetSdk()));
1450         }
1451         return outList;
1452     }
1453 
1454     /**
1455      * A permission that was added in a previous API level might have split into several
1456      * permissions. This object describes one such split.
1457      */
1458     @Immutable
1459     public static final class SplitPermissionInfo {
1460         private @NonNull final SplitPermissionInfoParcelable mSplitPermissionInfoParcelable;
1461 
1462         @Override
equals(@ullable Object o)1463         public boolean equals(@Nullable Object o) {
1464             if (this == o) return true;
1465             if (o == null || getClass() != o.getClass()) return false;
1466             SplitPermissionInfo that = (SplitPermissionInfo) o;
1467             return mSplitPermissionInfoParcelable.equals(that.mSplitPermissionInfoParcelable);
1468         }
1469 
1470         @Override
hashCode()1471         public int hashCode() {
1472             return mSplitPermissionInfoParcelable.hashCode();
1473         }
1474 
1475         /**
1476          * Get the permission that is split.
1477          */
getSplitPermission()1478         public @NonNull String getSplitPermission() {
1479             return mSplitPermissionInfoParcelable.getSplitPermission();
1480         }
1481 
1482         /**
1483          * Get the permissions that are added.
1484          */
getNewPermissions()1485         public @NonNull List<String> getNewPermissions() {
1486             return mSplitPermissionInfoParcelable.getNewPermissions();
1487         }
1488 
1489         /**
1490          * Get the target API level when the permission was split.
1491          */
getTargetSdk()1492         public int getTargetSdk() {
1493             return mSplitPermissionInfoParcelable.getTargetSdk();
1494         }
1495 
1496         /**
1497          * Constructs a split permission.
1498          *
1499          * @param splitPerm old permission that will be split
1500          * @param newPerms list of new permissions that {@code rootPerm} will be split into
1501          * @param targetSdk apps targetting SDK versions below this will have {@code rootPerm}
1502          * split into {@code newPerms}
1503          * @hide
1504          */
SplitPermissionInfo(@onNull String splitPerm, @NonNull List<String> newPerms, int targetSdk)1505         public SplitPermissionInfo(@NonNull String splitPerm, @NonNull List<String> newPerms,
1506                 int targetSdk) {
1507             this(new SplitPermissionInfoParcelable(splitPerm, newPerms, targetSdk));
1508         }
1509 
SplitPermissionInfo(@onNull SplitPermissionInfoParcelable parcelable)1510         private SplitPermissionInfo(@NonNull SplitPermissionInfoParcelable parcelable) {
1511             mSplitPermissionInfoParcelable = parcelable;
1512         }
1513     }
1514 
1515     /**
1516      * Starts a one-time permission session for a given package.
1517      * @see #startOneTimePermissionSession(String, long, long, int, int)
1518      * @hide
1519      * @deprecated Use {@link #startOneTimePermissionSession(String, long, long, int, int)} instead
1520      */
1521     @Deprecated
1522     @SystemApi
1523     @RequiresPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
startOneTimePermissionSession(@onNull String packageName, long timeoutMillis, @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive)1524     public void startOneTimePermissionSession(@NonNull String packageName, long timeoutMillis,
1525             @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer,
1526             @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) {
1527         startOneTimePermissionSession(packageName, timeoutMillis, -1,
1528                 importanceToResetTimer, importanceToKeepSessionAlive);
1529     }
1530 
1531     /**
1532      * Starts a one-time permission session for a given package. A one-time permission session is
1533      * ended if app becomes inactive. Inactivity is defined as the package's uid importance level
1534      * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid
1535      * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start
1536      * until going > importanceToResetTimer.
1537      * <p>
1538      * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive
1539      * then the session is extended until either the importance goes above
1540      * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which
1541      * will continue the session and reset the timer.
1542      * </p>
1543      * <p>
1544      * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}.
1545      * </p>
1546      * <p>
1547      * Once the session ends
1548      * {@link PermissionControllerService#onOneTimePermissionSessionTimeout(String)} is invoked.
1549      * </p>
1550      * <p>
1551      * Note that if there is currently an active session for a package a new one isn't created but
1552      * each parameter of the existing one will be updated to the more aggressive of both sessions.
1553      * This means that durations will be set to the shortest parameter and importances will be set
1554      * to the lowest one.
1555      * </p>
1556      * @param packageName The package to start a one-time permission session for
1557      * @param timeoutMillis Number of milliseconds for an app to be in an inactive state
1558      * @param revokeAfterKilledDelayMillis Number of milliseconds to wait before revoking on the
1559      *                                     event an app is terminated. Set to -1 to use default
1560      *                                     value for the device.
1561      * @param importanceToResetTimer The least important level to uid must be to reset the timer
1562      * @param importanceToKeepSessionAlive The least important level the uid must be to keep the
1563      *                                     session alive
1564      *
1565      * @hide
1566      */
1567     @SystemApi
1568     @RequiresPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
startOneTimePermissionSession(@onNull String packageName, @DurationMillisLong long timeoutMillis, @DurationMillisLong long revokeAfterKilledDelayMillis, @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive)1569     public void startOneTimePermissionSession(@NonNull String packageName,
1570             @DurationMillisLong long timeoutMillis,
1571             @DurationMillisLong long revokeAfterKilledDelayMillis,
1572             @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer,
1573             @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) {
1574         try {
1575             mPermissionManager.startOneTimePermissionSession(packageName, mContext.getDeviceId(),
1576                     mContext.getUserId(), timeoutMillis, revokeAfterKilledDelayMillis);
1577         } catch (RemoteException e) {
1578             e.rethrowFromSystemServer();
1579         }
1580     }
1581 
1582     /**
1583      * Stops the one-time permission session for the package. The callback to the end of session is
1584      * not invoked. If there is no one-time session for the package then nothing happens.
1585      *
1586      * @param packageName Package to stop the one-time permission session for
1587      *
1588      * @hide
1589      */
1590     @SystemApi
1591     @RequiresPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
stopOneTimePermissionSession(@onNull String packageName)1592     public void stopOneTimePermissionSession(@NonNull String packageName) {
1593         try {
1594             mPermissionManager.stopOneTimePermissionSession(packageName,
1595                     mContext.getUserId());
1596         } catch (RemoteException e) {
1597             e.rethrowFromSystemServer();
1598         }
1599     }
1600 
1601     /**
1602      * Checks whether the package with the given pid/uid can read device identifiers.
1603      *
1604      * @param packageName      the name of the package to be checked for identifier access
1605      * @param message          the message to be used for logging during identifier access
1606      *                         verification
1607      * @param callingFeatureId the feature in the package
1608      * @param pid              the process id of the package to be checked
1609      * @param uid              the uid of the package to be checked
1610      * @return {@link PackageManager#PERMISSION_GRANTED} if the package is allowed identifier
1611      * access, {@link PackageManager#PERMISSION_DENIED} otherwise
1612      * @hide
1613      */
1614     @SystemApi
checkDeviceIdentifierAccess(@ullable String packageName, @Nullable String message, @Nullable String callingFeatureId, int pid, int uid)1615     public int checkDeviceIdentifierAccess(@Nullable String packageName, @Nullable String message,
1616             @Nullable String callingFeatureId, int pid, int uid) {
1617         return mLegacyPermissionManager.checkDeviceIdentifierAccess(packageName, message,
1618                 callingFeatureId, pid, uid);
1619     }
1620 
1621     /**
1622      * Registers an attribution source with the OS. An app can only register an attribution
1623      * source for itself. Once an attribution source has been registered another app can
1624      * check whether this registration exists and thus trust the payload in the source
1625      * object. This is important for permission checking and specifically for app op blaming
1626      * since a malicious app should not be able to force the OS to blame another app
1627      * that doesn't participate in an attribution chain.
1628      *
1629      * @param source The attribution source to register.
1630      * @return The registered new attribution source.
1631      *
1632      * @see #isRegisteredAttributionSource(AttributionSource)
1633      *
1634      * @hide
1635      */
1636     @TestApi
registerAttributionSource(@onNull AttributionSource source)1637     public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) {
1638         // We use a shared static token for sources that are not registered since the token's
1639         // only used for process death detection. If we are about to use the source for security
1640         // enforcement we need to replace the binder with a unique one.
1641         try {
1642             if (serverSideAttributionRegistration()) {
1643                 IBinder newToken = mPermissionManager.registerAttributionSource(source.asState());
1644                 return source.withToken(newToken);
1645             } else {
1646                 AttributionSource registeredSource = source.withToken(new Binder());
1647                 mPermissionManager.registerAttributionSource(registeredSource.asState());
1648                 return registeredSource;
1649             }
1650         } catch (RemoteException e) {
1651             e.rethrowFromSystemServer();
1652         }
1653         return source;
1654     }
1655 
1656     /**
1657      * Checks whether an attribution source is registered.
1658      *
1659      * @param source The attribution source to check.
1660      * @return Whether this is a registered source.
1661      *
1662      * @see #registerAttributionSource(AttributionSource)
1663      *
1664      * @hide
1665      */
1666     @TestApi
1667     @FlaggedApi(FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE)
isRegisteredAttributionSource(@onNull AttributionSource source)1668     public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) {
1669         try {
1670             return mPermissionManager.isRegisteredAttributionSource(source.asState());
1671         } catch (RemoteException e) {
1672             e.rethrowFromSystemServer();
1673         }
1674         return false;
1675     }
1676 
1677     /**
1678      * Gets the number of currently registered attribution sources for a particular UID. This should
1679      * only be used for testing purposes.
1680      * @hide
1681      */
1682     @RequiresPermission(Manifest.permission.UPDATE_APP_OPS_STATS)
getRegisteredAttributionSourceCountForTest(int uid)1683     public int getRegisteredAttributionSourceCountForTest(int uid) {
1684         try {
1685             return mPermissionManager.getRegisteredAttributionSourceCount(uid);
1686         } catch (RemoteException e) {
1687             e.rethrowFromSystemServer();
1688         }
1689         return -1;
1690     }
1691 
1692     /**
1693      * Revoke the POST_NOTIFICATIONS permission, without killing the app. This method must ONLY BE
1694      * USED in CTS or local tests.
1695      *
1696      * @param packageName The package to be revoked
1697      * @param userId The user for which to revoke
1698      *
1699      * @hide
1700      */
1701     @TestApi
1702     @RequiresPermission(Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL)
revokePostNotificationPermissionWithoutKillForTest(@onNull String packageName, int userId)1703     public void revokePostNotificationPermissionWithoutKillForTest(@NonNull String packageName,
1704             int userId) {
1705         try {
1706             mPermissionManager.revokePostNotificationPermissionWithoutKillForTest(packageName,
1707                     userId);
1708         } catch (RemoteException e) {
1709             e.rethrowFromSystemServer();
1710         }
1711     }
1712 
1713     // Only warn once for assuming that root or system UID has a permission
1714     // to reduce duplicate logcat output.
1715     private static volatile boolean sShouldWarnMissingActivityManager = true;
1716 
checkPermissionUncached(@ullable String permission, int pid, int uid, int deviceId)1717     private static int checkPermissionUncached(@Nullable String permission, int pid, int uid,
1718             int deviceId) {
1719         final IActivityManager am = ActivityManager.getService();
1720         if (am == null) {
1721             // Well this is super awkward; we somehow don't have an active ActivityManager
1722             // instance. If we're testing a root or system UID, then they totally have whatever
1723             // permission this is.
1724             final int appId = UserHandle.getAppId(uid);
1725             if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
1726                 if (sShouldWarnMissingActivityManager) {
1727                     Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " holds "
1728                             + permission);
1729                     sShouldWarnMissingActivityManager = false;
1730                 }
1731                 return PackageManager.PERMISSION_GRANTED;
1732             }
1733             Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " does not hold "
1734                     + permission);
1735             return PackageManager.PERMISSION_DENIED;
1736         }
1737         try {
1738             sShouldWarnMissingActivityManager = true;
1739             return am.checkPermissionForDevice(permission, pid, uid, deviceId);
1740         } catch (RemoteException e) {
1741             throw e.rethrowFromSystemServer();
1742         }
1743     }
1744 
1745     /**
1746      * Identifies a permission query.
1747      *
1748      * N.B. we include the checking pid for tracking purposes but don't include it in the equality
1749      * comparison: we use only uid for the actual security check, so comparing pid would result
1750      * in spurious misses.
1751      *
1752      * @hide
1753      */
1754     @Immutable
1755     private static final class PermissionQuery {
1756         final String permission;
1757         final int pid;
1758         final int uid;
1759         final int deviceId;
1760 
PermissionQuery(@ullable String permission, int pid, int uid, int deviceId)1761         PermissionQuery(@Nullable String permission, int pid, int uid, int deviceId) {
1762             this.permission = permission;
1763             this.pid = pid;
1764             this.uid = uid;
1765             this.deviceId = deviceId;
1766         }
1767 
1768         @Override
toString()1769         public String toString() {
1770             return TextUtils.formatSimple("PermissionQuery(permission=\"%s\", pid=%d, uid=%d, "
1771                             + "deviceId=%d)", permission, pid, uid, deviceId);
1772         }
1773 
1774         @Override
hashCode()1775         public int hashCode() {
1776             // N.B. pid doesn't count toward equality and therefore shouldn't count for
1777             // hashing either.
1778             return Objects.hash(permission, uid, deviceId);
1779         }
1780 
1781         @Override
equals(@ullable Object rval)1782         public boolean equals(@Nullable Object rval) {
1783             // N.B. pid doesn't count toward equality!
1784             if (rval == null) {
1785                 return false;
1786             }
1787             PermissionQuery other;
1788             try {
1789                 other = (PermissionQuery) rval;
1790             } catch (ClassCastException ex) {
1791                 return false;
1792             }
1793             return uid == other.uid && deviceId == other.deviceId
1794                     && Objects.equals(permission, other.permission);
1795         }
1796     }
1797 
1798     /** @hide */
1799     public static final String CACHE_KEY_PACKAGE_INFO = "cache_key.package_info";
1800 
1801     /** @hide */
1802     private static final PropertyInvalidatedCache<PermissionQuery, Integer> sPermissionCache =
1803             new PropertyInvalidatedCache<PermissionQuery, Integer>(
1804                     2048, CACHE_KEY_PACKAGE_INFO, "checkPermission") {
1805                 @Override
1806                 public Integer recompute(PermissionQuery query) {
1807                     return checkPermissionUncached(query.permission, query.pid, query.uid,
1808                             query.deviceId);
1809                 }
1810             };
1811 
1812     /** @hide */
checkPermission(@ullable String permission, int pid, int uid, int deviceId)1813     public static int checkPermission(@Nullable String permission, int pid, int uid, int deviceId) {
1814         return sPermissionCache.query(new PermissionQuery(permission, pid, uid, deviceId));
1815     }
1816 
1817     /**
1818      * Gets the permission states for requested package and persistent device.
1819      * <p>
1820      * <strong>Note: </strong>Default device permissions are not inherited in this API. Returns the
1821      * exact permission states for the requested device.
1822      *
1823      * @param packageName name of the package you are checking against
1824      * @param persistentDeviceId id of the persistent device you are checking against
1825      * @return mapping of all permission states keyed by their permission names
1826      *
1827      * @hide
1828      */
1829     @SystemApi
1830     @NonNull
1831     @RequiresPermission(anyOf = {
1832             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1833             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1834             android.Manifest.permission.GET_RUNTIME_PERMISSIONS
1835     })
1836     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
getAllPermissionStates(@onNull String packageName, @NonNull String persistentDeviceId)1837     public Map<String, PermissionState> getAllPermissionStates(@NonNull String packageName,
1838             @NonNull String persistentDeviceId) {
1839         try {
1840             return mPermissionManager.getAllPermissionStates(packageName, persistentDeviceId,
1841                     mContext.getUserId());
1842         } catch (RemoteException e) {
1843             throw e.rethrowFromSystemServer();
1844         }
1845     }
1846 
1847     /**
1848      * Make checkPermission() above bypass the permission cache in this process.
1849      *
1850      * @hide
1851      */
disablePermissionCache()1852     public static void disablePermissionCache() {
1853         sPermissionCache.disableLocal();
1854     }
1855 
1856     /**
1857      * Like PermissionQuery, but for permission checks based on a package name instead of
1858      * a UID.
1859      */
1860     @Immutable
1861     private static final class PackageNamePermissionQuery {
1862         final String permName;
1863         final String pkgName;
1864         final String persistentDeviceId;
1865         @UserIdInt
1866         final int userId;
1867 
PackageNamePermissionQuery(@ullable String permName, @Nullable String pkgName, @Nullable String persistentDeviceId, @UserIdInt int userId)1868         PackageNamePermissionQuery(@Nullable String permName, @Nullable String pkgName,
1869                 @Nullable String persistentDeviceId, @UserIdInt int userId) {
1870             this.permName = permName;
1871             this.pkgName = pkgName;
1872             this.persistentDeviceId = persistentDeviceId;
1873             this.userId = userId;
1874         }
1875 
1876         @Override
toString()1877         public String toString() {
1878             return TextUtils.formatSimple(
1879                     "PackageNamePermissionQuery(pkgName=\"%s\", permName=\"%s\", "
1880                             + "persistentDeviceId=%s, userId=%s\")",
1881                     pkgName, permName, persistentDeviceId, userId);
1882         }
1883 
1884         @Override
hashCode()1885         public int hashCode() {
1886             return Objects.hash(permName, pkgName, persistentDeviceId, userId);
1887         }
1888 
1889         @Override
equals(@ullable Object rval)1890         public boolean equals(@Nullable Object rval) {
1891             if (rval == null) {
1892                 return false;
1893             }
1894             PackageNamePermissionQuery other;
1895             try {
1896                 other = (PackageNamePermissionQuery) rval;
1897             } catch (ClassCastException ex) {
1898                 return false;
1899             }
1900             return Objects.equals(permName, other.permName)
1901                     && Objects.equals(pkgName, other.pkgName)
1902                     && Objects.equals(persistentDeviceId, other.persistentDeviceId)
1903                     && userId == other.userId;
1904         }
1905     }
1906 
1907     /* @hide */
checkPackageNamePermissionUncached( String permName, String pkgName, String persistentDeviceId, @UserIdInt int userId)1908     private static int checkPackageNamePermissionUncached(
1909             String permName, String pkgName, String persistentDeviceId, @UserIdInt int userId) {
1910         try {
1911             return ActivityThread.getPermissionManager().checkPermission(
1912                     pkgName, permName, persistentDeviceId, userId);
1913         } catch (RemoteException e) {
1914             throw e.rethrowFromSystemServer();
1915         }
1916     }
1917 
1918     /* @hide */
1919     private static PropertyInvalidatedCache<PackageNamePermissionQuery, Integer>
1920             sPackageNamePermissionCache =
1921             new PropertyInvalidatedCache<PackageNamePermissionQuery, Integer>(
1922                     16, CACHE_KEY_PACKAGE_INFO, "checkPackageNamePermission") {
1923                 @Override
1924                 public Integer recompute(PackageNamePermissionQuery query) {
1925                     return checkPackageNamePermissionUncached(
1926                             query.permName, query.pkgName, query.persistentDeviceId, query.userId);
1927                 }
1928                 @Override
1929                 public boolean bypass(PackageNamePermissionQuery query) {
1930                     return query.userId < 0;
1931                 }
1932             };
1933 
1934     /**
1935      * Check whether a package has a permission for given device.
1936      *
1937      * @hide
1938      */
checkPackageNamePermission(String permName, String pkgName, int deviceId, @UserIdInt int userId)1939     public int checkPackageNamePermission(String permName, String pkgName,
1940             int deviceId, @UserIdInt int userId) {
1941         String persistentDeviceId = getPersistentDeviceId(deviceId);
1942         return sPackageNamePermissionCache.query(
1943                 new PackageNamePermissionQuery(permName, pkgName, persistentDeviceId, userId));
1944     }
1945 
1946     @Nullable
getPersistentDeviceId(int deviceId)1947     private String getPersistentDeviceId(int deviceId) {
1948         String persistentDeviceId = null;
1949 
1950         if (deviceId == Context.DEVICE_ID_DEFAULT) {
1951             persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
1952         } else if (android.companion.virtual.flags.Flags.vdmPublicApis()) {
1953             VirtualDeviceManager virtualDeviceManager = mContext.getSystemService(
1954                     VirtualDeviceManager.class);
1955             if (virtualDeviceManager != null) {
1956                 VirtualDevice virtualDevice = virtualDeviceManager.getVirtualDevice(deviceId);
1957                 if (virtualDevice == null) {
1958                     Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId);
1959                     return null;
1960                 }
1961                 persistentDeviceId = virtualDevice.getPersistentDeviceId();
1962                 if (persistentDeviceId == null) {
1963                     Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId);
1964                 }
1965             }
1966         } else {
1967             Slog.e(LOG_TAG, "vdmPublicApis flag is not enabled when device Id " + deviceId
1968                     + "is not default.");
1969         }
1970         return persistentDeviceId;
1971     }
1972 
1973     /**
1974      * Check whether a package has been granted a permission on a given device.
1975      * <p>
1976      * <strong>Note: </strong>This API returns the underlying permission state
1977      * as-is and is mostly intended for permission managing system apps. To
1978      * perform an access check for a certain app, please use the
1979      * {@link Context#checkPermission} APIs instead.
1980      *
1981      * @param permissionName The name of the permission you are checking for.
1982      * @param packageName The name of the package you are checking against.
1983      * @param persistentDeviceId The id of the physical device that you are checking permission
1984      *                           against.
1985      *
1986      * @return If the package has the permission on the device, PERMISSION_GRANTED is
1987      * returned.  If it does not have the permission on the device, PERMISSION_DENIED
1988      * is returned.
1989      *
1990      * @see VirtualDevice#getPersistentDeviceId()
1991      * @see PackageManager#PERMISSION_GRANTED
1992      * @see PackageManager#PERMISSION_DENIED
1993      *
1994      * @hide
1995      */
1996     @SystemApi
1997     @PermissionResult
1998     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
checkPermission(@onNull String permissionName, @NonNull String packageName, @NonNull String persistentDeviceId)1999     public int checkPermission(@NonNull String permissionName, @NonNull String packageName,
2000             @NonNull String persistentDeviceId) {
2001         return sPackageNamePermissionCache.query(
2002                 new PackageNamePermissionQuery(permissionName, packageName, persistentDeviceId,
2003                         mContext.getUserId()));
2004     }
2005 
2006     /**
2007      * Make checkPackageNamePermission() bypass the cache in this process.
2008      *
2009      * @hide
2010      */
disablePackageNamePermissionCache()2011     public static void disablePackageNamePermissionCache() {
2012         sPackageNamePermissionCache.disableLocal();
2013     }
2014 
2015     private final class OnPermissionsChangeListenerDelegate
2016             extends IOnPermissionsChangeListener.Stub implements Handler.Callback {
2017         private static final int MSG_PERMISSIONS_CHANGED = 1;
2018 
2019         private final PackageManager.OnPermissionsChangedListener mListener;
2020         private final Handler mHandler;
2021 
OnPermissionsChangeListenerDelegate( PackageManager.OnPermissionsChangedListener listener, Looper looper)2022         public OnPermissionsChangeListenerDelegate(
2023                 PackageManager.OnPermissionsChangedListener listener, Looper looper) {
2024             mListener = listener;
2025             mHandler = new Handler(looper, this);
2026         }
2027 
2028         @Override
onPermissionsChanged(int uid, String persistentDeviceId)2029         public void onPermissionsChanged(int uid, String persistentDeviceId) {
2030             mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0, persistentDeviceId)
2031                     .sendToTarget();
2032         }
2033 
2034         @Override
handleMessage(Message msg)2035         public boolean handleMessage(Message msg) {
2036             switch (msg.what) {
2037                 case MSG_PERMISSIONS_CHANGED: {
2038                     final int uid = msg.arg1;
2039                     final String persistentDeviceId = msg.obj.toString();
2040                     mListener.onPermissionsChanged(uid, persistentDeviceId);
2041                     return true;
2042                 }
2043                 default:
2044                     return false;
2045             }
2046         }
2047     }
2048 
2049     /**
2050      * Data class for the state of a permission requested by a package
2051      *
2052      * @hide
2053      */
2054     @SystemApi
2055     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
2056     public static final class PermissionState implements Parcelable {
2057         private final boolean mGranted;
2058         private final int mFlags;
2059 
2060         /** @hide */
2061         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
PermissionState(boolean granted, int flags)2062         public PermissionState(boolean granted, int flags) {
2063             mGranted = granted;
2064             mFlags = flags;
2065         }
2066 
2067         /**
2068          * Returns whether this permission is granted
2069          */
2070         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
isGranted()2071         public boolean isGranted() {
2072             return mGranted;
2073         }
2074 
2075         /**
2076          * Returns the flags associated with this permission state
2077          * @see PackageManager#getPermissionFlags
2078          */
2079         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
getFlags()2080         public int getFlags() {
2081             return mFlags;
2082         }
2083 
2084         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
2085         @Override
describeContents()2086         public int describeContents() {
2087             return 0;
2088         }
2089 
2090         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
2091         @Override
writeToParcel(@onNull Parcel parcel, int flags)2092         public void writeToParcel(@NonNull Parcel parcel, int flags) {
2093             parcel.writeBoolean(mGranted);
2094             parcel.writeInt(mFlags);
2095         }
2096 
PermissionState(Parcel parcel)2097         private PermissionState(Parcel parcel) {
2098             this(parcel.readBoolean(), parcel.readInt());
2099         }
2100 
2101         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
2102         public static final @NonNull Creator<PermissionState> CREATOR = new Creator<>() {
2103             public PermissionState createFromParcel(Parcel source) {
2104                 return new PermissionState(source);
2105             }
2106 
2107             public PermissionState[] newArray(int size) {
2108                 return new PermissionState[size];
2109             }
2110         };
2111 
2112         /** @hide */
2113         @Override
equals(Object o)2114         public boolean equals(Object o) {
2115             if (this == o) return true;
2116             if (o == null || getClass() != o.getClass()) return false;
2117             PermissionState that = (PermissionState) o;
2118             return mGranted == that.mGranted && mFlags == that.mFlags;
2119         }
2120 
2121         /** @hide */
2122         @Override
hashCode()2123         public int hashCode() {
2124             return Objects.hash(mGranted, mFlags);
2125         }
2126 
2127         /** @hide */
2128         @Override
toString()2129         public String toString() {
2130             return "PermissionState{"
2131                     + "mGranted=" + mGranted
2132                     + ", mFlags=" + mFlags
2133                     + '}';
2134         }
2135     }
2136 }
2137