Ensure transactional accounts cannot be call capable.
Similar to self-managed phone accounts, accounts with
CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS should also not be allowed
to have CAPABILITY_CALL_PROVIDER, CAPABILITY_CONNECTION_MANAGER, or
CAPABILITY_SIM_SUBSCRIPTION.
Test: Added new CTS test android.telecom.cts.PhoneAccountOperationsTest#testRegisterPhoneAccountBadCapabilitiesCombo
Fixes: 376936125
Flag: com.android.server.telecom.flags.enforce_transactional_exclusivity
Change-Id: If9f44c41f28ad1069021a95eab546b8bc478d1b4
diff --git a/flags/telecom_non_critical_security_flags.aconfig b/flags/telecom_non_critical_security_flags.aconfig
index 37929a8..e492073 100644
--- a/flags/telecom_non_critical_security_flags.aconfig
+++ b/flags/telecom_non_critical_security_flags.aconfig
@@ -7,4 +7,15 @@
namespace: "telecom"
description: "When set, Telecom will unregister accounts if the service is not resolvable"
bug: "281061708"
+}
+
+# OWNER=tgunn TARGET=25Q2
+flag {
+ name: "enforce_transactional_exclusivity"
+ namespace: "telecom"
+ description: "When set, ensure that transactional accounts cannot also be call capable"
+ bug: "376936125"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index f0423c3..796a62b 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -1284,12 +1284,15 @@
boolean isNewAccount;
// add self-managed capability for transactional accounts that are missing it
- if (hasTransactionalCallCapabilities(account) &&
- !account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
+ if (hasTransactionalCallCapabilities(account)
+ && !account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
account = account.toBuilder()
.setCapabilities(account.getCapabilities()
| PhoneAccount.CAPABILITY_SELF_MANAGED)
.build();
+ // Note: below we will automatically remove CAPABILITY_CONNECTION_MANAGER,
+ // CAPABILITY_CALL_PROVIDER, and CAPABILITY_SIM_SUBSCRIPTION if this magically becomes
+ // a self-managed phone account here.
}
PhoneAccount oldAccount = getPhoneAccountUnchecked(account.getAccountHandle());
@@ -1310,6 +1313,12 @@
if (account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
// Turn off bits we don't want to be able to set (TelecomServiceImpl protects against
// this but we'll also prevent it from happening here, just to be safe).
+ if ((account.getCapabilities() & (PhoneAccount.CAPABILITY_CALL_PROVIDER
+ | PhoneAccount.CAPABILITY_CONNECTION_MANAGER
+ | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) > 0) {
+ Log.w(this, "addOrReplacePhoneAccount: attempt to register a "
+ + "VoIP phone account with call provider/cm/sim sub capabilities.");
+ }
int newCapabilities = account.getCapabilities() &
~(PhoneAccount.CAPABILITY_CALL_PROVIDER |
PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index e6a6dd6..602f014 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -882,16 +882,20 @@
try {
enforcePhoneAccountModificationForPackage(
account.getAccountHandle().getComponentName().getPackageName());
- if (account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
+ if (account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
+ || (mFeatureFlags.enforceTransactionalExclusivity()
+ && account.hasCapabilities(
+ PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))) {
enforceRegisterSelfManaged();
if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) ||
account.hasCapabilities(
PhoneAccount.CAPABILITY_CONNECTION_MANAGER) ||
account.hasCapabilities(
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
- throw new SecurityException("Self-managed ConnectionServices " +
- "cannot also be call capable, connection managers, or " +
- "SIM accounts.");
+ throw new SecurityException("Self-managed ConnectionServices and "
+ + "transactional voip apps "
+ + "cannot also be call capable, connection managers, or "
+ + "SIM accounts.");
}
// For self-managed CS, the phone account registrar will override the