[automerger skipped] enforce stricter rules when registering phoneAccounts am: 643089ac49 -s ours

am skip reason: Merged-In I5eb2a127a44d5ec725d0ba39cb0ef478b12013de with SHA-1 f07776bc42 is already in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telecomm/+/21184327

Change-Id: I0d4e85365befa4b2d247e403ed533f85d460f0fc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/com/android/server/telecom/CallScreeningServiceHelper.java b/src/com/android/server/telecom/CallScreeningServiceHelper.java
index 9435250..338aa19 100644
--- a/src/com/android/server/telecom/CallScreeningServiceHelper.java
+++ b/src/com/android/server/telecom/CallScreeningServiceHelper.java
@@ -137,6 +137,23 @@
                                 "Cancelling outgoing call screen due to service disconnect.");
                     }
                     mFuture.complete(null);
+                    mContext.unbindService(this);
+                } finally {
+                    Log.endSession();
+                }
+            }
+
+            @Override
+            public void onNullBinding(ComponentName name) {
+                // No locking needed -- CompletableFuture only lets one thread call complete.
+                Log.continueSession(mLoggingSession, "CSSH.oNB");
+                try {
+                    if (!mFuture.isDone()) {
+                        Log.w(CallScreeningServiceHelper.this,
+                                "Cancelling outgoing call screen due to null binding.");
+                    }
+                    mFuture.complete(null);
+                    mContext.unbindService(this);
                 } finally {
                     Log.endSession();
                 }
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index 86fedd5..4569950 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -314,8 +314,18 @@
     }
 
     private String getNumberFromCallIntent(Intent intent) {
-        String number;
-        number = mPhoneNumberUtilsAdapter.getNumberFromIntent(intent, mContext);
+        String number = null;
+
+        Uri uri = intent.getData();
+        if (uri != null) {
+            String scheme = uri.getScheme();
+            if (scheme != null) {
+                if (scheme.equals("tel") || scheme.equals("sip")) {
+                    number = uri.getSchemeSpecificPart();
+                }
+            }
+        }
+
         if (TextUtils.isEmpty(number)) {
             Log.w(this, "Empty number obtained from the call intent.");
             return null;
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index baf7983..fab03b1 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -822,7 +822,6 @@
             throw new SecurityException("PhoneAccount connection service requires "
                     + "BIND_TELECOM_CONNECTION_SERVICE permission.");
         }
-
         enforceCharacterLimit(account);
         enforceIconSizeLimit(account);
         enforceMaxPhoneAccountLimit(account);
@@ -892,6 +891,7 @@
         String[] fields =
                 {"Package Name", "Class Name", "PhoneAccountHandle Id", "Label", "ShortDescription",
                         "GroupId", "Address", "SubscriptionAddress"};
+
         CharSequence[] args = {handle.getComponentName().getPackageName(),
                 handle.getComponentName().getClassName(), handle.getId(), account.getLabel(),
                 account.getShortDescription(), account.getGroupId(),
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index af77288..66cb6c9 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -1475,6 +1475,7 @@
                 enforceCallingPackage(callingPackage);
 
                 PhoneAccountHandle phoneAccountHandle = null;
+                boolean clearPhoneAccountHandleExtra = false;
                 if (extras != null) {
                     phoneAccountHandle = extras.getParcelable(
                             TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
@@ -1486,17 +1487,24 @@
                 boolean isSelfManaged = phoneAccountHandle != null &&
                         isSelfManagedConnectionService(phoneAccountHandle);
                 if (isSelfManaged) {
-                    mContext.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_OWN_CALLS,
-                            "Self-managed ConnectionServices require MANAGE_OWN_CALLS permission.");
+                    try {
+                        mContext.enforceCallingOrSelfPermission(
+                                Manifest.permission.MANAGE_OWN_CALLS,
+                                "Self-managed ConnectionServices require "
+                                        + "MANAGE_OWN_CALLS permission.");
+                    } catch (SecurityException e) {
+                        // Fallback to use mobile network to avoid disclosing phone account handle
+                        // package information
+                        clearPhoneAccountHandleExtra = true;
+                    }
 
-                    if (!callingPackage.equals(
+                    if (!clearPhoneAccountHandleExtra && !callingPackage.equals(
                             phoneAccountHandle.getComponentName().getPackageName())
                             && !canCallPhone(callingPackage, callingFeatureId,
                             "CALL_PHONE permission required to place calls.")) {
-                        // The caller is not allowed to place calls, so we want to ensure that it
-                        // can only place calls through itself.
-                        throw new SecurityException("Self-managed ConnectionServices can only "
-                                + "place calls through their own ConnectionService.");
+                        // The caller is not allowed to place calls, so fallback to use mobile
+                        // network.
+                        clearPhoneAccountHandleExtra = true;
                     }
                 } else if (!canCallPhone(callingPackage, callingFeatureId, "placeCall")) {
                     throw new SecurityException("Package " + callingPackage
@@ -1531,6 +1539,9 @@
                         final Intent intent = new Intent(hasCallPrivilegedPermission ?
                                 Intent.ACTION_CALL_PRIVILEGED : Intent.ACTION_CALL, handle);
                         if (extras != null) {
+                            if (clearPhoneAccountHandleExtra) {
+                                extras.remove(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+                            }
                             extras.setDefusable(true);
                             intent.putExtras(extras);
                         }
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
index 4a308e0..d4ca5ff 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
@@ -235,12 +235,14 @@
         public void onServiceDisconnected(ComponentName componentName) {
             mResultFuture.complete(mPriorStageResult);
             Log.i(this, "Service disconnected.");
+            unbindCallScreeningService();
         }
 
         @Override
         public void onBindingDied(ComponentName name) {
             mResultFuture.complete(mPriorStageResult);
             Log.i(this, "Binding died.");
+            unbindCallScreeningService();
         }
 
         @Override
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index e6c6bac..2614abf 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -214,6 +214,19 @@
         verifyNoCallPlaced();
     }
 
+    @Test
+    public void testNoCallsPlacedWithContentUri() {
+        Uri handle = Uri.parse("content://com.android.contacts/data/1");
+        Intent intent = new Intent(Intent.ACTION_CALL, handle);
+
+        int result = processIntent(intent, true).disconnectCause;
+
+        assertEquals(DisconnectCause.NO_PHONE_NUMBER_SUPPLIED, result);
+        verify(mContext, never()).getContentResolver();
+        verifyNoBroadcastSent();
+        verifyNoCallPlaced();
+    }
+
     @SmallTest
     @Test
     public void testEmergencyCallWithNonDefaultDialer() {
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index 0a10ea1..50363ae 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -1028,7 +1028,6 @@
         assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
     }
 
-
     /**
      * Ensure an IllegalArgumentException is thrown when adding more than 10 schemes for a single
      * account
@@ -1132,7 +1131,6 @@
        return sb.toString();
    }
 
-
     private static ComponentName makeQuickConnectionServiceComponentName() {
         return new ComponentName(
                 "com.android.server.telecom.tests",