summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/server/telecom/Call.java92
-rw-r--r--src/com/android/server/telecom/CallsManager.java29
-rw-r--r--src/com/android/server/telecom/ClockProxy.java39
-rw-r--r--src/com/android/server/telecom/TelecomSystem.java7
-rw-r--r--src/com/android/server/telecom/components/TelecomService.java16
-rw-r--r--tests/src/com/android/server/telecom/tests/BasicCallTests.java29
-rw-r--r--tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java4
-rw-r--r--tests/src/com/android/server/telecom/tests/TelecomSystemTest.java26
8 files changed, 192 insertions, 50 deletions
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 9ab52900..90c1fe81 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -27,6 +27,7 @@ import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.Trace;
import android.provider.ContactsContract.Contacts;
import android.telecom.CallAudioState;
@@ -242,17 +243,38 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
private String mViaNumber = "";
/**
- * The time this call was created. Beyond logging and such, may also be used for bookkeeping
- * and specifically for marking certain call attempts as failed attempts.
+ * The wall clock time this call was created. Beyond logging and such, may also be used for
+ * bookkeeping and specifically for marking certain call attempts as failed attempts.
+ * Note: This timestamp should NOT be used for calculating call duration.
*/
- private long mCreationTimeMillis = System.currentTimeMillis();
+ private long mCreationTimeMillis;
/** The time this call was made active. */
private long mConnectTimeMillis = 0;
- /** The time this call was disconnected. */
+ /**
+ * The time, in millis, since boot when this call was connected. This should ONLY be used when
+ * calculating the duration of the call.
+ *
+ * The reason for this is that the {@link SystemClock#elapsedRealtime()} is based on the
+ * elapsed time since the device was booted. Changes to the system clock (e.g. due to NITZ
+ * time sync, time zone changes user initiated clock changes) would cause a duration calculated
+ * based on {@link #mConnectTimeMillis} to change based on the delta in the time.
+ * Using the {@link SystemClock#elapsedRealtime()} ensures that changes to the wall clock do
+ * not impact the call duration.
+ */
+ private long mConnectElapsedTimeMillis = 0;
+
+ /** The wall clock time this call was disconnected. */
private long mDisconnectTimeMillis = 0;
+ /**
+ * The elapsed time since boot when this call was disconnected. Recorded as the
+ * {@link SystemClock#elapsedRealtime()}. This ensures that the call duration is not impacted
+ * by changes in the wall time clock.
+ */
+ private long mDisconnectElapsedTimeMillis = 0;
+
/** The gateway information associated with this call. This stores the original call handle
* that the user is attempting to connect to via the gateway, the actual handle to dial in
* order to connect the call via the gateway, as well as the package name of the gateway
@@ -376,6 +398,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
private final ConnectionServiceRepository mRepository;
private final Context mContext;
private final CallsManager mCallsManager;
+ private final ClockProxy mClockProxy;
private final TelecomSystem.SyncRoot mLock;
private final String mId;
private String mConnectionId;
@@ -471,20 +494,19 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
/**
* Persists the specified parameters and initializes the new instance.
- *
- * @param context The context.
+ * @param context The context.
* @param repository The connection service repository.
* @param handle The handle to dial.
* @param gatewayInfo Gateway information to use for the call.
* @param connectionManagerPhoneAccountHandle Account to use for the service managing the call.
- * This account must be one that was registered with the
- * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
+* This account must be one that was registered with the
+* {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
* @param targetPhoneAccountHandle Account information to use for the call. This account must be
- * one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
+* one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
* @param callDirection one of CALL_DIRECTION_INCOMING, CALL_DIRECTION_OUTGOING,
- * or CALL_DIRECTION_UNKNOWN.
+* or CALL_DIRECTION_UNKNOWN.
* @param shouldAttachToExistingConnection Set to true to attach the call to an existing
- * connection, regardless of whether it's incoming or outgoing.
+ * @param clockProxy
*/
public Call(
String callId,
@@ -501,7 +523,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
PhoneAccountHandle targetPhoneAccountHandle,
int callDirection,
boolean shouldAttachToExistingConnection,
- boolean isConference) {
+ boolean isConference,
+ ClockProxy clockProxy) {
mId = callId;
mConnectionId = callId;
mState = isConference ? CallState.ACTIVE : CallState.NEW;
@@ -522,26 +545,27 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
|| callDirection == CALL_DIRECTION_INCOMING;
maybeLoadCannedSmsResponses();
mAnalytics = new Analytics.CallInfo();
-
+ mClockProxy = clockProxy;
+ mCreationTimeMillis = mClockProxy.currentTimeMillis();
}
/**
* Persists the specified parameters and initializes the new instance.
- *
- * @param context The context.
+ * @param context The context.
* @param repository The connection service repository.
* @param handle The handle to dial.
* @param gatewayInfo Gateway information to use for the call.
* @param connectionManagerPhoneAccountHandle Account to use for the service managing the call.
- * This account must be one that was registered with the
- * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
+* This account must be one that was registered with the
+* {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
* @param targetPhoneAccountHandle Account information to use for the call. This account must be
- * one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
+* one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
* @param callDirection one of CALL_DIRECTION_INCOMING, CALL_DIRECTION_OUTGOING,
- * or CALL_DIRECTION_UNKNOWN
+* or CALL_DIRECTION_UNKNOWN
* @param shouldAttachToExistingConnection Set to true to attach the call to an existing
- * connection, regardless of whether it's incoming or outgoing.
+* connection, regardless of whether it's incoming or outgoing.
* @param connectTimeMillis The connection time of the call.
+ * @param clockProxy
*/
Call(
String callId,
@@ -559,13 +583,16 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
int callDirection,
boolean shouldAttachToExistingConnection,
boolean isConference,
- long connectTimeMillis) {
+ long connectTimeMillis,
+ long connectElapsedTimeMillis,
+ ClockProxy clockProxy) {
this(callId, context, callsManager, lock, repository, contactsAsyncHelper,
callerInfoAsyncQueryFactory, phoneNumberUtilsAdapter, handle, gatewayInfo,
connectionManagerPhoneAccountHandle, targetPhoneAccountHandle, callDirection,
- shouldAttachToExistingConnection, isConference);
+ shouldAttachToExistingConnection, isConference, clockProxy);
mConnectTimeMillis = connectTimeMillis;
+ mConnectElapsedTimeMillis = connectElapsedTimeMillis;
mAnalytics.setCallStartTime(connectTimeMillis);
}
@@ -790,14 +817,17 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
// We check to see if mConnectTime is already set to prevent the
// call from resetting active time when it goes in and out of
// ACTIVE/ON_HOLD
- mConnectTimeMillis = System.currentTimeMillis();
+ mConnectTimeMillis = mClockProxy.currentTimeMillis();
+ mConnectElapsedTimeMillis = mClockProxy.elapsedRealtime();
mAnalytics.setCallStartTime(mConnectTimeMillis);
}
// We're clearly not disconnected, so reset the disconnected time.
mDisconnectTimeMillis = 0;
+ mDisconnectElapsedTimeMillis = 0;
} else if (mState == CallState.DISCONNECTED) {
- mDisconnectTimeMillis = System.currentTimeMillis();
+ mDisconnectTimeMillis = mClockProxy.currentTimeMillis();
+ mDisconnectElapsedTimeMillis = mClockProxy.elapsedRealtime();
mAnalytics.setCallEndTime(mDisconnectTimeMillis);
setLocallyDisconnecting(false);
fixParentAfterDisconnect();
@@ -1200,9 +1230,11 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
}
/**
+ * Note: This method relies on {@link #mConnectElapsedTimeMillis} and
+ * {@link #mDisconnectElapsedTimeMillis} which are independent of the wall clock (which could
+ * change due to clock changes).
* @return The "age" of this call object in milliseconds, which typically also represents the
- * period since this call was added to the set pending outgoing calls, see
- * mCreationTimeMillis.
+ * period since this call was added to the set pending outgoing calls.
*/
@VisibleForTesting
public long getAgeMillis() {
@@ -1211,16 +1243,16 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable {
mDisconnectCause.getCode() == DisconnectCause.MISSED)) {
// Rejected and missed calls have no age. They're immortal!!
return 0;
- } else if (mConnectTimeMillis == 0) {
+ } else if (mConnectElapsedTimeMillis == 0) {
// Age is measured in the amount of time the call was active. A zero connect time
// indicates that we never went active, so return 0 for the age.
return 0;
- } else if (mDisconnectTimeMillis == 0) {
+ } else if (mDisconnectElapsedTimeMillis == 0) {
// We connected, but have not yet disconnected
- return System.currentTimeMillis() - mConnectTimeMillis;
+ return mClockProxy.elapsedRealtime() - mConnectElapsedTimeMillis;
}
- return mDisconnectTimeMillis - mConnectTimeMillis;
+ return mDisconnectElapsedTimeMillis - mConnectElapsedTimeMillis;
}
/**
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index c44e4fab..6cb08b2b 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -257,6 +257,7 @@ public class CallsManager extends Call.ListenerBase
private final DefaultDialerCache mDefaultDialerCache;
private final Timeouts.Adapter mTimeoutsAdapter;
private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
+ private final ClockProxy mClockProxy;
private final Set<Call> mLocallyDisconnectingCalls = new HashSet<>();
private final Set<Call> mPendingCallsToDisconnect = new HashSet<>();
/* Handler tied to thread in which CallManager was initialized. */
@@ -306,7 +307,8 @@ public class CallsManager extends Call.ListenerBase
AsyncRingtonePlayer asyncRingtonePlayer,
PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
EmergencyCallHelper emergencyCallHelper,
- InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory) {
+ InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
+ ClockProxy clockProxy) {
mContext = context;
mLock = lock;
mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter;
@@ -370,6 +372,7 @@ public class CallsManager extends Call.ListenerBase
mConnectionServiceRepository =
new ConnectionServiceRepository(mPhoneAccountRegistrar, mContext, mLock, this);
mInCallWakeLockController = inCallWakeLockControllerFactory.create(context, this);
+ mClockProxy = clockProxy;
mListeners.add(mInCallWakeLockController);
mListeners.add(statusBarNotifier);
@@ -833,8 +836,8 @@ public class CallsManager extends Call.ListenerBase
phoneAccountHandle,
Call.CALL_DIRECTION_INCOMING /* callDirection */,
false /* forceAttachToExistingConnection */,
- false /* isConference */
- );
+ false, /* isConference */
+ mClockProxy);
// Ensure new calls related to self-managed calls/connections are set as such. This will
// be overridden when the actual connection is returned in startCreateConnection, however
@@ -967,8 +970,8 @@ public class CallsManager extends Call.ListenerBase
// Use onCreateIncomingConnection in TelephonyConnectionService, so that we attach
// to the existing connection instead of trying to create a new one.
true /* forceAttachToExistingConnection */,
- false /* isConference */
- );
+ false, /* isConference */
+ mClockProxy);
call.initAnalytics();
setIntentExtrasAndStartTime(call, extras);
@@ -1047,8 +1050,8 @@ public class CallsManager extends Call.ListenerBase
null /* phoneAccountHandle */,
Call.CALL_DIRECTION_OUTGOING /* callDirection */,
false /* forceAttachToExistingConnection */,
- false /* isConference */
- );
+ false, /* isConference */
+ mClockProxy);
call.initAnalytics();
// Ensure new calls related to self-managed calls/connections are set as such. This
@@ -2023,6 +2026,10 @@ public class CallsManager extends Call.ListenerBase
parcelableConference.getConnectTimeMillis() ==
Conference.CONNECT_TIME_NOT_SPECIFIED ? 0 :
parcelableConference.getConnectTimeMillis();
+ long connectElapsedTime =
+ parcelableConference.getConnectElapsedTimeMillis() ==
+ Conference.CONNECT_TIME_NOT_SPECIFIED ? 0 :
+ parcelableConference.getConnectElapsedTimeMillis();
Call call = new Call(
callId,
@@ -2040,7 +2047,9 @@ public class CallsManager extends Call.ListenerBase
Call.CALL_DIRECTION_UNDEFINED /* callDirection */,
false /* forceAttachToExistingConnection */,
true /* isConference */,
- connectTime);
+ connectTime,
+ connectElapsedTime,
+ mClockProxy);
setCallState(call, Call.getStateFromConnectionState(parcelableConference.getState()),
"new conference call");
@@ -2707,7 +2716,9 @@ public class CallsManager extends Call.ListenerBase
Call.CALL_DIRECTION_UNDEFINED /* callDirection */,
false /* forceAttachToExistingConnection */,
isDowngradedConference /* isConference */,
- connection.getConnectTimeMillis() /* connectTimeMillis */);
+ connection.getConnectTimeMillis() /* connectTimeMillis */,
+ connection.getConnectElapsedTimeMillis(), /* connectElapsedTimeMillis */
+ mClockProxy);
call.initAnalytics();
call.getAnalytics().setCreatedFromExistingConnection(true);
diff --git a/src/com/android/server/telecom/ClockProxy.java b/src/com/android/server/telecom/ClockProxy.java
new file mode 100644
index 00000000..6f92f947
--- /dev/null
+++ b/src/com/android/server/telecom/ClockProxy.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom;
+
+import android.os.SystemClock;
+
+/**
+ * Defines common clock functionality used in Telecom. Provided to make unit testing of clock
+ * operations testable.
+ */
+public interface ClockProxy {
+ /**
+ * Returns the current wall-clock time of the system, as typically returned by
+ * {@link System#currentTimeMillis()}.
+ * @return The current wall-clock time.
+ */
+ long currentTimeMillis();
+
+ /**
+ * Returns the elapsed time since boot of the system, as typically returned by
+ * {@link SystemClock#elapsedRealtime()}.
+ * @return the current elapsed real time.
+ */
+ long elapsedRealtime();
+}
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index b40381bb..31afbba6 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -22,7 +22,6 @@ import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.IncomingCallNotifier;
-import com.android.server.telecom.ui.IncomingCallNotifier.IncomingCallNotifierFactory;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
@@ -190,7 +189,8 @@ public class TelecomSystem {
AsyncRingtonePlayer asyncRingtonePlayer,
PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
IncomingCallNotifier incomingCallNotifier,
- InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory) {
+ InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
+ ClockProxy clockProxy) {
mContext = context.getApplicationContext();
LogUtils.initLogging(mContext);
DefaultDialerManagerAdapter defaultDialerAdapter =
@@ -255,7 +255,8 @@ public class TelecomSystem {
asyncRingtonePlayer,
phoneNumberUtilsAdapter,
emergencyCallHelper,
- toneGeneratorFactory);
+ toneGeneratorFactory,
+ clockProxy);
mIncomingCallNotifier = incomingCallNotifier;
incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index d9d60b86..19dd404e 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -25,6 +25,7 @@ import android.media.ToneGenerator;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.telecom.Log;
import com.android.internal.telephony.CallerInfoAsyncQuery;
@@ -33,6 +34,7 @@ import com.android.server.telecom.BluetoothAdapterProxy;
import com.android.server.telecom.BluetoothPhoneServiceImpl;
import com.android.server.telecom.CallerInfoAsyncQueryFactory;
import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.HeadsetMediaButton;
import com.android.server.telecom.HeadsetMediaButtonFactory;
@@ -161,8 +163,18 @@ public class TelecomService extends Service implements TelecomSystem.Component {
new AsyncRingtonePlayer(),
new PhoneNumberUtilsAdapterImpl(),
new IncomingCallNotifier(context),
- ToneGenerator::new
- ));
+ ToneGenerator::new,
+ new ClockProxy() {
+ @Override
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ @Override
+ public long elapsedRealtime() {
+ return SystemClock.elapsedRealtime();
+ }
+ }));
}
if (BluetoothAdapter.getDefaultAdapter() != null) {
context.startService(new Intent(context, BluetoothPhoneService.class));
diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
index ce774a78..905a15e6 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -82,11 +82,22 @@ public class BasicCallTests extends TelecomSystemTest {
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
assertEquals(Call.STATE_DISCONNECTED,
mInCallServiceFixtureX.getCall(ids.mCallId).getState());
assertEquals(Call.STATE_DISCONNECTED,
mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+ assertEquals(TEST_CONNECT_TIME,
+ mInCallServiceFixtureX.getCall(ids.mCallId).getConnectTimeMillis());
+ assertEquals(TEST_CONNECT_TIME,
+ mInCallServiceFixtureY.getCall(ids.mCallId).getConnectTimeMillis());
+ assertEquals(TEST_CREATE_TIME,
+ mInCallServiceFixtureX.getCall(ids.mCallId).getCreationTimeMillis());
+ assertEquals(TEST_CREATE_TIME,
+ mInCallServiceFixtureY.getCall(ids.mCallId).getCreationTimeMillis());
+
verifyNoBlockChecks();
}
@@ -95,6 +106,8 @@ public class BasicCallTests extends TelecomSystemTest {
IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212",
mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
assertEquals(Call.STATE_DISCONNECTED,
mInCallServiceFixtureX.getCall(ids.mCallId).getState());
@@ -219,6 +232,8 @@ public class BasicCallTests extends TelecomSystemTest {
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
assertEquals(Call.STATE_DISCONNECTED,
mInCallServiceFixtureX.getCall(ids.mCallId).getState());
@@ -231,6 +246,8 @@ public class BasicCallTests extends TelecomSystemTest {
IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
assertEquals(Call.STATE_DISCONNECTED,
mInCallServiceFixtureX.getCall(ids.mCallId).getState());
@@ -290,6 +307,8 @@ public class BasicCallTests extends TelecomSystemTest {
IdPair ids = outgoingCallPhoneAccountSelected(mPhoneAccountA0.getAccountHandle(),
startingNumConnections, startingNumCalls, mConnectionServiceFixtureA);
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
assertEquals(Call.STATE_DISCONNECTED,
mInCallServiceFixtureX.getCall(ids.mCallId).getState());
@@ -341,6 +360,8 @@ public class BasicCallTests extends TelecomSystemTest {
@LargeTest
public void testIncomingCallCallerInfoLookupTimesOutIsAllowed() throws Exception {
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME);
Bundle extras = new Bundle();
extras.putParcelable(
TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
@@ -377,6 +398,8 @@ public class BasicCallTests extends TelecomSystemTest {
verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
.addCall(any(ParcelableCall.class));
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
disconnectCall(mInCallServiceFixtureX.mLatestCallId,
mConnectionServiceFixtureA.mLatestConnectionId);
}
@@ -736,9 +759,15 @@ public class BasicCallTests extends TelecomSystemTest {
}
private void disconnectCall(String callId, String connectionId) throws Exception {
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL);
assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState());
assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState());
+ assertEquals(TEST_CREATE_TIME,
+ mInCallServiceFixtureX.getCall(callId).getCreationTimeMillis());
+ assertEquals(TEST_CREATE_TIME,
+ mInCallServiceFixtureY.getCall(callId).getCreationTimeMillis());
}
/**
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index e815b5cb..39f70c8c 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -50,7 +50,6 @@ import com.google.android.collect.Lists;
import java.lang.Override;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -410,6 +409,7 @@ public class ConnectionServiceFixture implements TestFixture<IConnectionService>
IVideoProvider videoProvider;
int videoState;
long connectTimeMillis;
+ long connectElapsedTimeMillis;
StatusHints statusHints;
Bundle extras;
}
@@ -640,6 +640,7 @@ public class ConnectionServiceFixture implements TestFixture<IConnectionService>
c.videoProvider,
c.videoState,
c.connectTimeMillis,
+ c.connectElapsedTimeMillis,
c.statusHints,
c.extras);
}
@@ -660,6 +661,7 @@ public class ConnectionServiceFixture implements TestFixture<IConnectionService>
false, /* ringback requested */
false, /* voip audio mode */
0, /* Connect Time for conf call on this connection */
+ 0, /* Connect Real Time comes from conference call */
c.statusHints,
c.disconnectCause,
c.conferenceableConnectionIds,
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 205d7788..e51a9c75 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -65,11 +65,10 @@ 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.CallerInfoLookupHelper;
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.CallsManagerListenerBase;
+import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.HeadsetMediaButton;
import com.android.server.telecom.HeadsetMediaButtonFactory;
@@ -83,7 +82,6 @@ import com.android.server.telecom.ProximitySensorManager;
import com.android.server.telecom.ProximitySensorManagerFactory;
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.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
@@ -108,6 +106,16 @@ public class TelecomSystemTest extends TelecomTestCase {
static final int TEST_POLL_INTERVAL = 10; // milliseconds
static final int TEST_TIMEOUT = 1000; // milliseconds
+ // Purposely keep the connect time (which is wall clock) and elapsed time (which is time since
+ // boot) different to test that wall clock time operations and elapsed time operations perform
+ // as they individually should.
+ static final long TEST_CREATE_TIME = 100;
+ static final long TEST_CREATE_ELAPSED_TIME = 200;
+ static final long TEST_CONNECT_TIME = 1000;
+ static final long TEST_CONNECT_ELAPSED_TIME = 2000;
+ static final long TEST_DISCONNECT_TIME = 8000;
+ static final long TEST_DISCONNECT_ELAPSED_TIME = 4000;
+
public class HeadsetMediaButtonFactoryF implements HeadsetMediaButtonFactory {
@Override
public HeadsetMediaButton create(Context context, CallsManager callsManager,
@@ -194,6 +202,7 @@ public class TelecomSystemTest extends TelecomTestCase {
@Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
@Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
@Mock IncomingCallNotifier mIncomingCallNotifier;
+ @Mock ClockProxy mClockProxy;
final ComponentName mInCallServiceComponentNameX =
new ComponentName(
@@ -393,7 +402,9 @@ public class TelecomSystemTest extends TelecomTestCase {
when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
.thenReturn(TEST_TIMEOUT / 5L);
mIncomingCallNotifier = mock(IncomingCallNotifier.class);
-
+ mClockProxy = mock(ClockProxy.class);
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME);
mTelecomSystem = new TelecomSystem(
mComponentContextFixture.getTestDouble(),
new MissedCallNotifierImplFactory() {
@@ -426,7 +437,8 @@ public class TelecomSystemTest extends TelecomTestCase {
mAsyncRingtonePlayer,
mPhoneNumberUtilsAdapter,
mIncomingCallNotifier,
- (streamType, volume) -> mock(ToneGenerator.class));
+ (streamType, volume) -> mock(ToneGenerator.class),
+ mClockProxy);
mComponentContextFixture.setTelecomManager(new TelecomManager(
mComponentContextFixture.getTestDouble(),
@@ -891,6 +903,8 @@ public class TelecomSystemTest extends TelecomTestCase {
connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
connectionServiceFixture.sendSetActive(ids.mConnectionId);
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
@@ -928,6 +942,8 @@ public class TelecomSystemTest extends TelecomTestCase {
.answerVideo(eq(ids.mConnectionId), eq(videoState), any());
}
+ when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
+ when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
connectionServiceFixture.sendSetActive(ids.mConnectionId);
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());