Merge "Migrate to AAPT2" into pi-dev
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 222b694..6f1693a 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -802,6 +802,18 @@
         return mState;
     }
 
+    /**
+     * Determines if this {@link Call} can receive call focus via the
+     * {@link ConnectionServiceFocusManager}.
+     * Only top-level calls and non-external calls are eligible.
+     * @return {@code true} if this call is focusable, {@code false} otherwise.
+     */
+    @Override
+    public boolean isFocusable() {
+        boolean isChild = getParentCall() != null;
+        return !isChild && !isExternalCall();
+    }
+
     private boolean shouldContinueProcessingAfterDisconnect() {
         // Stop processing once the call is active.
         if (!CreateConnectionTimeout.isCallBeingPlaced(this)) {
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 90ee652..25f6f34 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1423,11 +1423,8 @@
                 notifyCreateConnectionFailed(call.getTargetPhoneAccount(), call);
             } else {
                 if (call.isEmergencyCall()) {
-                    // Disconnect calls from other ConnectionServices other than the one the
-                    // emergency call targets.
-                    // Except, do not disconnect calls from the Connection Manager's
-                    // ConnectionService.
-                    disconnectCallsHaveDifferentConnectionService(call);
+                    // Drop any ongoing self-managed calls to make way for an emergency call.
+                    disconnectSelfManagedCalls("place emerg call" /* reason */);
                 }
 
                 call.startCreateConnection(mPhoneAccountRegistrar);
@@ -3274,16 +3271,6 @@
         mCallAudioManager.switchBaseline();
     }
 
-    private void disconnectCallsHaveDifferentConnectionService(Call exceptCall) {
-        String csPackage = exceptCall.getConnectionService() != null ?
-                exceptCall.getConnectionService().getComponentName().toShortString() : "null";
-        mCalls.stream().filter(c ->
-                c.getConnectionService() != exceptCall.getConnectionService()
-                        && c.getConnectionManagerPhoneAccount()
-                        != exceptCall.getConnectionManagerPhoneAccount())
-                .forEach(c -> c.disconnect("CS not " + csPackage));
-    }
-
     /**
      * Dumps the state of the {@link CallsManager}.
      *
diff --git a/src/com/android/server/telecom/ConnectionServiceFocusManager.java b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
index 649a9d1..92570a0 100644
--- a/src/com/android/server/telecom/ConnectionServiceFocusManager.java
+++ b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
@@ -112,6 +112,11 @@
          * @see {@link CallState}
          */
         int getState();
+
+        /**
+         * @return {@code True} if this call can receive focus, {@code false} otherwise.
+         */
+        boolean isFocusable();
     }
 
     /** Interface define a call back for focus request event. */
@@ -330,7 +335,8 @@
 
         List<CallFocus> calls = mCalls
                 .stream()
-                .filter(call -> mCurrentFocus.equals(call.getConnectionServiceWrapper()))
+                .filter(call -> mCurrentFocus.equals(call.getConnectionServiceWrapper())
+                        && call.isFocusable())
                 .collect(Collectors.toList());
 
         for (int i = 0; i < PRIORITY_FOCUS_CALL_STATE.length; i++) {
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
index bd855f9..3c2cc61 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
@@ -307,6 +307,20 @@
         assertTrue(mFocusManagerUT.getAllCall().contains(mActiveCall));
     }
 
+    @SmallTest
+    @Test
+    public void testNonFocusableDoesntChangeFocus() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService
+        requestFocus(mActiveCall, null);
+
+        // WHEN a new non-focusable call is added.
+        when(mNewCall.isFocusable()).thenReturn(false);
+        mCallsManagerListener.onCallAdded((Call) mNewCall);
+
+        // THEN the call focus isn't changed.
+        assertEquals(mActiveCall, mFocusManagerUT.getCurrentFocusCall());
+    }
+
     private void requestFocus(CallFocus call, RequestFocusCallback callback) {
         mCallsManagerListener.onCallAdded((Call) call);
         mFocusManagerUT.requestFocus(call, callback);
@@ -344,6 +358,7 @@
         Call call = Mockito.mock(Call.class);
         when(call.getConnectionServiceWrapper()).thenReturn(connSvr);
         when(call.getState()).thenReturn(state);
+        when(call.isFocusable()).thenReturn(true);
         return call;
     }
 }