summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Benjamin Löhner <bloehner@google.com> 2024-01-26 14:38:06 +0000
committer Benjamin Löhner <bloehner@google.com> 2024-02-14 01:26:25 +0000
commit4675be8559d10d1fb60bfde9bfe4214ec5ad2c64 (patch)
tree0cf1a7e3b90d20329861cd115166d28cc6376cd4
parent516e07ac988a28443fb579ba945e82909c5de6d9 (diff)
Add getEmergencyRoleHolder SystemApi to RoleManager.
This API then enables TelephonyManager to expose the emergency role holder to priviliged clients via getEmergencyAssistancePackageName. Bug: 323157319 Test: atest RoleManagerTest LOW_COVERAGE_REASON=Flagged test added but flag not enabled Change-Id: I91089701248a32a720b488147405b2566cca2be9
-rw-r--r--framework-s/api/module-lib-current.txt1
-rw-r--r--framework-s/java/android/app/role/IRoleManager.aidl2
-rw-r--r--framework-s/java/android/app/role/RoleManager.java22
-rw-r--r--service/java/com/android/role/RoleService.java27
-rw-r--r--tests/cts/role/Android.bp2
-rw-r--r--tests/cts/role/src/android/app/role/cts/RoleManagerTest.java22
6 files changed, 75 insertions, 1 deletions
diff --git a/framework-s/api/module-lib-current.txt b/framework-s/api/module-lib-current.txt
index 14f71782e..97a8623b3 100644
--- a/framework-s/api/module-lib-current.txt
+++ b/framework-s/api/module-lib-current.txt
@@ -15,6 +15,7 @@ package android.app.role {
public final class RoleManager {
method @Nullable public String getBrowserRoleHolder(int);
+ method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyRoleHolder(int);
method @Nullable public String getSmsRoleHolder(int);
method @Nullable @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public boolean setBrowserRoleHolder(@Nullable String, int);
}
diff --git a/framework-s/java/android/app/role/IRoleManager.aidl b/framework-s/java/android/app/role/IRoleManager.aidl
index 0aef871e6..522967630 100644
--- a/framework-s/java/android/app/role/IRoleManager.aidl
+++ b/framework-s/java/android/app/role/IRoleManager.aidl
@@ -74,6 +74,8 @@ interface IRoleManager {
String getSmsRoleHolder(int userId);
+ String getEmergencyRoleHolder(int userId);
+
boolean isRoleVisibleAsUser(in String roleName, int userId);
boolean isApplicationVisibleForRoleAsUser(in String roleName, in String packageName,
diff --git a/framework-s/java/android/app/role/RoleManager.java b/framework-s/java/android/app/role/RoleManager.java
index fe27d50f3..4b8c9b388 100644
--- a/framework-s/java/android/app/role/RoleManager.java
+++ b/framework-s/java/android/app/role/RoleManager.java
@@ -975,6 +975,28 @@ public final class RoleManager {
}
/**
+ * Allows getting the role holder for {@link #ROLE_EMERGENCY} without requiring
+ * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}.
+ *
+ * @param userId the user ID to get the default emergency package for
+ * @return the package name of the default emergency app, or {@code null} if none
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @Nullable
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public String getEmergencyRoleHolder(@UserIdInt int userId) {
+ try {
+ return mService.getEmergencyRoleHolder(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Check whether a role should be visible to user.
*
* @param roleName name of the role to check for
diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java
index a2a6bab35..f441ce2f3 100644
--- a/service/java/com/android/role/RoleService.java
+++ b/service/java/com/android/role/RoleService.java
@@ -930,6 +930,33 @@ public class RoleService extends SystemService implements RoleUserState.Callback
}
@Override
+ public String getEmergencyRoleHolder(int userId) {
+ final Context context = getContext();
+ UserUtils.enforceCrossUserPermission(userId, false, "getEmergencyRoleHolder", context);
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return null;
+ }
+
+ getContext().enforceCallingOrSelfPermission(
+ Manifest.permission.READ_PRIVILEGED_PHONE_STATE, "getEmergencyRoleHolder");
+
+ final String packageName;
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ packageName = CollectionUtils.firstOrNull(getRoleHoldersAsUser(
+ RoleManager.ROLE_EMERGENCY, userId));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ if (packageName != null && !PackageUtils.canCallingOrSelfPackageQuery(packageName,
+ userId, context)) {
+ return null;
+ }
+ return packageName;
+ }
+
+ @Override
public boolean isRoleVisibleAsUser(@NonNull String roleName, @UserIdInt int userId) {
UserUtils.enforceCrossUserPermission(userId, false, "isRoleVisibleAsUser",
getContext());
diff --git a/tests/cts/role/Android.bp b/tests/cts/role/Android.bp
index cf6b7ee8c..2a312976b 100644
--- a/tests/cts/role/Android.bp
+++ b/tests/cts/role/Android.bp
@@ -32,8 +32,8 @@ android_test {
"androidx.test.rules",
"compatibility-device-util-axt",
"ctstestrunner-axt",
- "truth",
"platform-test-annotations",
+ "truth",
],
test_suites: [
diff --git a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
index c53718ba4..ee898d660 100644
--- a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
@@ -49,6 +49,7 @@ import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.provider.Telephony;
+import android.telephony.TelephonyManager;
import android.util.Pair;
import androidx.annotation.NonNull;
@@ -1103,6 +1104,27 @@ public class RoleManagerTest {
assertThat(Telephony.Sms.getDefaultSmsPackage(sContext)).isEqualTo(APP_PACKAGE_NAME);
}
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ codeName = "VanillaIceCream")
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED)
+ public void telephonyManagerGetEmergencyAssistancePackageNameBackedByRole() throws Exception {
+ TelephonyManager telephonyManager = sContext.getSystemService(TelephonyManager.class);
+ List<String> emergencyRoleHolders = getRoleHolders(RoleManager.ROLE_EMERGENCY);
+
+ if (callWithShellPermissionIdentity(() ->
+ telephonyManager.isEmergencyAssistanceEnabled())) {
+ String emergencyAssistancePackageName = callWithShellPermissionIdentity(() ->
+ telephonyManager.getEmergencyAssistancePackage());
+ assertThat(emergencyRoleHolders).hasSize(1);
+ assertThat(emergencyAssistancePackageName).isEqualTo(emergencyRoleHolders.get(0));
+ } else {
+ assertThrows(IllegalStateException.class, () ->
+ callWithShellPermissionIdentity(() ->
+ telephonyManager.getEmergencyAssistancePackage()));
+ }
+ }
+
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S, codeName = "S")
@Test
public void cannotBypassRoleQualificationWithoutPermission() throws Exception {