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
diff --git a/Android.bp b/Android.bp
index cd0720d..eb9cbbb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -269,7 +269,7 @@
"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",
diff --git a/api/system-current.txt b/api/system-current.txt
index e27c29f..f025025d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -62,6 +62,7 @@
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.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 @@
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 {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 3f6ebc8..9ddf4bd 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -144,6 +144,7 @@
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 @@
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
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 125c4c6..3a21b96 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3993,6 +3993,14 @@
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
* with the backup mechanism.
diff --git a/core/java/android/permission/IRuntimePermissionPresenter.aidl b/core/java/android/permission/IPermissionController.aidl
similarity index 89%
rename from core/java/android/permission/IRuntimePermissionPresenter.aidl
rename to core/java/android/permission/IPermissionController.aidl
index e95428a..38951d5 100644
--- a/core/java/android/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -19,11 +19,11 @@
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,
diff --git a/core/java/android/permission/RuntimePermissionPresenter.java b/core/java/android/permission/PermissionControllerManager.java
similarity index 82%
rename from core/java/android/permission/RuntimePermissionPresenter.java
rename to core/java/android/permission/PermissionControllerManager.java
index c607e3f..66e8666 100644
--- a/core/java/android/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -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.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.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 @@
}
/**
- * Listener for delivering the result of {@link #countPermissionApps}.
+ * Callback for delivering the result of {@link #countPermissionApps}.
*/
public interface OnCountPermissionAppsResultCallback {
/**
@@ -89,29 +86,9 @@
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 @@
* @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 @@
* @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 @@
* @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 @@
* 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 @@
}
@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 @@
@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 @@
* 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 @@
* 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 @@
}
@Override
- public void run(IRuntimePermissionPresenter remoteInterface) {
+ public void run(IPermissionController remoteInterface) {
try {
remoteInterface.revokeRuntimePermission(mPackageName, mPermissionName);
} catch (RemoteException e) {
@@ -306,7 +283,7 @@
* 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;
diff --git a/core/java/android/permission/RuntimePermissionPresenterService.java b/core/java/android/permission/PermissionControllerService.java
similarity index 76%
rename from core/java/android/permission/RuntimePermissionPresenterService.java
rename to core/java/android/permission/PermissionControllerService.java
index 81ec7be..5dad071 100644
--- a/core/java/android/permission/RuntimePermissionPresenterService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -20,6 +20,7 @@
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 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 @@
@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 @@
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 @@
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 @@
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 @@
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);
}
}
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 2b3f0f5..8d568c8 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -30,6 +30,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
+import android.permission.PermissionControllerService;
import java.util.List;
@@ -43,7 +44,7 @@
*
* @hide
*
- * @deprecated use {@link android.permission.RuntimePermissionPresenterService} instead
+ * @deprecated use {@link PermissionControllerService} instead
*/
@Deprecated
@SystemApi
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b16c16d..198cd02 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -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" />
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java
index 2387b01..5e5c22a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java
@@ -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 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;