Merge "Prevent self-managed call control from TelecomManager APIs." into sc-dev
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 241b758..89d494c 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -3770,7 +3770,10 @@
      * @param extras The extras.
      */
     public void onConnectionEvent(String event, Bundle extras) {
-        Log.addEvent(this, LogUtils.Events.CONNECTION_EVENT, event);
+        // Don't log call quality reports; they're quite frequent and will clog the log.
+        if (!Connection.EVENT_CALL_QUALITY_REPORT.equals(event)) {
+            Log.addEvent(this, LogUtils.Events.CONNECTION_EVENT, event);
+        }
         if (Connection.EVENT_ON_HOLD_TONE_START.equals(event)) {
             mIsRemotelyHeld = true;
             Log.addEvent(this, LogUtils.Events.REMOTELY_HELD);
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index c342350..9a683ad 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -990,7 +990,7 @@
 
                     long token = Binder.clearCallingIdentity();
                     try {
-                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
+                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE, packageName);
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
@@ -1013,7 +1013,7 @@
 
                     long token = Binder.clearCallingIdentity();
                     try {
-                        acceptRingingCallInternal(videoState);
+                        acceptRingingCallInternal(videoState, packageName);
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
@@ -2120,9 +2120,16 @@
         return false;
     }
 
-    private void acceptRingingCallInternal(int videoState) {
-        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING, CallState.SIMULATED_RINGING);
+    private void acceptRingingCallInternal(int videoState, String packageName) {
+        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING,
+                CallState.SIMULATED_RINGING);
         if (call != null) {
+            if (call.isSelfManaged()) {
+                Log.addEvent(call, LogUtils.Events.REQUEST_ACCEPT,
+                        "self-mgd accept ignored from " + packageName);
+                return;
+            }
+
             if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
                 videoState = call.getVideoState();
             }
@@ -2150,6 +2157,12 @@
                 return false;
             }
 
+            if (call.isSelfManaged()) {
+                Log.addEvent(call, LogUtils.Events.REQUEST_DISCONNECT,
+                        "self-mgd disconnect ignored from " + callingPackage);
+                return false;
+            }
+
             if (call.getState() == CallState.RINGING
                     || call.getState() == CallState.SIMULATED_RINGING) {
                 mCallsManager.rejectCall(call, false /* rejectWithMessage */, null);
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 0dfe29a..fa8ab10 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -1202,6 +1202,39 @@
     }
 
     /**
+     * Ensure self-managed calls cannot be ended using {@link TelecomManager#endCall()}.
+     * @throws Exception
+     */
+    @SmallTest
+    @Test
+    public void testCannotEndSelfManagedCall() throws Exception {
+        Call call = mock(Call.class);
+        when(call.isSelfManaged()).thenReturn(true);
+        when(call.getState()).thenReturn(CallState.ACTIVE);
+        when(mFakeCallsManager.getFirstCallWithState(any()))
+                .thenReturn(call);
+        assertFalse(mTSIBinder.endCall(TEST_PACKAGE));
+        verify(mFakeCallsManager, never()).disconnectCall(eq(call));
+    }
+
+    /**
+     * Ensure self-managed calls cannot be answered using {@link TelecomManager#acceptRingingCall()}
+     * or {@link TelecomManager#acceptRingingCall(int)}.
+     * @throws Exception
+     */
+    @SmallTest
+    @Test
+    public void testCannotAnswerSelfManagedCall() throws Exception {
+        Call call = mock(Call.class);
+        when(call.isSelfManaged()).thenReturn(true);
+        when(call.getState()).thenReturn(CallState.ACTIVE);
+        when(mFakeCallsManager.getFirstCallWithState(any()))
+                .thenReturn(call);
+        mTSIBinder.acceptRingingCall(TEST_PACKAGE);
+        verify(mFakeCallsManager, never()).answerCall(eq(call), anyInt());
+    }
+
+    /**
      * Register phone accounts for the supplied PhoneAccountHandles to make them
      * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.
      * @param handles the handles for which phone accounts should be created for.