Merge "Add information to grant permissions intent for continue messages"
This commit is contained in:
@@ -3321,6 +3321,7 @@ package android.content.pm {
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>);
|
||||
field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
|
||||
field public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER";
|
||||
field public static final String EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES";
|
||||
field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
|
||||
field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
|
||||
field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
|
||||
|
||||
@@ -2061,7 +2061,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);
|
||||
method @RequiresPermission(android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL) public void revokePostNotificationPermissionWithoutKillForTest(@NonNull String, int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4341,6 +4341,21 @@ public abstract class PackageManager {
|
||||
public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS
|
||||
= "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
|
||||
|
||||
/**
|
||||
* Indicates that the package requesting permissions has legacy access for some permissions,
|
||||
* or had it, but it was recently revoked. These request dialogs may show different text,
|
||||
* indicating that the app is requesting continued access to a permission. Will be cleared
|
||||
* from any permission request intent, if set by a non-system server app.
|
||||
* <p>
|
||||
* <strong>Type:</strong> String[]
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES
|
||||
= "android.content.pm.extra.REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES";
|
||||
|
||||
/**
|
||||
* String extra for {@link PackageInstallObserver} in the 'extras' Bundle in case of
|
||||
* {@link #INSTALL_FAILED_DUPLICATE_PERMISSION}. This extra names the package which provides
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
|
||||
package android.permission;
|
||||
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
|
||||
import static android.os.Build.VERSION_CODES.S;
|
||||
|
||||
import android.Manifest;
|
||||
@@ -106,6 +112,16 @@ public final class PermissionManager {
|
||||
*/
|
||||
public static final int PERMISSION_HARD_DENIED = 2;
|
||||
|
||||
/**
|
||||
* The set of flags that indicate that a permission state has been explicitly set
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int EXPLICIT_SET_FLAGS = FLAG_PERMISSION_USER_SET
|
||||
| FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_POLICY_FIXED
|
||||
| FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_GRANTED_BY_DEFAULT
|
||||
| FLAG_PERMISSION_GRANTED_BY_ROLE;
|
||||
|
||||
/**
|
||||
* Activity action: Launch UI to review permission decisions.
|
||||
* <p>
|
||||
@@ -1447,6 +1463,7 @@ public final class PermissionManager {
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL)
|
||||
public void revokePostNotificationPermissionWithoutKillForTest(@NonNull String packageName,
|
||||
int userId) {
|
||||
try {
|
||||
|
||||
@@ -179,7 +179,7 @@ public final class PermissionHelper {
|
||||
assertFlag();
|
||||
final long callingId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if (grant) {
|
||||
if (grant && !reviewRequired) {
|
||||
mPermManager.grantRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId);
|
||||
} else {
|
||||
mPermManager.revokeRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId,
|
||||
@@ -210,8 +210,10 @@ public final class PermissionHelper {
|
||||
if (pkgPerm == null || pkgPerm.packageName == null) {
|
||||
return;
|
||||
}
|
||||
setNotificationPermission(pkgPerm.packageName, pkgPerm.userId, pkgPerm.granted,
|
||||
pkgPerm.userSet, !pkgPerm.userSet);
|
||||
if (!isPermissionFixed(pkgPerm.packageName, pkgPerm.userId)) {
|
||||
setNotificationPermission(pkgPerm.packageName, pkgPerm.userId, pkgPerm.granted,
|
||||
pkgPerm.userSet, !pkgPerm.userSet);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPermissionFixed(String packageName, @UserIdInt int userId) {
|
||||
@@ -239,7 +241,8 @@ public final class PermissionHelper {
|
||||
try {
|
||||
int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
|
||||
userId);
|
||||
return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
|
||||
return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
|
||||
| PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Could not reach system server", e);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.pm.permission;
|
||||
|
||||
import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
|
||||
import static android.Manifest.permission.POST_NOTIFICATIONS;
|
||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
|
||||
@@ -752,11 +753,14 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
|
||||
flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||
flagValues &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
|
||||
flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
|
||||
flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
|
||||
// REVIEW_REQUIRED can only be set by non-system apps for for POST_NOTIFICATIONS
|
||||
if (!POST_NOTIFICATIONS.equals(permName)) {
|
||||
flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
|
||||
|
||||
@@ -37,7 +37,7 @@ import android.app.AppOpsManagerInternal;
|
||||
import android.app.TaskInfo;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.EnabledAfter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@@ -58,6 +58,7 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.permission.PermissionControllerManager;
|
||||
import android.permission.PermissionManager;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Telephony;
|
||||
import android.telecom.TelecomManager;
|
||||
@@ -141,7 +142,7 @@ public final class PermissionPolicyService extends SystemService {
|
||||
* This change reflects the presence of the new Notification Permission
|
||||
*/
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
|
||||
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2)
|
||||
private static final long NOTIFICATION_PERM_CHANGE_ID = 194833441L;
|
||||
|
||||
private List<String> mAppOpPermissions;
|
||||
@@ -149,7 +150,6 @@ public final class PermissionPolicyService extends SystemService {
|
||||
private Context mContext;
|
||||
private PackageManagerInternal mPackageManagerInternal;
|
||||
private NotificationManagerInternal mNotificationManager;
|
||||
private PermissionManagerServiceInternal mPermissionManagerService;
|
||||
private final PackageManager mPackageManager;
|
||||
|
||||
public PermissionPolicyService(@NonNull Context context) {
|
||||
@@ -1001,13 +1001,48 @@ public final class PermissionPolicyService extends SystemService {
|
||||
|
||||
private class Internal extends PermissionPolicyInternal {
|
||||
|
||||
private ActivityInterceptorCallback mActivityInterceptorCallback =
|
||||
// UIDs that, if a grant dialog is shown for POST_NOTIFICATIONS before next reboot,
|
||||
// should display a "continue allowing" message, rather than an "allow" message
|
||||
private final ArraySet<Integer> mContinueNotifGrantMessageUids = new ArraySet<>();
|
||||
|
||||
private final ActivityInterceptorCallback mActivityInterceptorCallback =
|
||||
new ActivityInterceptorCallback() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ActivityInterceptorCallback.ActivityInterceptResult intercept(
|
||||
ActivityInterceptorInfo info) {
|
||||
return null;
|
||||
String action = info.intent.getAction();
|
||||
ActivityInterceptResult result = null;
|
||||
if (!PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)
|
||||
&& !PackageManager.ACTION_REQUEST_PERMISSIONS.equals(action)) {
|
||||
return null;
|
||||
}
|
||||
// Only this interceptor can add LEGACY_ACCESS_PERMISSION_NAMES
|
||||
if (info.intent.getStringArrayExtra(PackageManager
|
||||
.EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES)
|
||||
!= null) {
|
||||
result = new ActivityInterceptResult(
|
||||
new Intent(info.intent), info.checkedOptions);
|
||||
result.intent.removeExtra(PackageManager
|
||||
.EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES);
|
||||
}
|
||||
if (PackageManager.ACTION_REQUEST_PERMISSIONS.equals(action)
|
||||
&& !mContinueNotifGrantMessageUids.contains(info.realCallingUid)) {
|
||||
return result;
|
||||
}
|
||||
if (PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(action)) {
|
||||
String otherPkg = info.intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
|
||||
if (otherPkg == null || (mPackageManager.getPermissionFlags(
|
||||
POST_NOTIFICATIONS, otherPkg, UserHandle.of(info.userId))
|
||||
& FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
mContinueNotifGrantMessageUids.remove(info.realCallingUid);
|
||||
return new ActivityInterceptResult(info.intent.putExtra(PackageManager
|
||||
.EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES,
|
||||
new String[] { POST_NOTIFICATIONS }), info.checkedOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1057,12 +1092,21 @@ public final class PermissionPolicyService extends SystemService {
|
||||
launchNotificationPermissionRequestDialog(packageName, user, taskId);
|
||||
}
|
||||
|
||||
private void clearNotificationReviewFlagsIfNeeded(String packageName, UserHandle userId) {
|
||||
if (!CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID, packageName, userId)) {
|
||||
private void clearNotificationReviewFlagsIfNeeded(String packageName, UserHandle user) {
|
||||
if (!CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID, packageName, user)
|
||||
|| ((mPackageManager.getPermissionFlags(POST_NOTIFICATIONS, packageName, user)
|
||||
& FLAG_PERMISSION_REVIEW_REQUIRED) == 0)) {
|
||||
return;
|
||||
}
|
||||
mPackageManager.updatePermissionFlags(POST_NOTIFICATIONS, packageName,
|
||||
FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
|
||||
try {
|
||||
int uid = mPackageManager.getPackageUidAsUser(packageName, 0,
|
||||
user.getIdentifier());
|
||||
mContinueNotifGrantMessageUids.add(uid);
|
||||
mPackageManager.updatePermissionFlags(POST_NOTIFICATIONS, packageName,
|
||||
FLAG_PERMISSION_REVIEW_REQUIRED, 0, user);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private void launchNotificationPermissionRequestDialog(String pkgName, UserHandle user,
|
||||
@@ -1142,8 +1186,10 @@ public final class PermissionPolicyService extends SystemService {
|
||||
if (pkg == null || pkg.getPackageName() == null
|
||||
|| Objects.equals(pkgName, mPackageManager.getPermissionControllerPackageName())
|
||||
|| pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
|
||||
Slog.w(LOG_TAG, "Cannot check for Notification prompt, no package for "
|
||||
+ pkgName + " or pkg is Permission Controller");
|
||||
if (pkg == null) {
|
||||
Slog.w(LOG_TAG, "Cannot check for Notification prompt, no package for "
|
||||
+ pkgName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1175,9 +1221,10 @@ public final class PermissionPolicyService extends SystemService {
|
||||
}
|
||||
boolean hasCreatedNotificationChannels = mNotificationManager
|
||||
.getNumNotificationChannelsForPackage(pkg.getPackageName(), uid, true) > 0;
|
||||
boolean needsReview = (mPackageManager.getPermissionFlags(POST_NOTIFICATIONS, pkgName,
|
||||
user) & FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
|
||||
return hasCreatedNotificationChannels && needsReview;
|
||||
int flags = mPackageManager.getPermissionFlags(POST_NOTIFICATIONS, pkgName, user);
|
||||
boolean explicitlySet = (flags & PermissionManager.EXPLICIT_SET_FLAGS) != 0;
|
||||
boolean needsReview = (flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
|
||||
return hasCreatedNotificationChannels && (needsReview || !explicitlySet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,8 +233,8 @@ public class PermissionHelperTest extends UiServiceTestCase {
|
||||
public void testSetNotificationPermission_grantReviewRequired() throws Exception {
|
||||
mPermissionHelper.setNotificationPermission("pkg", 10, true, false, true);
|
||||
|
||||
verify(mPermManager).grantRuntimePermission(
|
||||
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
|
||||
verify(mPermManager).revokeRuntimePermission(
|
||||
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10, "PermissionHelper");
|
||||
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
|
||||
FLAG_PERMISSION_REVIEW_REQUIRED, FLAG_PERMISSION_REVIEW_REQUIRED, true, 10);
|
||||
}
|
||||
@@ -245,8 +245,8 @@ public class PermissionHelperTest extends UiServiceTestCase {
|
||||
"pkg", 10, true, false);
|
||||
mPermissionHelper.setNotificationPermission(pkgPerm);
|
||||
|
||||
verify(mPermManager).grantRuntimePermission(
|
||||
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
|
||||
verify(mPermManager).revokeRuntimePermission(
|
||||
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10, "PermissionHelper");
|
||||
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
|
||||
FLAG_PERMISSION_REVIEW_REQUIRED, FLAG_PERMISSION_REVIEW_REQUIRED, true, 10);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user