fix TelecomManager#getters for transactional accounts

Currently, if an application registers accounts with
CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS and tries to fetch
the account via a TelecomManager#getter, the account will not be
returned.

The bug is a result of the check in
PhoneAccountRegistrar#resolveComponent that ensures there is a valid
ConnectionService for the application fetching the accounts.

In U, applications that utilize accounts with
CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS do not need to create a
ConnectionService.  Therefore, this check should be bypassed for such
accounts.

Fixes: 266873410
Test: testFetchingTransactionalAccounts + manual
Change-Id: I7c4ba664230547bc7145c79d874bec3507101feb
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 3c6934a..8a29955 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -873,7 +873,7 @@
     public void registerPhoneAccount(PhoneAccount account) {
         // Enforce the requirement that a connection service for a phone account has the correct
         // permission.
-        if (!hasTransactionalCallCapabilites(account) &&
+        if (!hasTransactionalCallCapabilities(account) &&
                 !phoneAccountRequiresBindPermission(account.getAccountHandle())) {
             Log.w(this,
                     "Phone account %s does not have BIND_TELECOM_CONNECTION_SERVICE permission.",
@@ -1062,7 +1062,7 @@
         boolean isNewAccount;
 
         // add self-managed capability for transactional accounts that are missing it
-        if (hasTransactionalCallCapabilites(account) &&
+        if (hasTransactionalCallCapabilities(account) &&
                 !account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
             account = account.toBuilder()
                     .setCapabilities(account.getCapabilities()
@@ -1367,13 +1367,13 @@
      * @return {@code True} if the phone account has permission.
      */
     public boolean phoneAccountRequiresBindPermission(PhoneAccountHandle phoneAccountHandle) {
-        List<ResolveInfo> resolveInfos = resolveComponent(phoneAccountHandle);
-        if (resolveInfos.isEmpty()) {
-            Log.w(this, "phoneAccount %s not found", phoneAccountHandle.getComponentName());
+        if (hasTransactionalCallCapabilities(getPhoneAccountUnchecked(phoneAccountHandle))) {
             return false;
         }
 
-        if (hasTransactionalCallCapabilites(getPhoneAccountUnchecked(phoneAccountHandle))) {
+        List<ResolveInfo> resolveInfos = resolveComponent(phoneAccountHandle);
+        if (resolveInfos.isEmpty()) {
+            Log.w(this, "phoneAccount %s not found", phoneAccountHandle.getComponentName());
             return false;
         }
 
@@ -1396,7 +1396,7 @@
     }
 
     @VisibleForTesting
-    public boolean hasTransactionalCallCapabilites(PhoneAccount phoneAccount) {
+    public boolean hasTransactionalCallCapabilities(PhoneAccount phoneAccount) {
         if (phoneAccount == null) {
             return false;
         }
@@ -1530,7 +1530,10 @@
             }
             PhoneAccountHandle handle = m.getAccountHandle();
 
-            if (resolveComponent(handle).isEmpty()) {
+            // PhoneAccounts with CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS do not require a
+            // ConnectionService and will fail [resolveComponent(PhoneAccountHandle)]. Bypass
+            // the [resolveComponent(PhoneAccountHandle)] for transactional accounts.
+            if (!hasTransactionalCallCapabilities(m) && resolveComponent(handle).isEmpty()) {
                 // This component cannot be resolved anymore; skip this one.
                 continue;
             }
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index cef032f..e573bb8 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -23,8 +23,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyObject;
-import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
@@ -707,7 +705,7 @@
                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
                 .build();
 
-        assertFalse(mRegistrar.hasTransactionalCallCapabilites(accountWithoutCapability));
+        assertFalse(mRegistrar.hasTransactionalCallCapabilities(accountWithoutCapability));
 
         try {
             mRegistrar.registerPhoneAccount(accountWithoutCapability);
@@ -730,7 +728,7 @@
                         PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS)
                 .build();
 
-        assertTrue(mRegistrar.hasTransactionalCallCapabilites(accountWithCapability));
+        assertTrue(mRegistrar.hasTransactionalCallCapabilities(accountWithCapability));
 
         try {
             mRegistrar.registerPhoneAccount(accountWithCapability);
@@ -752,7 +750,7 @@
                         PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS)
                 .build();
 
-        assertTrue(mRegistrar.hasTransactionalCallCapabilites(accountWithCapability));
+        assertTrue(mRegistrar.hasTransactionalCallCapabilities(accountWithCapability));
 
         try {
             // WHEN
@@ -1684,6 +1682,24 @@
         }
     }
 
+    /**
+     * PhoneAccounts with CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS do not require a
+     * ConnectionService. Ensure that such an account can be registered and fetched.
+     */
+    @Test
+    public void testFetchingTransactionalAccounts() {
+        PhoneAccount account = makeBuilderWithBindCapabilities(
+                makeQuickAccountHandle(TEST_ID)).build();
+
+        try {
+            assertEquals(0, mRegistrar.getAllPhoneAccounts(null, true).size());
+            registerAndEnableAccount(account);
+            assertEquals(1, mRegistrar.getAllPhoneAccounts(null, true).size());
+        } finally {
+            mRegistrar.unregisterPhoneAccount(account.getAccountHandle());
+        }
+    }
+
     private static PhoneAccount.Builder makeBuilderWithBindCapabilities(PhoneAccountHandle handle) {
         return new PhoneAccount.Builder(handle, TEST_LABEL)
                 .setCapabilities(PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS);