Loading src/com/android/server/telecom/InCallController.java +14 −0 Original line number Diff line number Diff line Loading @@ -405,11 +405,25 @@ public class InCallController extends CallsManagerListenerBase implements } protected void onDisconnected() { boolean shouldReconnect = mIsConnected; InCallController.this.onDisconnected(mInCallServiceInfo); disconnect(); // Unbind explicitly if we get disconnected. if (mListener != null) { mListener.onDisconnect(InCallServiceBindingConnection.this, mCall); } // Check if we are expected to reconnect if (shouldReconnect && shouldHandleReconnect()) { connect(mCall); // reconnect } } private boolean shouldHandleReconnect() { int serviceType = mInCallServiceInfo.getType(); boolean nonUI = (serviceType == IN_CALL_SERVICE_TYPE_NON_UI) || (serviceType == IN_CALL_SERVICE_TYPE_COMPANION); boolean carModeUI = (serviceType == IN_CALL_SERVICE_TYPE_CAR_MODE_UI); return carModeUI || (nonUI && !mIsNullBinding); } } Loading tests/src/com/android/server/telecom/tests/InCallControllerTests.java +40 −0 Original line number Diff line number Diff line Loading @@ -759,6 +759,46 @@ public class InCallControllerTests extends TelecomTestCase { assertEquals(sysDialerComponentName, bindIntentCaptor2.getValue().getComponent()); } @Test public void testBindToService_CarModeUI_Crash() throws Exception { setupMocks(false /* isExternalCall */); setupMockPackageManager(true /* default */, true /* system */, true /* external calls */); // Enable car mode when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true); mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true); // Now bind; we should only bind to one app. mInCallController.bindToServices(mMockCall); // Bind InCallServices ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class); ArgumentCaptor<ServiceConnection> serviceConnectionCaptor = ArgumentCaptor.forClass(ServiceConnection.class); verify(mMockContext, times(1)).bindServiceAsUser( bindIntentCaptor.capture(), serviceConnectionCaptor.capture(), eq(serviceBindingFlags), eq(UserHandle.CURRENT)); // Verify bind car mode ui assertEquals(1, bindIntentCaptor.getAllValues().size()); verifyBinding(bindIntentCaptor, 0, CAR_PKG, CAR_CLASS); // Emulate a crash in the CarModeUI ServiceConnection serviceConnection = serviceConnectionCaptor.getValue(); serviceConnection.onServiceDisconnected(bindIntentCaptor.getValue().getComponent()); ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class); verify(mMockContext, times(2)).bindServiceAsUser( bindIntentCaptor2.capture(), any(ServiceConnection.class), eq(serviceBindingFlags), eq(UserHandle.CURRENT)); verifyBinding(bindIntentCaptor2, 1, CAR_PKG, CAR_CLASS); } /** * Ensures that the {@link InCallController} will bind to an {@link InCallService} which * supports external calls. Loading Loading
src/com/android/server/telecom/InCallController.java +14 −0 Original line number Diff line number Diff line Loading @@ -405,11 +405,25 @@ public class InCallController extends CallsManagerListenerBase implements } protected void onDisconnected() { boolean shouldReconnect = mIsConnected; InCallController.this.onDisconnected(mInCallServiceInfo); disconnect(); // Unbind explicitly if we get disconnected. if (mListener != null) { mListener.onDisconnect(InCallServiceBindingConnection.this, mCall); } // Check if we are expected to reconnect if (shouldReconnect && shouldHandleReconnect()) { connect(mCall); // reconnect } } private boolean shouldHandleReconnect() { int serviceType = mInCallServiceInfo.getType(); boolean nonUI = (serviceType == IN_CALL_SERVICE_TYPE_NON_UI) || (serviceType == IN_CALL_SERVICE_TYPE_COMPANION); boolean carModeUI = (serviceType == IN_CALL_SERVICE_TYPE_CAR_MODE_UI); return carModeUI || (nonUI && !mIsNullBinding); } } Loading
tests/src/com/android/server/telecom/tests/InCallControllerTests.java +40 −0 Original line number Diff line number Diff line Loading @@ -759,6 +759,46 @@ public class InCallControllerTests extends TelecomTestCase { assertEquals(sysDialerComponentName, bindIntentCaptor2.getValue().getComponent()); } @Test public void testBindToService_CarModeUI_Crash() throws Exception { setupMocks(false /* isExternalCall */); setupMockPackageManager(true /* default */, true /* system */, true /* external calls */); // Enable car mode when(mMockSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(true); mInCallController.handleCarModeChange(UiModeManager.DEFAULT_PRIORITY, CAR_PKG, true); // Now bind; we should only bind to one app. mInCallController.bindToServices(mMockCall); // Bind InCallServices ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class); ArgumentCaptor<ServiceConnection> serviceConnectionCaptor = ArgumentCaptor.forClass(ServiceConnection.class); verify(mMockContext, times(1)).bindServiceAsUser( bindIntentCaptor.capture(), serviceConnectionCaptor.capture(), eq(serviceBindingFlags), eq(UserHandle.CURRENT)); // Verify bind car mode ui assertEquals(1, bindIntentCaptor.getAllValues().size()); verifyBinding(bindIntentCaptor, 0, CAR_PKG, CAR_CLASS); // Emulate a crash in the CarModeUI ServiceConnection serviceConnection = serviceConnectionCaptor.getValue(); serviceConnection.onServiceDisconnected(bindIntentCaptor.getValue().getComponent()); ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class); verify(mMockContext, times(2)).bindServiceAsUser( bindIntentCaptor2.capture(), any(ServiceConnection.class), eq(serviceBindingFlags), eq(UserHandle.CURRENT)); verifyBinding(bindIntentCaptor2, 1, CAR_PKG, CAR_CLASS); } /** * Ensures that the {@link InCallController} will bind to an {@link InCallService} which * supports external calls. Loading