Rename RuntimePermissionPresenter to PermissionController
As this has already evolved from just presenting data. In the future any permission related calls to the permission controller will be added here. As the calls are protected by different permissions the binding will not require a permission anymore, but each individual call checks the permission. Bug: 120221960 Test: Looked at settings UI showing data from this interface Change-Id: I6b4a5c3b7ee17b145e11e2c1b6e11a8a232bffed
This commit is contained in:
@@ -269,7 +269,7 @@ java_defaults {
|
||||
"core/java/android/os/storage/IStorageEventListener.aidl",
|
||||
"core/java/android/os/storage/IStorageShutdownObserver.aidl",
|
||||
"core/java/android/os/storage/IObbActionListener.aidl",
|
||||
"core/java/android/permission/IRuntimePermissionPresenter.aidl",
|
||||
"core/java/android/permission/IPermissionController.aidl",
|
||||
"core/java/android/rolecontrollerservice/IRoleControllerService.aidl",
|
||||
":keystore_aidl",
|
||||
"core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl",
|
||||
|
||||
@@ -62,6 +62,7 @@ package android {
|
||||
field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
|
||||
field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
|
||||
field public static final java.lang.String GET_PROCESS_STATE_AND_OOM_SCORE = "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE";
|
||||
field public static final java.lang.String GET_RUNTIME_PERMISSIONS = "android.permission.GET_RUNTIME_PERMISSIONS";
|
||||
field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
|
||||
field public static final java.lang.String GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS = "android.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS";
|
||||
field public static final java.lang.String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS";
|
||||
@@ -4655,6 +4656,16 @@ package android.os.storage {
|
||||
|
||||
package android.permission {
|
||||
|
||||
public abstract class PermissionControllerService extends android.app.Service {
|
||||
ctor public PermissionControllerService();
|
||||
method public final void attachBaseContext(android.content.Context);
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public abstract int onCountPermissionApps(java.util.List<java.lang.String>, boolean, boolean);
|
||||
method public abstract java.util.List<android.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(java.lang.String);
|
||||
method public abstract void onRevokeRuntimePermission(java.lang.String, java.lang.String);
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
|
||||
}
|
||||
|
||||
public final class PermissionManager {
|
||||
method public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
|
||||
}
|
||||
@@ -4675,16 +4686,6 @@ package android.permission {
|
||||
field public static final android.os.Parcelable.Creator<android.permission.RuntimePermissionPresentationInfo> CREATOR;
|
||||
}
|
||||
|
||||
public abstract class RuntimePermissionPresenterService extends android.app.Service {
|
||||
ctor public RuntimePermissionPresenterService();
|
||||
method public final void attachBaseContext(android.content.Context);
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public abstract int onCountPermissionApps(java.util.List<java.lang.String>, boolean, boolean);
|
||||
method public abstract java.util.List<android.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(java.lang.String);
|
||||
method public abstract void onRevokeRuntimePermission(java.lang.String, java.lang.String);
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.permission.RuntimePermissionPresenterService";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.permissionpresenterservice {
|
||||
|
||||
@@ -144,6 +144,7 @@ import android.os.UserManager;
|
||||
import android.os.Vibrator;
|
||||
import android.os.health.SystemHealthManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.permission.PermissionControllerManager;
|
||||
import android.permission.PermissionManager;
|
||||
import android.print.IPrintManager;
|
||||
import android.print.PrintManager;
|
||||
@@ -1164,6 +1165,13 @@ final class SystemServiceRegistry {
|
||||
return new PermissionManager(ctx.getOuterContext());
|
||||
}});
|
||||
|
||||
registerService(Context.PERMISSION_CONTROLLER_SERVICE, PermissionControllerManager.class,
|
||||
new CachedServiceFetcher<PermissionControllerManager>() {
|
||||
@Override
|
||||
public PermissionControllerManager createService(ContextImpl ctx) {
|
||||
return new PermissionControllerManager(ctx.getOuterContext());
|
||||
}});
|
||||
|
||||
registerService(Context.ROLE_SERVICE, RoleManager.class,
|
||||
new CachedServiceFetcher<RoleManager>() {
|
||||
@Override
|
||||
|
||||
@@ -3992,6 +3992,14 @@ public abstract class Context {
|
||||
@SystemApi
|
||||
public static final String PERMISSION_SERVICE = "permission";
|
||||
|
||||
/**
|
||||
* Official published name of the (internal) permission controller service.
|
||||
*
|
||||
* @see #getSystemService(String)
|
||||
* @hide
|
||||
*/
|
||||
public static final String PERMISSION_CONTROLLER_SERVICE = "permission_controller";
|
||||
|
||||
/**
|
||||
* Use with {@link #getSystemService(String)} to retrieve an
|
||||
* {@link android.app.backup.IBackupManager IBackupManager} for communicating
|
||||
|
||||
@@ -19,11 +19,11 @@ package android.permission;
|
||||
import android.os.RemoteCallback;
|
||||
|
||||
/**
|
||||
* Interface for communication with the permission presenter service.
|
||||
* Interface for system apps to communication with the permission controller.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IRuntimePermissionPresenter {
|
||||
oneway interface IPermissionController {
|
||||
void getAppPermissions(String packageName, in RemoteCallback callback);
|
||||
void revokeRuntimePermission(String packageName, String permissionName);
|
||||
void countPermissionApps(in List<String> permissionNames, boolean countOnlyGranted,
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package android.permission;
|
||||
|
||||
import static android.permission.RuntimePermissionPresenterService.SERVICE_INTERFACE;
|
||||
import static android.permission.PermissionControllerService.SERVICE_INTERFACE;
|
||||
|
||||
import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull;
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -34,7 +37,6 @@ import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
|
||||
import com.android.internal.infra.AbstractRemoteService;
|
||||
|
||||
@@ -42,29 +44,24 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class provides information about runtime permissions for a specific
|
||||
* app or all apps. This information is dedicated for presentation purposes
|
||||
* and does not necessarily reflect the individual permissions requested/
|
||||
* granted to an app as the platform may be grouping permissions to improve
|
||||
* presentation and help the user make an informed choice. For example, all
|
||||
* runtime permissions in the same permission group may be presented as a
|
||||
* single permission in the UI.
|
||||
* Interface for communicating with the permission controller from system apps. All UI operations
|
||||
* regarding permissions and any changes to the permission state should flow through this
|
||||
* interface.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class RuntimePermissionPresenter {
|
||||
private static final String TAG = "RuntimePermPresenter";
|
||||
@SystemService(Context.PERMISSION_CONTROLLER_SERVICE)
|
||||
public final class PermissionControllerManager {
|
||||
private static final String TAG = PermissionControllerManager.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* The key for retrieving the result from the returned bundle.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String KEY_RESULT =
|
||||
"android.permission.RuntimePermissionPresenter.key.result";
|
||||
"android.permission.PermissionControllerManager.key.result";
|
||||
|
||||
/**
|
||||
* Listener for delivering the result of {@link #getAppPermissions}.
|
||||
* Callback for delivering the result of {@link #getAppPermissions}.
|
||||
*/
|
||||
public interface OnGetAppPermissionResultCallback {
|
||||
/**
|
||||
@@ -77,7 +74,7 @@ public final class RuntimePermissionPresenter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for delivering the result of {@link #countPermissionApps}.
|
||||
* Callback for delivering the result of {@link #countPermissionApps}.
|
||||
*/
|
||||
public interface OnCountPermissionAppsResultCallback {
|
||||
/**
|
||||
@@ -89,29 +86,9 @@ public final class RuntimePermissionPresenter {
|
||||
void onCountPermissionApps(int numApps);
|
||||
}
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
@GuardedBy("sLock")
|
||||
private static RuntimePermissionPresenter sInstance;
|
||||
|
||||
private final RemoteService mRemoteService;
|
||||
|
||||
/**
|
||||
* Gets the singleton runtime permission presenter.
|
||||
*
|
||||
* @param context Context for accessing resources.
|
||||
* @return The singleton instance.
|
||||
*/
|
||||
public static RuntimePermissionPresenter getInstance(@NonNull Context context) {
|
||||
synchronized (sLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new RuntimePermissionPresenter(context.getApplicationContext());
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private RuntimePermissionPresenter(@NonNull Context context) {
|
||||
public PermissionControllerManager(@NonNull Context context) {
|
||||
Intent intent = new Intent(SERVICE_INTERFACE);
|
||||
intent.setPackage(context.getPackageManager().getPermissionControllerPackageName());
|
||||
ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0);
|
||||
@@ -127,6 +104,7 @@ public final class RuntimePermissionPresenter {
|
||||
* @param callback Callback to receive the result.
|
||||
* @param handler Handler on which to invoke the callback.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
|
||||
public void getAppPermissions(@NonNull String packageName,
|
||||
@NonNull OnGetAppPermissionResultCallback callback, @Nullable Handler handler) {
|
||||
checkNotNull(packageName);
|
||||
@@ -142,6 +120,7 @@ public final class RuntimePermissionPresenter {
|
||||
* @param packageName The package for which to revoke
|
||||
* @param permissionName The permission to revoke
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
|
||||
public void revokeRuntimePermission(@NonNull String packageName,
|
||||
@NonNull String permissionName) {
|
||||
checkNotNull(packageName);
|
||||
@@ -160,6 +139,7 @@ public final class RuntimePermissionPresenter {
|
||||
* @param callback Callback to receive the result
|
||||
* @param handler Handler on which to invoke the callback
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
|
||||
public void countPermissionApps(@NonNull List<String> permissionNames,
|
||||
boolean countOnlyGranted, boolean countSystem,
|
||||
@NonNull OnCountPermissionAppsResultCallback callback, @Nullable Handler handler) {
|
||||
@@ -175,8 +155,7 @@ public final class RuntimePermissionPresenter {
|
||||
* A connection to the remote service
|
||||
*/
|
||||
static final class RemoteService extends
|
||||
AbstractMultiplePendingRequestsRemoteService<RemoteService,
|
||||
IRuntimePermissionPresenter> {
|
||||
AbstractMultiplePendingRequestsRemoteService<RemoteService, IPermissionController> {
|
||||
private static final long UNBIND_TIMEOUT_MILLIS = 10000;
|
||||
private static final long MESSAGE_TIMEOUT_MILLIS = 30000;
|
||||
|
||||
@@ -200,9 +179,8 @@ public final class RuntimePermissionPresenter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull IRuntimePermissionPresenter getServiceInterface(
|
||||
@NonNull IBinder binder) {
|
||||
return IRuntimePermissionPresenter.Stub.asInterface(binder);
|
||||
protected @NonNull IPermissionController getServiceInterface(@NonNull IBinder binder) {
|
||||
return IPermissionController.Stub.asInterface(binder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,13 +195,12 @@ public final class RuntimePermissionPresenter {
|
||||
|
||||
@Override
|
||||
public void scheduleRequest(@NonNull PendingRequest<RemoteService,
|
||||
IRuntimePermissionPresenter> pendingRequest) {
|
||||
IPermissionController> pendingRequest) {
|
||||
super.scheduleRequest(pendingRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAsyncRequest(
|
||||
@NonNull AsyncRequest<IRuntimePermissionPresenter> request) {
|
||||
public void scheduleAsyncRequest(@NonNull AsyncRequest<IPermissionController> request) {
|
||||
super.scheduleAsyncRequest(request);
|
||||
}
|
||||
}
|
||||
@@ -232,7 +209,7 @@ public final class RuntimePermissionPresenter {
|
||||
* Request for {@link #getAppPermissions}
|
||||
*/
|
||||
private static final class PendingGetAppPermissionRequest extends
|
||||
AbstractRemoteService.PendingRequest<RemoteService, IRuntimePermissionPresenter> {
|
||||
AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> {
|
||||
private final @NonNull String mPackageName;
|
||||
private final @NonNull OnGetAppPermissionResultCallback mCallback;
|
||||
|
||||
@@ -282,7 +259,7 @@ public final class RuntimePermissionPresenter {
|
||||
* Request for {@link #revokeRuntimePermission}
|
||||
*/
|
||||
private static final class PendingRevokeAppPermissionRequest
|
||||
implements AbstractRemoteService.AsyncRequest<IRuntimePermissionPresenter> {
|
||||
implements AbstractRemoteService.AsyncRequest<IPermissionController> {
|
||||
private final @NonNull String mPackageName;
|
||||
private final @NonNull String mPermissionName;
|
||||
|
||||
@@ -293,7 +270,7 @@ public final class RuntimePermissionPresenter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IRuntimePermissionPresenter remoteInterface) {
|
||||
public void run(IPermissionController remoteInterface) {
|
||||
try {
|
||||
remoteInterface.revokeRuntimePermission(mPackageName, mPermissionName);
|
||||
} catch (RemoteException e) {
|
||||
@@ -306,7 +283,7 @@ public final class RuntimePermissionPresenter {
|
||||
* Request for {@link #countPermissionApps}
|
||||
*/
|
||||
private static final class PendingCountPermissionAppsRequest extends
|
||||
AbstractRemoteService.PendingRequest<RemoteService, IRuntimePermissionPresenter> {
|
||||
AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> {
|
||||
private final @NonNull List<String> mPermissionNames;
|
||||
private final @NonNull OnCountPermissionAppsResultCallback mCallback;
|
||||
private final boolean mCountOnlyGranted;
|
||||
@@ -20,6 +20,7 @@ import static com.android.internal.util.Preconditions.checkCollectionElementsNot
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.Service;
|
||||
@@ -33,26 +34,21 @@ import android.os.RemoteCallback;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This service presents information regarding runtime permissions that is
|
||||
* used for presenting them in the UI. Runtime permissions are presented as
|
||||
* a single permission in the UI but may be composed of several individual
|
||||
* permissions.
|
||||
* This service is meant to be implemented by the app controlling permissions.
|
||||
*
|
||||
* @see RuntimePermissionPresenter
|
||||
* @see RuntimePermissionPresentationInfo
|
||||
* @see PermissionController
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public abstract class RuntimePermissionPresenterService extends Service {
|
||||
public abstract class PermissionControllerService extends Service {
|
||||
|
||||
/**
|
||||
* The {@link Intent} action that must be declared as handled by a service
|
||||
* in its manifest for the system to recognize it as a runtime permission
|
||||
* presenter service.
|
||||
*/
|
||||
public static final String SERVICE_INTERFACE =
|
||||
"android.permission.RuntimePermissionPresenterService";
|
||||
public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
|
||||
|
||||
// No need for locking - always set first and never modified
|
||||
private Handler mHandler;
|
||||
@@ -96,16 +92,17 @@ public abstract class RuntimePermissionPresenterService extends Service {
|
||||
|
||||
@Override
|
||||
public final IBinder onBind(Intent intent) {
|
||||
return new IRuntimePermissionPresenter.Stub() {
|
||||
return new IPermissionController.Stub() {
|
||||
@Override
|
||||
public void getAppPermissions(String packageName, RemoteCallback callback) {
|
||||
checkNotNull(packageName, "packageName");
|
||||
checkNotNull(callback, "callback");
|
||||
|
||||
enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
|
||||
|
||||
mHandler.sendMessage(
|
||||
obtainMessage(
|
||||
RuntimePermissionPresenterService::getAppPermissions,
|
||||
RuntimePermissionPresenterService.this, packageName, callback));
|
||||
obtainMessage(PermissionControllerService::getAppPermissions,
|
||||
PermissionControllerService.this, packageName, callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,11 +110,11 @@ public abstract class RuntimePermissionPresenterService extends Service {
|
||||
checkNotNull(packageName, "packageName");
|
||||
checkNotNull(permissionName, "permissionName");
|
||||
|
||||
enforceCallingPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, null);
|
||||
|
||||
mHandler.sendMessage(
|
||||
obtainMessage(
|
||||
RuntimePermissionPresenterService::onRevokeRuntimePermission,
|
||||
RuntimePermissionPresenterService.this, packageName,
|
||||
permissionName));
|
||||
obtainMessage(PermissionControllerService::onRevokeRuntimePermission,
|
||||
PermissionControllerService.this, packageName, permissionName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,11 +123,12 @@ public abstract class RuntimePermissionPresenterService extends Service {
|
||||
checkCollectionElementsNotNull(permissionNames, "permissionNames");
|
||||
checkNotNull(callback, "callback");
|
||||
|
||||
enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
|
||||
|
||||
mHandler.sendMessage(
|
||||
obtainMessage(
|
||||
RuntimePermissionPresenterService::countPermissionApps,
|
||||
RuntimePermissionPresenterService.this, permissionNames,
|
||||
countOnlyGranted, countSystem, callback));
|
||||
obtainMessage(PermissionControllerService::countPermissionApps,
|
||||
PermissionControllerService.this, permissionNames, countOnlyGranted,
|
||||
countSystem, callback));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -139,7 +137,7 @@ public abstract class RuntimePermissionPresenterService extends Service {
|
||||
List<RuntimePermissionPresentationInfo> permissions = onGetAppPermissions(packageName);
|
||||
if (permissions != null && !permissions.isEmpty()) {
|
||||
Bundle result = new Bundle();
|
||||
result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT, permissions);
|
||||
result.putParcelableList(PermissionControllerManager.KEY_RESULT, permissions);
|
||||
callback.sendResult(result);
|
||||
} else {
|
||||
callback.sendResult(null);
|
||||
@@ -151,7 +149,7 @@ public abstract class RuntimePermissionPresenterService extends Service {
|
||||
int numApps = onCountPermissionApps(permissionNames, countOnlyGranted, countSystem);
|
||||
|
||||
Bundle result = new Bundle();
|
||||
result.putInt(RuntimePermissionPresenter.KEY_RESULT, numApps);
|
||||
result.putInt(PermissionControllerManager.KEY_RESULT, numApps);
|
||||
callback.sendResult(result);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteCallback;
|
||||
import android.permission.PermissionControllerService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -43,7 +44,7 @@ import java.util.List;
|
||||
*
|
||||
* @hide
|
||||
*
|
||||
* @deprecated use {@link android.permission.RuntimePermissionPresenterService} instead
|
||||
* @deprecated use {@link PermissionControllerService} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@SystemApi
|
||||
|
||||
@@ -3379,6 +3379,11 @@
|
||||
<permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS"
|
||||
android:protectionLevel="signature|installer|verifier" />
|
||||
|
||||
<!-- @SystemApi Allows the system to read runtime permission state.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.GET_RUNTIME_PERMISSIONS"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- @hide Allows an application to observe permission changes. -->
|
||||
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
package com.android.settingslib.applications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.permission.PermissionControllerManager;
|
||||
import android.permission.RuntimePermissionPresentationInfo;
|
||||
import android.permission.RuntimePermissionPresenter;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
@@ -28,9 +28,9 @@ public class PermissionsSummaryHelper {
|
||||
|
||||
public static void getPermissionSummary(Context context, String pkg,
|
||||
final PermissionsResultCallback callback) {
|
||||
final RuntimePermissionPresenter presenter =
|
||||
RuntimePermissionPresenter.getInstance(context);
|
||||
presenter.getAppPermissions(pkg, permissions -> {
|
||||
final PermissionControllerManager permController =
|
||||
context.getSystemService(PermissionControllerManager.class);
|
||||
permController.getAppPermissions(pkg, permissions -> {
|
||||
final int permissionCount = permissions.size();
|
||||
|
||||
int grantedStandardCount = 0;
|
||||
|
||||
Reference in New Issue
Block a user