summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt1
-rw-r--r--framework-s/java/android/app/ecm/EnhancedConfirmationManager.java7
-rw-r--r--service/java/com/android/ecm/EnhancedConfirmationService.java55
-rw-r--r--tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationInCallTest.kt52
4 files changed, 80 insertions, 35 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt
index e2d46e519..952274d4a 100644
--- a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt
+++ b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt
@@ -55,7 +55,6 @@ 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
diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java
index 290388558..4248a429c 100644
--- a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java
+++ b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java
@@ -213,7 +213,7 @@ public final class EnhancedConfirmationManager {
* 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";
+ public static final String REASON_PACKAGE_RESTRICTED = "package_restricted";
/** A map of ECM states to their corresponding app op states */
@@ -367,8 +367,9 @@ public final class EnhancedConfirmationManager {
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()));
+ String restrictionReason = mService.getRestrictionReason(packageName,
+ settingIdentifier, UserHandle.getUserHandleForUid(uid).getIdentifier());
+ intent.putExtra(Intent.EXTRA_REASON, restrictionReason);
} 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
diff --git a/service/java/com/android/ecm/EnhancedConfirmationService.java b/service/java/com/android/ecm/EnhancedConfirmationService.java
index dde5404a4..46b5eedbc 100644
--- a/service/java/com/android/ecm/EnhancedConfirmationService.java
+++ b/service/java/com/android/ecm/EnhancedConfirmationService.java
@@ -16,7 +16,7 @@
package com.android.ecm;
-import static android.app.ecm.EnhancedConfirmationManager.REASON_APP_OP_RESTRICTED;
+import static android.app.ecm.EnhancedConfirmationManager.REASON_PACKAGE_RESTRICTED;
import static android.app.ecm.EnhancedConfirmationManager.REASON_PHONE_STATE;
import android.Manifest;
@@ -240,7 +240,7 @@ public class EnhancedConfirmationService extends SystemService {
int ECM_STATE_IMPLICIT = AppOpsManager.MODE_DEFAULT;
}
- private static final ArraySet<String> PROTECTED_SETTINGS = new ArraySet<>();
+ private static final ArraySet<String> PER_PACKAGE_PROTECTED_SETTINGS = new ArraySet<>();
// Settings restricted when an untrusted call is ongoing. These must also be added to
// PROTECTED_SETTINGS
@@ -248,28 +248,27 @@ public class EnhancedConfirmationService extends SystemService {
static {
// Runtime permissions
- PROTECTED_SETTINGS.add(Manifest.permission.SEND_SMS);
- PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_SMS);
- PROTECTED_SETTINGS.add(Manifest.permission.READ_SMS);
- PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_MMS);
- PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_WAP_PUSH);
- PROTECTED_SETTINGS.add(Manifest.permission.READ_CELL_BROADCASTS);
- PROTECTED_SETTINGS.add(Manifest.permission_group.SMS);
-
- PROTECTED_SETTINGS.add(Manifest.permission.BIND_DEVICE_ADMIN);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.SEND_SMS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_SMS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.READ_SMS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_MMS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_WAP_PUSH);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.READ_CELL_BROADCASTS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission_group.SMS);
+
+ PER_PACKAGE_PROTECTED_SETTINGS.add(Manifest.permission.BIND_DEVICE_ADMIN);
// App ops
- PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE);
- PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS);
- PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW);
- PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_GET_USAGE_STATS);
- PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_LOADER_USAGE_STATS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_GET_USAGE_STATS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_LOADER_USAGE_STATS);
// Default application roles.
- PROTECTED_SETTINGS.add(RoleManager.ROLE_DIALER);
- PROTECTED_SETTINGS.add(RoleManager.ROLE_SMS);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(RoleManager.ROLE_DIALER);
+ PER_PACKAGE_PROTECTED_SETTINGS.add(RoleManager.ROLE_SMS);
if (Flags.unknownCallPackageInstallBlockingEnabled()) {
// Requesting package installs, limited during phone calls
- PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES);
UNTRUSTED_CALL_RESTRICTED_SETTINGS.add(
AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES);
UNTRUSTED_CALL_RESTRICTED_SETTINGS.add(
@@ -312,11 +311,14 @@ public class EnhancedConfirmationService extends SystemService {
if (!isSettingEcmProtected(settingIdentifier)) {
return null;
}
+ if (isSettingEcmGuardedForPackage(settingIdentifier, packageName, userId)) {
+ return REASON_PACKAGE_RESTRICTED;
+ }
String globalProtectionReason = getGlobalProtectionReason(settingIdentifier);
if (globalProtectionReason != null) {
return globalProtectionReason;
}
- return isPackageEcmGuarded(packageName, userId) ? REASON_APP_OP_RESTRICTED : null;
+ return null;
} catch (NameNotFoundException e) {
throw new IllegalArgumentException(e);
}
@@ -448,6 +450,14 @@ public class EnhancedConfirmationService extends SystemService {
|| isAllowlistedInstaller(installingPackageName));
}
+ private boolean isSettingEcmGuardedForPackage(@NonNull String settingIdentifier,
+ @NonNull String packageName, @UserIdInt int userId) throws NameNotFoundException {
+ if (!PER_PACKAGE_PROTECTED_SETTINGS.contains(settingIdentifier)) {
+ return false;
+ }
+ return isPackageEcmGuarded(packageName, userId);
+ }
+
private boolean isAllowlistedPackage(String packageName) {
return isPackageSignedWithAnyOf(packageName,
mTrustedPackageCertDigests.get(packageName));
@@ -518,7 +528,10 @@ public class EnhancedConfirmationService extends SystemService {
return false;
}
- if (PROTECTED_SETTINGS.contains(settingIdentifier)) {
+ if (PER_PACKAGE_PROTECTED_SETTINGS.contains(settingIdentifier)) {
+ return true;
+ }
+ if (UNTRUSTED_CALL_RESTRICTED_SETTINGS.contains(settingIdentifier)) {
return true;
}
// TODO(b/310218979): Add role selections as protected settings
diff --git a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationInCallTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationInCallTest.kt
index 16a27c9a8..9a4908c79 100644
--- a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationInCallTest.kt
+++ b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationInCallTest.kt
@@ -24,6 +24,7 @@ import android.content.Context
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
+import android.os.Process
import android.permission.flags.Flags
import android.platform.test.annotations.AppModeFull
import android.platform.test.annotations.RequiresFlagsEnabled
@@ -56,8 +57,11 @@ import org.junit.Test
// @CddTest(requirement = "TBD")
class EnhancedConfirmationInCallTest {
private val ecm = context.getSystemService(EnhancedConfirmationManager::class.java)!!
+ private val aom = context.getSystemService(AppOpsManager::class.java)!!
private val packageManager = context.packageManager
private val addedContacts = mutableMapOf<String, List<Uri>>()
+ private val phoneOnlyRestrictedSetting = AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES
+ private val phoneAndEcmRestrictedSetting = AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES
@JvmField
@Rule
@@ -149,20 +153,32 @@ class EnhancedConfirmationInCallTest {
fun tearDown() {
voipService.endCallAndWaitForInactive()
addedContacts.keys.forEach { removeContact(it) }
+ runWithShellPermissionIdentity {
+ aom.setUidMode(
+ AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS,
+ Process.myUid(),
+ AppOpsManager.MODE_ALLOWED,
+ )
+ }
}
- private fun isSettingRestricted(): Boolean {
+ private fun isSettingRestricted(settingsIdentifier: String): Boolean {
return callWithShellPermissionIdentity {
- ecm.isRestricted(context.packageName, AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES)
+ ecm.isRestricted(context.packageName, settingsIdentifier)
}
}
+ private fun areSettingsRestricted(): Boolean {
+ return isSettingRestricted(phoneOnlyRestrictedSetting) &&
+ isSettingRestricted(phoneAndEcmRestrictedSetting)
+ }
+
@Test
fun testIncomingCall_NonContact() {
voipService.createCallAndWaitForActive(NON_CONTACT_DISPLAY_NAME, NON_CONTACT_PHONE_NUMBER)
- Assert.assertTrue(isSettingRestricted())
+ Assert.assertTrue(areSettingsRestricted())
voipService.endCallAndWaitForInactive()
- Assert.assertFalse(isSettingRestricted())
+ Assert.assertFalse(areSettingsRestricted())
}
@Test
@@ -170,9 +186,9 @@ class EnhancedConfirmationInCallTest {
addContact(CONTACT_DISPLAY_NAME, CONTACT_PHONE_NUMBER)
// If no phone number is given, the display name will be checked
voipService.createCallAndWaitForActive(CONTACT_DISPLAY_NAME, CONTACT_PHONE_NUMBER)
- Assert.assertFalse(isSettingRestricted())
+ Assert.assertFalse(areSettingsRestricted())
voipService.endCallAndWaitForInactive()
- Assert.assertFalse(isSettingRestricted())
+ Assert.assertFalse(areSettingsRestricted())
}
@Test
@@ -180,9 +196,9 @@ class EnhancedConfirmationInCallTest {
addContact(CONTACT_DISPLAY_NAME, CONTACT_PHONE_NUMBER)
// If the phone number matches, the display name is not checked
voipService.createCallAndWaitForActive(NON_CONTACT_DISPLAY_NAME, CONTACT_PHONE_NUMBER)
- Assert.assertFalse(isSettingRestricted())
+ Assert.assertFalse(areSettingsRestricted())
voipService.endCallAndWaitForInactive()
- Assert.assertFalse(isSettingRestricted())
+ Assert.assertFalse(areSettingsRestricted())
}
@Test
@@ -192,10 +208,26 @@ class EnhancedConfirmationInCallTest {
voipService.createCallAndWaitForActive(tempContactDisplay, tempContactPhone)
addContact(tempContactDisplay, tempContactPhone)
// State should not be recomputed just because the contact is newly added
- Assert.assertTrue(isSettingRestricted())
+ Assert.assertTrue(areSettingsRestricted())
voipService.endCallAndWaitForInactive()
voipService.createCallAndWaitForActive(tempContactDisplay, tempContactPhone)
// A new call should recognize our contact, and mark the call as trusted
- Assert.assertFalse(isSettingRestricted())
+ Assert.assertFalse(areSettingsRestricted())
+ }
+
+ @Test
+ fun testCallOnlyRestrictedSetting_notRestrictedIfEcmSet() {
+ // Set the current app to be restricted by ECM
+ runWithShellPermissionIdentity {
+ aom.setUidMode(
+ AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS,
+ Process.myUid(),
+ AppOpsManager.MODE_ERRORED,
+ )
+ }
+ // The ecm and phone restricted setting is restricted
+ Assert.assertFalse(isSettingRestricted(phoneOnlyRestrictedSetting))
+ // But the phone only restriction is not
+ Assert.assertFalse(isSettingRestricted(phoneAndEcmRestrictedSetting))
}
}