Allow shell to revoke notification permission without kill
Add the revokePostNotificationPermissionWithoutKillForTest API, which will allow the shell to revoke the POST_NOTIFICATIONS permission without killing this app. Gate this permission behind the REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL permission, which is signature|privileged, accessible only to the shell. Ignore-AOSP-First: Contains information about unreleased features Test: manual Bug: 194833441 Change-Id: I3177d1aeb338591c1d736aa6b4f073b6db6227e7
This commit is contained in:
@@ -36,6 +36,7 @@ package android {
|
||||
field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
|
||||
field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
|
||||
field public static final String RESET_APP_ERRORS = "android.permission.RESET_APP_ERRORS";
|
||||
field public static final String REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL = "android.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL";
|
||||
field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS";
|
||||
field public static final String START_TASKS_FROM_RECENTS = "android.permission.START_TASKS_FROM_RECENTS";
|
||||
field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
|
||||
@@ -2036,6 +2037,7 @@ package android.permission {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData(boolean);
|
||||
method @NonNull public android.content.AttributionSource registerAttributionSource(@NonNull android.content.AttributionSource);
|
||||
method public void revokePostNotificationPermissionWithoutKillForTest(@NonNull String, int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ interface IPermissionManager {
|
||||
void revokeRuntimePermission(String packageName, String permissionName, int userId,
|
||||
String reason);
|
||||
|
||||
void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId);
|
||||
|
||||
boolean shouldShowRequestPermissionRationale(String packageName, String permissionName,
|
||||
int userId);
|
||||
|
||||
|
||||
@@ -1362,6 +1362,26 @@ public final class PermissionManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke the POST_NOTIFICATIONS permission, without killing the app. This method must ONLY BE
|
||||
* USED in CTS or local tests.
|
||||
*
|
||||
* @param packageName The package to be revoked
|
||||
* @param userId The user for which to revoke
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void revokePostNotificationPermissionWithoutKillForTest(@NonNull String packageName,
|
||||
int userId) {
|
||||
try {
|
||||
mPermissionManager.revokePostNotificationPermissionWithoutKillForTest(packageName,
|
||||
userId);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/* @hide */
|
||||
private static int checkPermissionUncached(@Nullable String permission, int pid, int uid) {
|
||||
final IActivityManager am = ActivityManager.getService();
|
||||
|
||||
@@ -4438,6 +4438,12 @@
|
||||
<permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS"
|
||||
android:protectionLevel="signature|installer|verifier" />
|
||||
|
||||
<!-- @TestApi Allows an application to revoke the POST_NOTIFICATIONS permission from an app
|
||||
without killing the app. Only granted to the shell.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- @SystemApi Allows the system to read runtime permission state.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.GET_RUNTIME_PERMISSIONS"
|
||||
|
||||
@@ -613,6 +613,9 @@
|
||||
<!-- Permission required for CTS test - CtsSafetyCenterTestCases -->
|
||||
<uses-permission android:name="android.permission.READ_SAFETY_CENTER_STATUS" />
|
||||
|
||||
<!-- Permission required for CTS test - Notification test suite -->
|
||||
<uses-permission android:name="android.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL" />
|
||||
|
||||
<application android:label="@string/app_label"
|
||||
android:theme="@android:style/Theme.DeviceDefault.DayNight"
|
||||
android:defaultToDeviceProtectedStorage="true"
|
||||
|
||||
@@ -548,6 +548,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId) {
|
||||
mPermissionManagerServiceImpl.revokePostNotificationPermissionWithoutKillForTest(
|
||||
packageName, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldShowRequestPermissionRationale(String packageName, String permissionName,
|
||||
int userId) {
|
||||
|
||||
@@ -170,6 +170,10 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
private static final String TAG = "PackageManager";
|
||||
private static final String LOG_TAG = PermissionManagerServiceImpl.class.getSimpleName();
|
||||
|
||||
private static final String SKIP_KILL_APP_REASON_NOTIFICATION_TEST = "skip permission revoke "
|
||||
+ "app kill for notification test";
|
||||
|
||||
|
||||
private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
|
||||
|
||||
// For automotive products, CarService enforces allow-listing of the privileged permissions
|
||||
@@ -326,11 +330,15 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
mPackageManagerInt.writeSettings(true);
|
||||
}
|
||||
@Override
|
||||
public void onPermissionRevoked(int uid, int userId, String reason) {
|
||||
public void onPermissionRevoked(int uid, int userId, String reason, boolean overrideKill) {
|
||||
mOnPermissionChangeListeners.onPermissionsChanged(uid);
|
||||
|
||||
// Critical; after this call the application should never have the permission
|
||||
mPackageManagerInt.writeSettings(false);
|
||||
if (overrideKill) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int appId = UserHandle.getAppId(uid);
|
||||
if (reason == null) {
|
||||
mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
|
||||
@@ -1445,9 +1453,29 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
reason, mDefaultPermissionCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final boolean overridePolicy =
|
||||
checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL, "");
|
||||
revokeRuntimePermissionInternal(packageName, Manifest.permission.POST_NOTIFICATIONS,
|
||||
overridePolicy, true, callingUid, userId,
|
||||
SKIP_KILL_APP_REASON_NOTIFICATION_TEST, mDefaultPermissionCallback);
|
||||
}
|
||||
|
||||
private void revokeRuntimePermissionInternal(String packageName, String permName,
|
||||
boolean overridePolicy, int callingUid, final int userId, String reason,
|
||||
PermissionCallback callback) {
|
||||
boolean overridePolicy, int callingUid, final int userId,
|
||||
String reason, PermissionCallback callback) {
|
||||
revokeRuntimePermissionInternal(packageName, permName, overridePolicy, false, callingUid,
|
||||
userId, reason, callback);
|
||||
}
|
||||
|
||||
private void revokeRuntimePermissionInternal(String packageName, String permName,
|
||||
boolean overridePolicy, boolean overrideKill, int callingUid, final int userId,
|
||||
String reason, PermissionCallback callback) {
|
||||
if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
|
||||
&& PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
|
||||
Log.i(TAG, "System is revoking " + packageName + " "
|
||||
@@ -1559,7 +1587,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
if (callback != null) {
|
||||
if (isRuntimePermission) {
|
||||
callback.onPermissionRevoked(UserHandle.getUid(userId, pkg.getUid()), userId,
|
||||
reason);
|
||||
reason, overrideKill);
|
||||
} else {
|
||||
mDefaultPermissionCallback.onInstallPermissionRevoked();
|
||||
}
|
||||
@@ -5232,7 +5260,11 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
public void onPermissionChanged() {}
|
||||
public void onPermissionGranted(int uid, @UserIdInt int userId) {}
|
||||
public void onInstallPermissionGranted() {}
|
||||
public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason) {}
|
||||
public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason) {
|
||||
onPermissionRevoked(uid, userId, reason, false);
|
||||
}
|
||||
public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason,
|
||||
boolean overrideKill) {}
|
||||
public void onInstallPermissionRevoked() {}
|
||||
public void onPermissionUpdated(@UserIdInt int[] updatedUserIds, boolean sync) {}
|
||||
public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
|
||||
|
||||
@@ -317,6 +317,15 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
|
||||
void revokeRuntimePermission(String packageName, String permName, int userId,
|
||||
String reason);
|
||||
|
||||
/**
|
||||
* Revoke the POST_NOTIFICATIONS permission, without killing the app. This method must ONLY BE
|
||||
* USED in CTS or local tests.
|
||||
*
|
||||
* @param packageName The package to be revoked
|
||||
* @param userId The user for which to revoke
|
||||
*/
|
||||
void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId);
|
||||
|
||||
/**
|
||||
* Get whether you should show UI with rationale for requesting a permission. You should do this
|
||||
* only if you do not have the permission and the context in which the permission is requested
|
||||
|
||||
Reference in New Issue
Block a user