diff options
20 files changed, 244 insertions, 40 deletions
diff --git a/proto/telecom.proto b/proto/telecom.proto index f0b3d02a..06dd3941 100644 --- a/proto/telecom.proto +++ b/proto/telecom.proto @@ -149,6 +149,23 @@ message EventTimingEntry { optional int64 time_millis = 2; } +message InCallServiceInfo { + // Keep this up-to-date with com.android.server.telecom.InCallController. + enum InCallServiceType { + IN_CALL_SERVICE_TYPE_INVALID = 0; + IN_CALL_SERVICE_TYPE_DIALER_UI = 1; + IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2; + IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3; + IN_CALL_SERVICE_TYPE_NON_UI = 4; + } + + // The shortened component name of the in-call service. + optional string in_call_service_name = 1; + + // The type of the in-call service + optional InCallServiceType in_call_service_type = 2; +} + // Information about each call. message CallLog { @@ -227,7 +244,7 @@ message CallLog { // A bitmask with bits corresponding to call technologies that were used // during the call. The ones that we will record are CDMA, GSM, IMS, SIP, // and third-party. - // https://googleplex-android-review.git.corp.google.com/#/c/816516/6/src/com/android/server/telecom/Analytics.java + // See the com.android.server.telecom.Analytics.*_PHONE constants. optional int32 call_technologies = 6; // Indicates the call termination code. @@ -253,4 +270,11 @@ message CallLog { // A list of the video events during the call. repeated VideoEvent video_events = 15; + + // A list of the in-call services bound during the call. + repeated InCallServiceInfo in_call_services = 16; + + // A bitmask of the properties that were set at any point during the call. + // Bits are defined by android.telecom.Connection.PROPERTY_* constants. + optional int32 connection_properties = 17; } diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java index 0ad130b9..44567343 100644 --- a/src/com/android/server/telecom/Analytics.java +++ b/src/com/android/server/telecom/Analytics.java @@ -16,6 +16,7 @@ package com.android.server.telecom; +import android.telecom.Connection; import android.telecom.DisconnectCause; import android.telecom.ParcelableCallAnalytics; import android.telecom.TelecomAnalytics; @@ -176,6 +177,12 @@ public class Analytics { public void addVideoEvent(int eventId, int videoState) { } + + public void addInCallService(String serviceName, int type) { + } + + public void addCallProperties(int properties) { + } } /** @@ -207,6 +214,9 @@ public class Analytics { public boolean isVideo = false; public List<TelecomLogClass.VideoEvent> videoEvents; + public List<TelecomLogClass.InCallServiceInfo> inCallServiceInfos; + public int callProperties = 0; + private long mTimeOfLastVideoEvent = -1; CallInfoImpl(String callId, int callDirection) { @@ -217,6 +227,7 @@ public class Analytics { callTechnologies = 0; connectionService = ""; videoEvents = new LinkedList<>(); + inCallServiceInfos = new LinkedList<>(); } CallInfoImpl(CallInfoImpl other) { @@ -233,6 +244,7 @@ public class Analytics { this.callEvents = other.callEvents; this.isVideo = other.isVideo; this.videoEvents = other.videoEvents; + this.callProperties = other.callProperties; if (other.callTerminationReason != null) { this.callTerminationReason = new DisconnectCause( @@ -324,6 +336,18 @@ public class Analytics { } @Override + public void addInCallService(String serviceName, int type) { + inCallServiceInfos.add(new TelecomLogClass.InCallServiceInfo() + .setInCallServiceName(serviceName) + .setInCallServiceType(type)); + } + + @Override + public void addCallProperties(int properties) { + this.callProperties |= properties; + } + + @Override public String toString() { return "{\n" + " startTime: " + startTime + '\n' @@ -335,6 +359,9 @@ public class Analytics { + " callTerminationReason: " + getCallDisconnectReasonString() + '\n' + " connectionService: " + connectionService + '\n' + " isVideoCall: " + isVideo + '\n' + + " inCallServices: " + getInCallServicesString() + '\n' + + " callProperties: " + Connection.propertiesToStringShort(callProperties) + + '\n' + "}\n"; } @@ -402,7 +429,8 @@ public class Analytics { .setIsEmergencyCall(isEmergency) .setIsCreatedFromExistingConnection(createdFromExistingConnection) .setIsEmergencyCall(isEmergency) - .setIsVideoCall(isVideo); + .setIsVideoCall(isVideo) + .setConnectionProperties(callProperties); result.connectionService = new String[] {connectionService}; if (callEvents != null) { @@ -413,6 +441,9 @@ public class Analytics { } result.videoEvents = videoEvents.toArray(new TelecomLogClass.VideoEvent[videoEvents.size()]); + result.inCallServices = inCallServiceInfos.toArray( + new TelecomLogClass.InCallServiceInfo[inCallServiceInfos.size()]); + return result; } @@ -448,6 +479,21 @@ public class Analytics { return "NOT SET"; } } + + private String getInCallServicesString() { + StringBuilder s = new StringBuilder(); + s.append("[\n"); + for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) { + s.append(" "); + s.append("name: "); + s.append(service.getInCallServiceName()); + s.append(" type: "); + s.append(service.getInCallServiceType()); + s.append("\n"); + } + s.append("]"); + return s.toString(); + } } public static final String TAG = "TelecomAnalytics"; diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java index e225e8af..8d981796 100644 --- a/src/com/android/server/telecom/Call.java +++ b/src/com/android/server/telecom/Call.java @@ -1052,6 +1052,8 @@ public class Call implements CreateConnectionResponse { } + mAnalytics.addCallProperties(mConnectionProperties); + int xorProps = previousProperties ^ mConnectionProperties; Log.event(this, Log.Events.PROPERTY_CHANGE, "Current: [%s], Removed [%s], Added [%s]", @@ -2146,6 +2148,7 @@ public class Call implements CreateConnectionResponse { * @param extras The extras. */ public void onConnectionEvent(String event, Bundle extras) { + Log.event(this, Log.Events.CONNECTION_EVENT, event); if (Connection.EVENT_ON_HOLD_TONE_START.equals(event)) { mIsRemotelyHeld = true; Log.event(this, Log.Events.REMOTELY_HELD); diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java index b11a3e9b..aff13624 100644 --- a/src/com/android/server/telecom/CallAudioManager.java +++ b/src/com/android/server/telecom/CallAudioManager.java @@ -452,6 +452,11 @@ public class CallAudioManager extends CallsManagerListenerBase { return mCallAudioRouteStateMachine; } + @VisibleForTesting + public CallAudioModeStateMachine getCallAudioModeStateMachine() { + return mCallAudioModeStateMachine; + } + void dump(IndentingPrintWriter pw) { pw.println("All calls:"); pw.increaseIndent(); diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java index a501dcad..3cc2dadc 100644 --- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java +++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java @@ -1080,6 +1080,7 @@ public class CallAudioRouteStateMachine extends StateMachine { private final StatusBarNotifier mStatusBarNotifier; private final CallAudioManager.AudioServiceFactory mAudioServiceFactory; private final boolean mDoesDeviceSupportEarpieceRoute; + private final TelecomSystem.SyncRoot mLock; private boolean mHasUserExplicitlyLeftBluetooth = false; private HashMap<String, Integer> mStateNameToRouteCode; @@ -1117,6 +1118,7 @@ public class CallAudioRouteStateMachine extends StateMachine { mStatusBarNotifier = statusBarNotifier; mAudioServiceFactory = audioServiceFactory; mDoesDeviceSupportEarpieceRoute = doesDeviceSupportEarpieceRoute; + mLock = callsManager.getLock(); mStateNameToRouteCode = new HashMap<>(8); mStateNameToRouteCode.put(mQuiescentEarpieceRoute.getName(), ROUTE_EARPIECE); @@ -1298,18 +1300,20 @@ public class CallAudioRouteStateMachine extends StateMachine { } private void setSystemAudioState(CallAudioState newCallAudioState, boolean force) { - Log.i(this, "setSystemAudioState: changing from %s to %s", mLastKnownCallAudioState, - newCallAudioState); - if (force || !newCallAudioState.equals(mLastKnownCallAudioState)) { - if (newCallAudioState.getRoute() != mLastKnownCallAudioState.getRoute()) { - Log.event(mCallsManager.getForegroundCall(), - AUDIO_ROUTE_TO_LOG_EVENT.get(newCallAudioState.getRoute(), - Log.Events.AUDIO_ROUTE)); - } + synchronized (mLock) { + Log.i(this, "setSystemAudioState: changing from %s to %s", mLastKnownCallAudioState, + newCallAudioState); + if (force || !newCallAudioState.equals(mLastKnownCallAudioState)) { + if (newCallAudioState.getRoute() != mLastKnownCallAudioState.getRoute()) { + Log.event(mCallsManager.getForegroundCall(), + AUDIO_ROUTE_TO_LOG_EVENT.get(newCallAudioState.getRoute(), + Log.Events.AUDIO_ROUTE)); + } - mCallsManager.onCallAudioStateChanged(mLastKnownCallAudioState, newCallAudioState); - updateAudioForForegroundCall(newCallAudioState); - mLastKnownCallAudioState = newCallAudioState; + mCallsManager.onCallAudioStateChanged(mLastKnownCallAudioState, newCallAudioState); + updateAudioForForegroundCall(newCallAudioState); + mLastKnownCallAudioState = newCallAudioState; + } } } diff --git a/src/com/android/server/telecom/CallerInfoLookupHelper.java b/src/com/android/server/telecom/CallerInfoLookupHelper.java index 0dec3176..e557c8ad 100644 --- a/src/com/android/server/telecom/CallerInfoLookupHelper.java +++ b/src/com/android/server/telecom/CallerInfoLookupHelper.java @@ -150,7 +150,7 @@ public class CallerInfoLookupHelper { } } else { Log.i(CallerInfoLookupHelper.this, "CI query for handle %s has completed," + - " but there are no listeners left.", handle); + " but there are no listeners left.", Log.piiHandle(handle)); } } finally { Log.endSession(); @@ -197,7 +197,8 @@ public class CallerInfoLookupHelper { mQueryEntries.remove(handle); } else { Log.i(CallerInfoLookupHelper.this, "Photo query for handle %s has" + - " completed, but there are no listeners left.", handle); + " completed, but there are no listeners left.", + Log.piiHandle(handle)); } } finally { Log.endSession(); diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java index f24ffc06..2157bf3f 100644 --- a/src/com/android/server/telecom/InCallController.java +++ b/src/com/android/server/telecom/InCallController.java @@ -79,12 +79,16 @@ public final class InCallController extends CallsManagerListenerBase { } private class InCallServiceInfo { - private ComponentName mComponentName; + private final ComponentName mComponentName; private boolean mIsExternalCallsSupported; + private final int mType; - public InCallServiceInfo(ComponentName componentName, boolean isExternalCallsSupported) { + public InCallServiceInfo(ComponentName componentName, + boolean isExternalCallsSupported, + int type) { mComponentName = componentName; mIsExternalCallsSupported = isExternalCallsSupported; + mType = type; } public ComponentName getComponentName() { @@ -95,6 +99,10 @@ public final class InCallController extends CallsManagerListenerBase { return mIsExternalCallsSupported; } + public int getType() { + return mType; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -192,6 +200,12 @@ public final class InCallController extends CallsManagerListenerBase { mIsConnected = false; } + if (call != null && mIsConnected) { + call.getAnalytics().addInCallService( + mInCallServiceInfo.getComponentName().flattenToShortString(), + mInCallServiceInfo.getType()); + } + return mIsConnected; } @@ -920,7 +934,7 @@ public final class InCallController extends CallsManagerListenerBase { // Last Resort: Try to bind to the ComponentName given directly. Log.e(this, new Exception(), "Package Manager could not find ComponentName: " + componentName +". Trying to bind anyway."); - return new InCallServiceInfo(componentName, false); + return new InCallServiceInfo(componentName, false, type); } } @@ -974,7 +988,7 @@ public final class InCallController extends CallsManagerListenerBase { retval.add(new InCallServiceInfo( new ComponentName(serviceInfo.packageName, serviceInfo.name), - isExternalCallsSupported)); + isExternalCallsSupported, requestedType)); } } } diff --git a/src/com/android/server/telecom/Log.java b/src/com/android/server/telecom/Log.java index 29d9576c..2282ff01 100644 --- a/src/com/android/server/telecom/Log.java +++ b/src/com/android/server/telecom/Log.java @@ -170,6 +170,7 @@ public class Log { public static final String IS_EXTERNAL = "IS_EXTERNAL"; public static final String PROPERTY_CHANGE = "PROPERTY_CHANGE"; public static final String CAPABILITY_CHANGE = "CAPABILITY_CHANGE"; + public static final String CONNECTION_EVENT = "CONNECTION_EVENT"; public static class Timings { public static final String ACCEPT_TIMING = "accept"; diff --git a/src/com/android/server/telecom/VideoProviderProxy.java b/src/com/android/server/telecom/VideoProviderProxy.java index 6b63255f..3722b59b 100644 --- a/src/com/android/server/telecom/VideoProviderProxy.java +++ b/src/com/android/server/telecom/VideoProviderProxy.java @@ -205,7 +205,8 @@ public class VideoProviderProxy extends Connection.VideoProvider { @Override public void handleCallSessionEvent(int event) { synchronized (mLock) { - logFromVideoProvider("handleCallSessionEvent: " + event); + logFromVideoProvider("handleCallSessionEvent: " + + Connection.VideoProvider.sessionEventToString(event)); VideoProviderProxy.this.handleCallSessionEvent(event); } } @@ -477,7 +478,7 @@ public class VideoProviderProxy extends Connection.VideoProvider { * @param toLog The message to log. */ private void logFromInCall(String toLog) { - Log.v(this, "IC->VP: " + toLog); + Log.i(this, "IC->VP (callId=" + (mCall == null ? "?" : mCall.getId()) + "): " + toLog); } /** @@ -487,6 +488,6 @@ public class VideoProviderProxy extends Connection.VideoProvider { * @param toLog The message to log. */ private void logFromVideoProvider(String toLog) { - Log.v(this, "VP->IC: " + toLog); + Log.i(this, "VP->IC (callId=" + (mCall == null ? "?" : mCall.getId()) + "): " + toLog); } } diff --git a/tests/Android.mk b/tests/Android.mk index 1065ad16..8a8113be 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -21,7 +21,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ android-ex-camera2 \ android-support-v4 \ guava \ - mockito-target + mockito-target \ + platform-test-annotations LOCAL_SRC_FILES := \ $(call all-java-files-under, src) \ diff --git a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java index d8e152aa..81d4aa5b 100644 --- a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java +++ b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java @@ -17,6 +17,7 @@ package com.android.server.telecom.tests; import android.content.Context; +import android.telecom.Connection; import android.telecom.DisconnectCause; import android.telecom.InCallService; import android.telecom.ParcelableCallAnalytics; @@ -54,6 +55,7 @@ public class AnalyticsTests extends TelecomSystemTest { "650-555-1212", mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); + Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData(); assertTrue(analyticsMap.containsKey(testCall.mCallId)); @@ -250,7 +252,7 @@ public class AnalyticsTests extends TelecomSystemTest { sessions.stream() .filter(s -> Log.Sessions.CSW_ADD_CONFERENCE_CALL.equals( Analytics.sSessionIdToLogSession.get(s.getKey()))) - .forEach(s -> assertTrue(s.getTime() > minTime)); + .forEach(s -> assertTrue(s.getTime() >= minTime)); } @MediumTest @@ -300,6 +302,41 @@ public class AnalyticsTests extends TelecomSystemTest { ParcelableCallAnalytics.AnalyticsEvent.FILTERING_INITIATED)); } + @MediumTest + public void testAnalyticsConnectionProperties() throws Exception { + Analytics.reset(); + IdPair testCall = startAndMakeActiveIncomingCall( + "650-555-1212", + mPhoneAccountA0.getAccountHandle(), + mConnectionServiceFixtureA); + + int properties1 = Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE + | Connection.PROPERTY_WIFI + | Connection.PROPERTY_EMERGENCY_CALLBACK_MODE; + int properties2 = Connection.PROPERTY_HIGH_DEF_AUDIO + | Connection.PROPERTY_WIFI; + int expectedProperties = properties1 | properties2; + + mConnectionServiceFixtureA.mConnectionById.get(testCall.mConnectionId).properties = + properties1; + mConnectionServiceFixtureA.sendSetConnectionProperties(testCall.mConnectionId); + mConnectionServiceFixtureA.mConnectionById.get(testCall.mConnectionId).properties = + properties2; + mConnectionServiceFixtureA.sendSetConnectionProperties(testCall.mConnectionId); + + mConnectionServiceFixtureA. + sendSetDisconnected(testCall.mConnectionId, DisconnectCause.ERROR); + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + Analytics.dumpToEncodedProto(pw, new String[]{}); + TelecomLogClass.TelecomLog analyticsProto = + TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT)); + + assertEquals(expectedProperties, + analyticsProto.callLogs[0].getConnectionProperties() & expectedProperties); + } + private void assertIsRoundedToOneSigFig(long x) { assertEquals(x, Analytics.roundToOneSigFig(x)); } diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java index ceec91b7..6688ca0e 100644 --- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java +++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java @@ -278,6 +278,7 @@ public class BasicCallTests extends TelecomSystemTest { .createConnection(any(PhoneAccountHandle.class), anyString(), any(ConnectionRequest.class), eq(true), eq(false)); + waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); for (CallerInfoAsyncQueryFactoryFixture.Request request : mCallerInfoAsyncQueryFactoryFixture.mRequests) { @@ -314,10 +315,12 @@ public class BasicCallTests extends TelecomSystemTest { mTelecomSystem.getTelecomServiceImpl().getBinder() .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); + waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); verify(mConnectionServiceFixtureA.getTestDouble()) .createConnection(any(PhoneAccountHandle.class), anyString(), any(ConnectionRequest.class), eq(true), eq(false)); + waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); // Never reply to the caller info lookup. assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); @@ -357,10 +360,12 @@ public class BasicCallTests extends TelecomSystemTest { mTelecomSystem.getTelecomServiceImpl().getBinder() .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); + waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); verify(mConnectionServiceFixtureA.getTestDouble()) .createConnection(any(PhoneAccountHandle.class), anyString(), any(ConnectionRequest.class), eq(true), eq(false)); + waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); for (CallerInfoAsyncQueryFactoryFixture.Request request : mCallerInfoAsyncQueryFactoryFixture.mRequests) { diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java index 615fd0ec..4e5fe69d 100644 --- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java +++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java @@ -32,6 +32,7 @@ import com.android.server.telecom.CallsManager; import com.android.server.telecom.ConnectionServiceWrapper; import com.android.server.telecom.CallAudioManager; import com.android.server.telecom.StatusBarNotifier; +import com.android.server.telecom.TelecomSystem; import com.android.server.telecom.WiredHeadsetManager; import org.mockito.ArgumentCaptor; @@ -117,6 +118,7 @@ public class CallAudioRouteStateMachineTest private CallAudioManager.AudioServiceFactory mAudioServiceFactory; private static final int TEST_TIMEOUT = 500; private AudioManager mockAudioManager; + private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { }; @Override public void setUp() throws Exception { @@ -133,6 +135,7 @@ public class CallAudioRouteStateMachineTest }; when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall); + when(mockCallsManager.getLock()).thenReturn(mLock); when(fakeCall.getConnectionService()).thenReturn(mockConnectionServiceWrapper); when(fakeCall.isAlive()).thenReturn(true); doNothing().when(mockConnectionServiceWrapper).onCallAudioStateChanged(any(Call.class), @@ -856,6 +859,7 @@ public class CallAudioRouteStateMachineTest reset(mockAudioManager, mockBluetoothManager, mockCallsManager, mockConnectionServiceWrapper); when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall); + when(mockCallsManager.getLock()).thenReturn(mLock); doNothing().when(mockConnectionServiceWrapper).onCallAudioStateChanged(any(Call.class), any(CallAudioState.class)); } diff --git a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java index b8dcb68c..e9db5437 100644 --- a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java +++ b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java @@ -28,14 +28,17 @@ import android.location.CountryDetector; import android.location.CountryListener; import android.net.Uri; import android.os.Looper; +import android.os.PersistableBundle; import android.os.UserHandle; import android.os.UserManager; +import android.platform.test.annotations.Postsubmit; import android.provider.CallLog; import android.provider.CallLog.Calls; import android.telecom.DisconnectCause; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.VideoProfile; +import android.telephony.CarrierConfigManager; import android.telephony.PhoneNumberUtils; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; @@ -53,6 +56,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -195,8 +199,13 @@ public class CallLogManagerTest extends TelecomTestCase { public void testDontLogCallsFromEmergencyAccount() { when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(any(PhoneAccountHandle.class))) .thenReturn(makeFakePhoneAccount(EMERGENCY_ACCT_HANDLE, 0)); - mComponentContextFixture.putBooleanResource(R.bool.allow_emergency_numbers_in_call_log, - false); + CarrierConfigManager mockCarrierConfigManager = + (CarrierConfigManager) mComponentContextFixture.getTestDouble() + .getApplicationContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); + PersistableBundle bundle = new PersistableBundle(); + bundle.putBoolean(CarrierConfigManager.KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL, false); + when(mockCarrierConfigManager.getConfig()).thenReturn(bundle); + Call fakeCall = makeFakeCall( DisconnectCause.OTHER, // disconnectCauseCode false, // isConference @@ -285,7 +294,9 @@ public class CallLogManagerTest extends TelecomTestCase { ContentValues insertedValues = verifyInsertionWithCapture(CURRENT_USER_ID); assertEquals(insertedValues.getAsInteger(CallLog.Calls.TYPE), Integer.valueOf(CallLog.Calls.MISSED_TYPE)); - verify(mMissedCallNotifier).showMissedCallNotification(fakeMissedCall); + // Timeout needed because showMissedCallNotification is called from onPostExecute. + verify(mMissedCallNotifier, timeout(TEST_TIMEOUT_MILLIS)) + .showMissedCallNotification(fakeMissedCall); } @MediumTest @@ -413,6 +424,7 @@ public class CallLogManagerTest extends TelecomTestCase { } @MediumTest + @Postsubmit public void testLogCallDirectionOutgoingWithMultiUserCapability() { when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(any(PhoneAccountHandle.class))) .thenReturn(makeFakePhoneAccount(mOtherUserAccountHandle, @@ -506,6 +518,7 @@ public class CallLogManagerTest extends TelecomTestCase { } @MediumTest + @Postsubmit public void testLogCallDirectionOutgoingFromManagedProfile() { when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(any(PhoneAccountHandle.class))) .thenReturn(makeFakePhoneAccount(mManagedProfileAccountHandle, 0)); @@ -656,10 +669,13 @@ public class CallLogManagerTest extends TelecomTestCase { private void verifyNoInsertion() { try { - verify(mContentProvider, timeout(TEST_TIMEOUT_MILLIS).never()).insert(any(String.class), + Thread.sleep(TEST_TIMEOUT_MILLIS); + verify(mContentProvider, never()).insert(any(String.class), any(Uri.class), any(ContentValues.class)); } catch (android.os.RemoteException e) { fail("Remote exception occurred during test execution"); + } catch (InterruptedException e) { + e.printStackTrace(); } } @@ -667,10 +683,13 @@ public class CallLogManagerTest extends TelecomTestCase { private void verifyNoInsertionInUser(int userId) { try { Uri uri = ContentProvider.maybeAddUserId(CallLog.Calls.CONTENT_URI, userId); - verify(getContentProviderForUser(userId), timeout(TEST_TIMEOUT_MILLIS).never()) + Thread.sleep(TEST_TIMEOUT_MILLIS); + verify(getContentProviderForUser(userId), never()) .insert(any(String.class), eq(uri), any(ContentValues.class)); } catch (android.os.RemoteException e) { fail("Remote exception occurred during test execution"); + } catch (InterruptedException e) { + e.printStackTrace(); } } @@ -719,6 +738,8 @@ public class CallLogManagerTest extends TelecomTestCase { when(fakeCall.getViaNumber()).thenReturn(viaNumber); when(fakeCall.getInitiatingUser()).thenReturn(initiatingUser); when(fakeCall.getCallDataUsage()).thenReturn(callDataUsage); + when(fakeCall.isEmergencyCall()).thenReturn( + phoneAccountHandle.equals(EMERGENCY_ACCT_HANDLE)); return fakeCall; } diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java index 962ab10e..255f3ea8 100644 --- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java +++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java @@ -434,6 +434,11 @@ public class ConnectionServiceFixture implements TestFixture<IConnectionService> } } + public void sendSetConnectionProperties(String id) throws Exception { + for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { + a.setConnectionProperties(id, mConnectionById.get(id).properties); + } + } public void sendSetIsConferenced(String id) throws Exception { for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { a.setIsConferenced(id, mConnectionById.get(id).conferenceId); diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java index cf722252..f5c04395 100644 --- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java +++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java @@ -39,6 +39,7 @@ import android.text.TextUtils; import com.android.internal.telecom.IInCallAdapter; import com.android.internal.telecom.IInCallService; +import com.android.server.telecom.Analytics; import com.android.server.telecom.BluetoothHeadsetProxy; import com.android.server.telecom.Call; import com.android.server.telecom.CallsManager; @@ -101,6 +102,7 @@ public class InCallControllerTests extends TelecomTestCase { public void setUp() throws Exception { super.setUp(); MockitoAnnotations.initMocks(this); + when(mMockCall.getAnalytics()).thenReturn(new Analytics.CallInfo()); doReturn(mMockResources).when(mMockContext).getResources(); doReturn(SYS_PKG).when(mMockResources).getString(R.string.ui_default_package); doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class); @@ -121,7 +123,6 @@ public class InCallControllerTests extends TelecomTestCase { when(mMockCall.isIncoming()).thenReturn(true); when(mMockCall.isExternalCall()).thenReturn(false); - Intent queryIntent = new Intent(InCallService.SERVICE_INTERFACE); setupMockPackageManager(false /* default */, true /* system */, false /* external calls */); mInCallController.bindToServices(mMockCall); diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java index 98231ce4..8de54bfb 100644 --- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java @@ -53,7 +53,9 @@ import com.android.server.telecom.components.UserCallIntentProcessorFactory; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; +import org.mockito.Matchers; import org.mockito.Mock; +import org.mockito.internal.matchers.VarargMatcher; import java.util.ArrayList; import java.util.Collection; @@ -139,6 +141,13 @@ public class TelecomServiceImplTest extends TelecomTestCase { } } + private static class IntVarArgMatcher extends ArgumentMatcher<int[]> implements VarargMatcher { + @Override + public boolean matches(Object argument) { + return true; + } + } + private ITelecomService.Stub mTSIBinder; private AppOpsManager mAppOpsManager; private UserManager mUserManager; @@ -859,7 +868,7 @@ public class TelecomServiceImplTest extends TelecomTestCase { public void testEndCallWithNoForegroundCall() throws Exception { Call call = mock(Call.class); when(call.getState()).thenReturn(CallState.ACTIVE); - when(mFakeCallsManager.getFirstCallWithState(anyInt(), anyInt(), anyInt(), anyInt())) + when(mFakeCallsManager.getFirstCallWithState(argThat(new IntVarArgMatcher()))) .thenReturn(call); assertTrue(mTSIBinder.endCall()); verify(call).disconnect(); diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java index c8a12859..d2757479 100644 --- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java +++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java @@ -61,6 +61,7 @@ import com.android.internal.telecom.IInCallAdapter; import com.android.server.telecom.AsyncRingtonePlayer; import com.android.server.telecom.BluetoothPhoneServiceImpl; import com.android.server.telecom.CallAudioManager; +import com.android.server.telecom.CallAudioRouteStateMachine; import com.android.server.telecom.CallerInfoAsyncQueryFactory; import com.android.server.telecom.CallsManager; import com.android.server.telecom.CallsManagerListenerBase; @@ -75,8 +76,10 @@ import com.android.server.telecom.PhoneNumberUtilsAdapter; import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; import com.android.server.telecom.ProximitySensorManager; import com.android.server.telecom.ProximitySensorManagerFactory; +import com.android.server.telecom.Runnable; import com.android.server.telecom.TelecomSystem; import com.android.server.telecom.Timeouts; +import com.android.server.telecom.callfiltering.AsyncBlockCheckFilter; import com.android.server.telecom.components.UserCallIntentProcessor; import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory; @@ -89,6 +92,8 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * Implements mocks and functionality required to implement telecom system tests. @@ -197,7 +202,8 @@ public class TelecomSystemTest extends TelecomTestCase { .addSupportedUriScheme("tel") .setCapabilities( PhoneAccount.CAPABILITY_CALL_PROVIDER | - PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) + PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION | + PhoneAccount.CAPABILITY_VIDEO_CALLING) .build(); final PhoneAccount mPhoneAccountA1 = PhoneAccount.builder( @@ -342,7 +348,7 @@ public class TelecomSystemTest extends TelecomTestCase { mTimeoutsAdapter = mock(Timeouts.Adapter.class); when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class))) - .thenReturn(TEST_TIMEOUT / 10L); + .thenReturn(TEST_TIMEOUT / 5L); mTelecomSystem = new TelecomSystem( mComponentContextFixture.getTestDouble(), diff --git a/tests/src/com/android/server/telecom/tests/VideoCallTests.java b/tests/src/com/android/server/telecom/tests/VideoCallTests.java index ca56247a..0319e81f 100644 --- a/tests/src/com/android/server/telecom/tests/VideoCallTests.java +++ b/tests/src/com/android/server/telecom/tests/VideoCallTests.java @@ -18,11 +18,14 @@ package com.android.server.telecom.tests; import org.mockito.ArgumentCaptor; +import android.os.RemoteException; import android.telecom.CallAudioState; import android.telecom.VideoProfile; import android.test.suitebuilder.annotation.MediumTest; +import com.android.server.telecom.CallAudioModeStateMachine; import com.android.server.telecom.CallAudioRouteStateMachine; +import com.android.server.telecom.Log; import java.util.List; @@ -134,13 +137,25 @@ public class VideoCallTests extends TelecomSystemTest { private void verifyAudioRoute(int expectedRoute) throws Exception { // Capture all onCallAudioStateChanged callbacks to InCall. CallAudioRouteStateMachine carsm = mTelecomSystem.getCallsManager() - .getCallAudioManager().getCallAudioRouteStateMachine(); + .getCallAudioManager().getCallAudioRouteStateMachine(); + CallAudioModeStateMachine camsm = mTelecomSystem.getCallsManager() + .getCallAudioManager().getCallAudioModeStateMachine(); + waitForHandlerAction(camsm.getHandler(), TEST_TIMEOUT); + final boolean[] success = {true}; + carsm.sendMessage(CallAudioRouteStateMachine.RUN_RUNNABLE, (Runnable) () -> { + ArgumentCaptor<CallAudioState> callAudioStateArgumentCaptor = ArgumentCaptor.forClass( + CallAudioState.class); + try { + verify(mInCallServiceFixtureX.getTestDouble(), atLeastOnce()) + .onCallAudioStateChanged(callAudioStateArgumentCaptor.capture()); + } catch (RemoteException e) { + fail("Remote exception in InCallServiceFixture"); + } + List<CallAudioState> changes = callAudioStateArgumentCaptor.getAllValues(); + assertEquals(expectedRoute, changes.get(changes.size() - 1).getRoute()); + success[0] = true; + }); waitForHandlerAction(carsm.getHandler(), TEST_TIMEOUT); - ArgumentCaptor<CallAudioState> callAudioStateArgumentCaptor = ArgumentCaptor.forClass( - CallAudioState.class); - verify(mInCallServiceFixtureX.getTestDouble(), atLeastOnce()).onCallAudioStateChanged( - callAudioStateArgumentCaptor.capture()); - List<CallAudioState> changes = callAudioStateArgumentCaptor.getAllValues(); - assertEquals(expectedRoute, changes.get(changes.size() - 1).getRoute()); + assertTrue(success[0]); } } diff --git a/tests/src/com/android/server/telecom/tests/VideoProviderTest.java b/tests/src/com/android/server/telecom/tests/VideoProviderTest.java index 92f876b9..993679e5 100644 --- a/tests/src/com/android/server/telecom/tests/VideoProviderTest.java +++ b/tests/src/com/android/server/telecom/tests/VideoProviderTest.java @@ -113,6 +113,7 @@ public class VideoProviderTest extends TelecomSystemTest { mConnectionInfo = mConnectionServiceFixtureA.mConnectionById.get(mCallIds.mConnectionId); mVerificationLock = new CountDownLatch(1); + waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); } @Override |