diff options
4 files changed, 58 insertions, 17 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt index e6cf094e3..e2d46e519 100644 --- a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt +++ b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt @@ -18,7 +18,6 @@ package com.android.permissioncontroller.ecm import android.annotation.SuppressLint import android.app.AlertDialog -import android.app.AppOpsManager import android.app.Dialog import android.app.ecm.EnhancedConfirmationManager import android.content.Context @@ -55,6 +54,8 @@ import com.android.role.controller.model.Roles class EnhancedConfirmationDialogActivity : FragmentActivity() { companion object { private const val KEY_WAS_CLEAR_RESTRICTION_ALLOWED = "KEY_WAS_CLEAR_RESTRICTION_ALLOWED" + private const val REASON_PHONE_STATE = "phone_state" + private const val REASON_APP_OP_RESTRICTED = "app_op_restricted" } private var wasClearRestrictionAllowed: Boolean = false @@ -77,6 +78,7 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { val packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME) val settingIdentifier = intent.getStringExtra(Intent.EXTRA_SUBJECT) val isEcmInApp = intent.getBooleanExtra(EXTRA_IS_ECM_IN_APP, false) + val reason = intent.getStringExtra(Intent.EXTRA_REASON) require(uid != Process.INVALID_UID) { "EXTRA_UID cannot be null or invalid" } require(!packageName.isNullOrEmpty()) { "EXTRA_PACKAGE_NAME cannot be null or empty" } @@ -84,9 +86,9 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { wasClearRestrictionAllowed = setClearRestrictionAllowed(packageName, UserHandle.getUserHandleForUid(uid)) - val setting = Setting.fromIdentifier(this, settingIdentifier, isEcmInApp) + val setting = Setting.fromIdentifier(this, settingIdentifier, isEcmInApp, reason) if ( - SettingType.fromIdentifier(this, settingIdentifier, isEcmInApp) == + SettingType.fromIdentifier(this, settingIdentifier, isEcmInApp, reason) == SettingType.BLOCKED_DUE_TO_PHONE_STATE && !Flags.unknownCallPackageInstallBlockingEnabled() ) { @@ -127,8 +129,10 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { context: Context, settingIdentifier: String, isEcmInApp: Boolean, + reason: String?, ): Setting { - val settingType = SettingType.fromIdentifier(context, settingIdentifier, isEcmInApp) + val settingType = + SettingType.fromIdentifier(context, settingIdentifier, isEcmInApp, reason) val label = when (settingType) { SettingType.PLATFORM_PERMISSION -> @@ -189,10 +193,10 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { context: Context, settingIdentifier: String, isEcmInApp: Boolean, + restrictionReason: String?, ): SettingType { return when { - settingIdentifier == AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES -> - BLOCKED_DUE_TO_PHONE_STATE + restrictionReason == REASON_PHONE_STATE -> BLOCKED_DUE_TO_PHONE_STATE !isEcmInApp -> OTHER PermissionMapping.isRuntimePlatformPermission(settingIdentifier) && PermissionMapping.getGroupOfPlatformPermission(settingIdentifier) != null -> diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java index db05a0af6..290388558 100644 --- a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java +++ b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java @@ -33,6 +33,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.RemoteException; +import android.os.UserHandle; import android.permission.flags.Flags; import android.util.ArraySet; @@ -202,6 +203,19 @@ public final class EnhancedConfirmationManager { public static final String ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG = "android.app.ecm.action.SHOW_ECM_RESTRICTED_SETTING_DIALOG"; + /** + * The setting is restricted because of the phone state of the device + * @hide + */ + public static final String REASON_PHONE_STATE = "phone_state"; + + /** + * The setting is restricted because the restricted app op is set for the given package + * @hide + */ + public static final String REASON_APP_OP_RESTRICTED = "app_op_restricted"; + + /** A map of ECM states to their corresponding app op states */ @Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix = {"ECM_STATE_"}, value = {EcmState.ECM_STATE_NOT_GUARDED, @@ -349,8 +363,16 @@ public final class EnhancedConfirmationManager { @NonNull String settingIdentifier) throws NameNotFoundException { Intent intent = new Intent(ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); - intent.putExtra(Intent.EXTRA_UID, getPackageUid(packageName)); + int uid = getPackageUid(packageName); + intent.putExtra(Intent.EXTRA_UID, uid); intent.putExtra(Intent.EXTRA_SUBJECT, settingIdentifier); + try { + intent.putExtra(Intent.EXTRA_REASON, mService.getRestrictionReason(packageName, + settingIdentifier, UserHandle.getUserHandleForUid(uid).getIdentifier())); + } catch (SecurityException | RemoteException e) { + // The caller of this method does not have permission to read the ECM state, so we + // won't include it in the return + } return intent; } diff --git a/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl b/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl index 5149daa49..79d2322bd 100644 --- a/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl +++ b/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl @@ -25,6 +25,8 @@ interface IEnhancedConfirmationManager { boolean isRestricted(in String packageName, in String settingIdentifier, int userId); + String getRestrictionReason(in String packageName, in String settingIdentifier, int userId); + void clearRestriction(in String packageName, int userId); boolean isClearRestrictionAllowed(in String packageName, int userId); diff --git a/service/java/com/android/ecm/EnhancedConfirmationService.java b/service/java/com/android/ecm/EnhancedConfirmationService.java index 65fde6daf..dde5404a4 100644 --- a/service/java/com/android/ecm/EnhancedConfirmationService.java +++ b/service/java/com/android/ecm/EnhancedConfirmationService.java @@ -16,6 +16,9 @@ package com.android.ecm; +import static android.app.ecm.EnhancedConfirmationManager.REASON_APP_OP_RESTRICTED; +import static android.app.ecm.EnhancedConfirmationManager.REASON_PHONE_STATE; + import android.Manifest; import android.annotation.FlaggedApi; import android.annotation.IntDef; @@ -89,7 +92,7 @@ public class EnhancedConfirmationService extends SystemService { private static final int CALL_TYPE_UNTRUSTED = 0; private static final int CALL_TYPE_TRUSTED = 1; - private static final int CALL_TYPE_EMERGENCY = 2; + private static final int CALL_TYPE_EMERGENCY = 1 << 1; @IntDef(flag = true, value = { CALL_TYPE_UNTRUSTED, CALL_TYPE_TRUSTED, @@ -269,6 +272,8 @@ public class EnhancedConfirmationService extends SystemService { PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES); UNTRUSTED_CALL_RESTRICTED_SETTINGS.add( AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES); + UNTRUSTED_CALL_RESTRICTED_SETTINGS.add( + AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE); } } @@ -287,10 +292,16 @@ public class EnhancedConfirmationService extends SystemService { public boolean isRestricted(@NonNull String packageName, @NonNull String settingIdentifier, @UserIdInt int userId) { + return getRestrictionReason(packageName, settingIdentifier, userId) != null; + } + + public String getRestrictionReason(@NonNull String packageName, + @NonNull String settingIdentifier, + @UserIdInt int userId) { enforcePermissions("isRestricted", userId); if (!UserUtils.isUserExistent(userId, getContext())) { Log.e(LOG_TAG, "user " + userId + " does not exist"); - return false; + return null; } Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); @@ -299,12 +310,13 @@ public class EnhancedConfirmationService extends SystemService { try { if (!isSettingEcmProtected(settingIdentifier)) { - return false; + return null; } - if (isSettingProtectedGlobally(settingIdentifier)) { - return true; + String globalProtectionReason = getGlobalProtectionReason(settingIdentifier); + if (globalProtectionReason != null) { + return globalProtectionReason; } - return isPackageEcmGuarded(packageName, userId); + return isPackageEcmGuarded(packageName, userId) ? REASON_APP_OP_RESTRICTED : null; } catch (NameNotFoundException e) { throw new IllegalArgumentException(e); } @@ -513,12 +525,13 @@ public class EnhancedConfirmationService extends SystemService { return false; } - private boolean isSettingProtectedGlobally(@NonNull String settingIdentifier) { - if (UNTRUSTED_CALL_RESTRICTED_SETTINGS.contains(settingIdentifier)) { - return isUntrustedCallOngoing(); + private String getGlobalProtectionReason(@NonNull String settingIdentifier) { + if (UNTRUSTED_CALL_RESTRICTED_SETTINGS.contains(settingIdentifier) + && isUntrustedCallOngoing()) { + return REASON_PHONE_STATE; } - return false; + return null; } @Nullable |