Telecomm: Use new InCallCall object
Change-Id: I3916e33e184f57bb6e58ed93a26b866d3ce0e7df
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 00ce14d..6aae5ca 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -28,7 +28,6 @@
import com.google.android.collect.Sets;
import com.google.common.base.Preconditions;
-import java.util.Date;
import java.util.Locale;
import java.util.Set;
@@ -50,7 +49,9 @@
* Beyond logging and such, may also be used for bookkeeping and specifically for marking
* certain call attempts as failed attempts.
*/
- private final Date mCreationTime;
+ private final long mCreationTimeMillis = System.currentTimeMillis();
+
+ private long mConnectTimeMillis;
/** The state of the call. */
private CallState mState;
@@ -86,7 +87,7 @@
* Disconnect cause for the call. Only valid if the state of the call is DISCONNECTED.
* See {@link android.telephony.DisconnectCause}.
*/
- private int mDisconnectCause;
+ private int mDisconnectCause = DisconnectCause.NOT_VALID;
/**
* Additional disconnect information provided by the call service.
@@ -94,7 +95,7 @@
private String mDisconnectMessage;
/** Info used by the call services. */
- private Bundle mExtras;
+ private Bundle mExtras = Bundle.EMPTY;
/** The Uri to dial to perform the handoff. If this is null then handoff is not supported. */
private Uri mHandoffHandle;
@@ -106,6 +107,12 @@
private Call mOriginalCall;
/**
+ * The descriptor for the call service that this call is being switched to, null if handoff is
+ * not in progress.
+ */
+ private CallServiceDescriptor mHandoffCallServiceDescriptor;
+
+ /**
* Creates an empty call object.
*
* @param isIncoming True if this is an incoming call.
@@ -128,9 +135,6 @@
mContactInfo = contactInfo;
mGatewayInfo = gatewayInfo;
mIsIncoming = isIncoming;
- mCreationTime = new Date();
- mDisconnectCause = DisconnectCause.NOT_VALID;
- mExtras = Bundle.EMPTY;
}
/** {@inheritDoc} */
@@ -218,18 +222,27 @@
/**
* @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 mCreationTime.
+ * period since this call was added to the set pending outgoing calls, see
+ * mCreationTimeMillis.
*/
- long getAgeMs() {
- return new Date().getTime() - mCreationTime.getTime();
+ long getAgeMillis() {
+ return System.currentTimeMillis() - mCreationTimeMillis;
}
/**
* @return The time when this call object was created and added to the set of pending outgoing
* calls.
*/
- long getCreationTimeMs() {
- return mCreationTime.getTime();
+ long getCreationTimeMillis() {
+ return mCreationTimeMillis;
+ }
+
+ long getConnectTimeMillis() {
+ return mConnectTimeMillis;
+ }
+
+ void setConnectTimeMillis(long connectTimeMillis) {
+ mConnectTimeMillis = connectTimeMillis;
}
CallServiceWrapper getCallService() {
@@ -472,6 +485,14 @@
mOriginalCall = originalCall;
}
+ CallServiceDescriptor getHandoffCallServiceDescriptor() {
+ return mHandoffCallServiceDescriptor;
+ }
+
+ void setHandoffCallServiceDescriptor(CallServiceDescriptor descriptor) {
+ mHandoffCallServiceDescriptor = descriptor;
+ }
+
/**
* @return True if the call is ringing, else logs the action name.
*/
diff --git a/src/com/android/telecomm/CallLogManager.java b/src/com/android/telecomm/CallLogManager.java
index 8bdc150..fcaf5f2 100644
--- a/src/com/android/telecomm/CallLogManager.java
+++ b/src/com/android/telecomm/CallLogManager.java
@@ -101,8 +101,8 @@
* {@link android.provider.CallLog.Calls#MISSED_TYPE}
*/
private void logCall(Call call, int callLogType) {
- final long creationTime = call.getCreationTimeMs();
- final long age = call.getAgeMs();
+ final long creationTime = call.getCreationTimeMillis();
+ final long age = call.getAgeMillis();
final ContactInfo contactInfo = call.getContactInfo(); // May be null.
final String logNumber = getLogNumber(call);
diff --git a/src/com/android/telecomm/CallServiceRepository.java b/src/com/android/telecomm/CallServiceRepository.java
index 7247259..50ef977 100644
--- a/src/com/android/telecomm/CallServiceRepository.java
+++ b/src/com/android/telecomm/CallServiceRepository.java
@@ -139,7 +139,7 @@
mOutstandingProviders.size());
// Schedule a timeout.
- mHandler.postDelayed(mTimeoutLookupTerminator, Timeouts.getProviderLookupMs());
+ mHandler.postDelayed(mTimeoutLookupTerminator, Timeouts.getProviderLookupMillis());
}
/**
@@ -168,8 +168,8 @@
// TODO(gilad): Either add ICallService.getActiveCallCount() or have this tracked by the
// Switchboard if we rather not rely on 3rd-party code to do the bookkeeping for us. If
- // we prefer the latter, we can also have purgeInactiveCallService(descriptor). Otherwise
- // this might look something like:
+ // we prefer the latter, we can also have purgeInactiveCallService(descriptor).
+ // Otherwise this might look something like:
//
// if (callService.getActiveCallCount() < 1) {
// mCallServices.remove(callServiceName);
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 1411270..e7ea621 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -23,6 +23,7 @@
import android.telecomm.CallServiceDescriptor;
import android.telecomm.CallState;
import android.telecomm.GatewayInfo;
+import android.telecomm.InCallCall;
import android.telephony.DisconnectCause;
import com.google.common.base.Preconditions;
@@ -51,9 +52,17 @@
void onCallAdded(Call call);
void onCallRemoved(Call call);
void onCallStateChanged(Call call, CallState oldState, CallState newState);
+ void onCallHandoffHandleChanged(Call call, Uri oldHandle, Uri newHandle);
+ void onCallServiceChanged(
+ Call call,
+ CallServiceWrapper oldCallService,
+ CallServiceWrapper newCallService);
+ void onCallHandoffCallServiceDescriptorChanged(
+ Call call,
+ CallServiceDescriptor oldDescriptor,
+ CallServiceDescriptor newDescriptor);
void onIncomingCallAnswered(Call call);
void onIncomingCallRejected(Call call);
- void onCallHandoffHandleChanged(Call call, Uri oldHandle, Uri newHandle);
void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall);
void onAudioStateChanged(CallAudioState oldAudioState, CallAudioState newAudioState);
}
@@ -231,6 +240,14 @@
*/
void handleSuccessfulOutgoingCall(Call call) {
Log.v(this, "handleSuccessfulOutgoingCall, %s", call);
+ if (mCalls.contains(call)) {
+ // The call's CallService has been updated.
+ for (CallsManagerListener listener : mListeners) {
+ listener.onCallServiceChanged(call, null, call.getCallService());
+ }
+ } else if (mPendingHandoffCalls.contains(call)) {
+ updateHandoffCallServiceDescriptor(call.getOriginalCall(), call);
+ }
}
/**
@@ -421,6 +438,9 @@
}
void markCallAsActive(Call call) {
+ if (call.getConnectTimeMillis() == 0) {
+ call.setConnectTimeMillis(System.currentTimeMillis());
+ }
setCallState(call, CallState.ACTIVE);
if (mPendingHandoffCalls.contains(call)) {
@@ -507,6 +527,7 @@
} else if (mPendingHandoffCalls.contains(call)) {
Log.v(this, "silently removing handoff call %s", call);
mPendingHandoffCalls.remove(call);
+ updateHandoffCallServiceDescriptor(call.getOriginalCall(), null);
}
// Only broadcast changes for calls that are being tracked.
@@ -527,6 +548,7 @@
private void setCallState(Call call, CallState newState) {
Preconditions.checkNotNull(newState);
CallState oldState = call.getState();
+ Log.i(this, "setCallState %s -> %s, call: %s", oldState, newState, call);
if (newState != oldState) {
// Unfortunately, in the telephony world the radio is king. So if the call notifies
// us that the call is in a particular state, we allow it even if it doesn't make
@@ -593,6 +615,8 @@
for (CallsManagerListener listener : mListeners) {
listener.onForegroundCallChanged(mForegroundCall, mForegroundCall);
}
+
+ updateHandoffCallServiceDescriptor(originalCall, null);
}
/** Makes sure there are no dangling handoff calls. */
@@ -614,6 +638,35 @@
}
}
+ private void updateHandoffCallServiceDescriptor(Call originalCall, Call handoffCall) {
+ Log.v(this, "updateHandoffCallServiceDescriptor, originalCall: %s, handoffCall: %s",
+ originalCall, handoffCall);
+ CallServiceDescriptor oldDescriptor = originalCall.getHandoffCallServiceDescriptor();
+ CallServiceDescriptor newDescriptor = null;
+ if (handoffCall != null && handoffCall.getCallService() != null) {
+ newDescriptor = handoffCall.getCallService().getDescriptor();
+ }
+ Log.v(this, "updateHandoffCallServiceDescriptor, pending descriptor: %s -> %s",
+ oldDescriptor, newDescriptor);
+
+ if (!areDescriptorsEqual(oldDescriptor, newDescriptor)) {
+ originalCall.setHandoffCallServiceDescriptor(newDescriptor);
+ for (CallsManagerListener listener : mListeners) {
+ listener.onCallHandoffCallServiceDescriptorChanged(originalCall, oldDescriptor,
+ newDescriptor);
+ }
+ }
+ }
+
+ private static boolean areDescriptorsEqual(
+ CallServiceDescriptor descriptor1,
+ CallServiceDescriptor descriptor2) {
+ if (descriptor1 == null) {
+ return descriptor2 == null;
+ }
+ return descriptor1.equals(descriptor2);
+ }
+
private static boolean areUriEqual(Uri handle1, Uri handle2) {
if (handle1 == null) {
return handle2 == null;
diff --git a/src/com/android/telecomm/CallsManagerListenerBase.java b/src/com/android/telecomm/CallsManagerListenerBase.java
index 6144651..8286857 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -18,6 +18,7 @@
import android.net.Uri;
import android.telecomm.CallAudioState;
+import android.telecomm.CallServiceDescriptor;
import android.telecomm.CallState;
/**
@@ -37,6 +38,24 @@
}
@Override
+ public void onCallHandoffHandleChanged(Call call, Uri oldHandle, Uri newHandle) {
+ }
+
+ @Override
+ public void onCallServiceChanged(
+ Call call,
+ CallServiceWrapper oldCallServiceWrapper,
+ CallServiceWrapper newCallService) {
+ }
+
+ @Override
+ public void onCallHandoffCallServiceDescriptorChanged(
+ Call call,
+ CallServiceDescriptor oldDescriptor,
+ CallServiceDescriptor newDescriptor) {
+ }
+
+ @Override
public void onIncomingCallAnswered(Call call) {
}
@@ -45,10 +64,6 @@
}
@Override
- public void onCallHandoffHandleChanged(Call call, Uri oldHandle, Uri newHandle) {
- }
-
- @Override
public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
}
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index beac0d5..395e92e 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -24,7 +24,10 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.telecomm.CallAudioState;
-import android.telecomm.CallInfo;
+import android.telecomm.CallCapabilities;
+import android.telecomm.CallServiceDescriptor;
+import android.telecomm.CallState;
+import android.telecomm.InCallCall;
import android.telecomm.CallState;
import com.android.internal.telecomm.IInCallService;
@@ -85,9 +88,8 @@
} else {
Log.i(this, "Adding call: %s", call);
mCallIdMapper.addCall(call);
- CallInfo callInfo = call.toCallInfo(mCallIdMapper.getCallId(call));
try {
- mInCallService.addCall(callInfo);
+ mInCallService.addCall(toInCallCall(call));
} catch (RemoteException e) {
}
}
@@ -104,47 +106,28 @@
@Override
public void onCallStateChanged(Call call, CallState oldState, CallState newState) {
- if (mInCallService == null) {
- return;
- }
-
- String callId = mCallIdMapper.getCallId(call);
- switch (newState) {
- case ACTIVE:
- Log.i(this, "Mark call as ACTIVE: %s", callId);
- try {
- mInCallService.setActive(callId);
- } catch (RemoteException e) {
- }
- break;
- case ON_HOLD:
- Log.i(this, "Mark call as HOLD: %s", callId);
- try {
- mInCallService.setOnHold(callId);
- } catch (RemoteException e) {
- }
- break;
- case DISCONNECTED:
- Log.i(this, "Mark call as DISCONNECTED: %s", callId);
- try {
- mInCallService.setDisconnected(callId, call.getDisconnectCause());
- } catch (RemoteException e) {
- }
- break;
- default:
- break;
- }
+ updateCall(call);
}
@Override
public void onCallHandoffHandleChanged(Call call, Uri oldHandle, Uri newHandle) {
- if (mInCallService != null) {
- try {
- mInCallService.setHandoffEnabled(mCallIdMapper.getCallId(call), newHandle != null);
- } catch (RemoteException e) {
- Log.e(this, e, "Exception attempting to call setHandoffEnabled.");
- }
- }
+ updateCall(call);
+ }
+
+ @Override
+ public void onCallServiceChanged(
+ Call call,
+ CallServiceWrapper oldCallServiceWrapper,
+ CallServiceWrapper newCallService) {
+ updateCall(call);
+ }
+
+ @Override
+ public void onCallHandoffCallServiceDescriptorChanged(
+ Call call,
+ CallServiceDescriptor oldDescriptor,
+ CallServiceDescriptor newDescriptor) {
+ updateCall(call);
}
@Override
@@ -219,7 +202,6 @@
if (!calls.isEmpty()) {
for (Call call : calls) {
onCallAdded(call);
- onCallHandoffHandleChanged(call, null, call.getHandoffHandle());
}
onAudioStateChanged(null, CallsManager.getInstance().getAudioState());
} else {
@@ -234,4 +216,36 @@
ThreadUtil.checkOnMainThread();
mInCallService = null;
}
+
+ private void updateCall(Call call) {
+ if (mInCallService != null) {
+ try {
+ mInCallService.updateCall(toInCallCall(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ private InCallCall toInCallCall(Call call) {
+ String callId = mCallIdMapper.getCallId(call);
+ CallServiceDescriptor descriptor =
+ call.getCallService() != null ? call.getCallService().getDescriptor() : null;
+
+ boolean isHandoffCapable = call.getHandoffHandle() != null;
+ int capabilities = CallCapabilities.HOLD | CallCapabilities.MUTE;
+ if (call.getHandoffHandle() != null) {
+ capabilities |= CallCapabilities.CONNECTION_HANDOFF;
+ }
+ CallState state = call.getState();
+ if (state == CallState.ABORTED) {
+ state = CallState.DISCONNECTED;
+ }
+ // TODO(sail): Remove this and replace with final reconnecting code.
+ if (state == CallState.DISCONNECTED && call.getHandoffCallServiceDescriptor() != null) {
+ state = CallState.ACTIVE;
+ }
+ return new InCallCall(callId, state, call.getDisconnectCause(), capabilities,
+ call.getConnectTimeMillis(), call.getHandle(), call.getGatewayInfo(), descriptor,
+ call.getHandoffCallServiceDescriptor());
+ }
}
diff --git a/src/com/android/telecomm/InCallTonePlayer.java b/src/com/android/telecomm/InCallTonePlayer.java
index 58e0423..258f8b0 100644
--- a/src/com/android/telecomm/InCallTonePlayer.java
+++ b/src/com/android/telecomm/InCallTonePlayer.java
@@ -65,7 +65,7 @@
// Buffer time (in msec) to add on to the tone timeout value. Needed mainly when the timeout
// value for a tone is exact duration of the tone itself.
- private static final int TIMEOUT_BUFFER_MS = 20;
+ private static final int TIMEOUT_BUFFER_MILLIS = 20;
// The tone state.
private static final int STATE_OFF = 0;
@@ -109,19 +109,19 @@
final int toneType; // Passed to ToneGenerator.startTone.
final int toneVolume; // Passed to the ToneGenerator constructor.
- final int toneLengthMs;
+ final int toneLengthMillis;
switch (mToneId) {
case TONE_BUSY:
// TODO: CDMA-specific tones
toneType = ToneGenerator.TONE_SUP_BUSY;
toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMs = 4000;
+ toneLengthMillis = 4000;
break;
case TONE_CALL_ENDED:
toneType = ToneGenerator.TONE_PROP_PROMPT;
toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMs = 4000;
+ toneLengthMillis = 4000;
break;
case TONE_OTA_CALL_ENDED:
// TODO: fill in
@@ -132,42 +132,42 @@
case TONE_CDMA_DROP:
toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE;
toneVolume = RELATIVE_VOLUME_LOPRI;
- toneLengthMs = 375;
+ toneLengthMillis = 375;
break;
case TONE_CONGESTION:
toneType = ToneGenerator.TONE_SUP_CONGESTION;
toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMs = 4000;
+ toneLengthMillis = 4000;
break;
case TONE_INTERCEPT:
toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT;
toneVolume = RELATIVE_VOLUME_LOPRI;
- toneLengthMs = 500;
+ toneLengthMillis = 500;
break;
case TONE_OUT_OF_SERVICE:
toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE;
toneVolume = RELATIVE_VOLUME_LOPRI;
- toneLengthMs = 375;
+ toneLengthMillis = 375;
break;
case TONE_REDIAL:
toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE;
toneVolume = RELATIVE_VOLUME_LOPRI;
- toneLengthMs = 5000;
+ toneLengthMillis = 5000;
break;
case TONE_REORDER:
toneType = ToneGenerator.TONE_CDMA_REORDER;
toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMs = 5000;
+ toneLengthMillis = 5000;
break;
case TONE_RING_BACK:
toneType = ToneGenerator.TONE_SUP_RINGTONE;
toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMs = Integer.MAX_VALUE - TIMEOUT_BUFFER_MS;
+ toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS;
break;
case TONE_UNOBTAINABLE_NUMBER:
toneType = ToneGenerator.TONE_SUP_ERROR;
toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMs = 4000;
+ toneLengthMillis = 4000;
break;
case TONE_VOICE_PRIVACY:
// TODO: fill in.
@@ -202,8 +202,8 @@
toneGenerator.startTone(toneType);
try {
Log.v(this, "Starting tone %d...waiting for %d ms.", mToneId,
- toneLengthMs + TIMEOUT_BUFFER_MS);
- wait(toneLengthMs + TIMEOUT_BUFFER_MS);
+ toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
+ wait(toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
} catch (InterruptedException e) {
Log.w(this, "wait interrupted", e);
}
diff --git a/src/com/android/telecomm/MissedCallNotifier.java b/src/com/android/telecomm/MissedCallNotifier.java
index 8100472..9414030 100644
--- a/src/com/android/telecomm/MissedCallNotifier.java
+++ b/src/com/android/telecomm/MissedCallNotifier.java
@@ -106,7 +106,7 @@
// Create the notification.
Notification.Builder builder = new Notification.Builder(mContext);
builder.setSmallIcon(android.R.drawable.stat_notify_missed_call)
- .setWhen(call.getCreationTimeMs())
+ .setWhen(call.getCreationTimeMillis())
.setContentTitle(mContext.getText(titleResId))
.setContentText(expandedText)
.setContentIntent(createCallLogPendingIntent())
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 66e1269..bd6b449 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -264,7 +264,7 @@
* Schedules the next tick invocation.
*/
private void scheduleNextTick() {
- mHandler.postDelayed(mTicker, Timeouts.getTickMs());
+ mHandler.postDelayed(mTicker, Timeouts.getTickMillis());
}
/**
@@ -359,11 +359,11 @@
return;
}
- final long newCallTimeoutMs = Timeouts.getNewOutgoingCallMs();
+ final long newCallTimeoutMillis = Timeouts.getNewOutgoingCallMillis();
Iterator<Call> iterator = calls.iterator();
while (iterator.hasNext()) {
Call call = iterator.next();
- if (call.getAgeMs() >= newCallTimeoutMs) {
+ if (call.getAgeMillis() >= newCallTimeoutMillis) {
Log.d(this, "Call %s timed out.", call);
mOutgoingCallsManager.abort(call);
calls.remove(call);
diff --git a/src/com/android/telecomm/TelephonyUtil.java b/src/com/android/telecomm/TelephonyUtil.java
index be501f0..bffe7eb 100644
--- a/src/com/android/telecomm/TelephonyUtil.java
+++ b/src/com/android/telecomm/TelephonyUtil.java
@@ -26,7 +26,7 @@
* differently from 3rd party services in some situations (emergency calls, audio focus, etc...).
*/
public final class TelephonyUtil {
- private static final String TAG = ThreadUtil.class.getSimpleName();
+ private static final String TAG = TelephonyUtil.class.getSimpleName();
private static final String TELEPHONY_PACKAGE_NAME =
"com.android.phone";
diff --git a/src/com/android/telecomm/Timeouts.java b/src/com/android/telecomm/Timeouts.java
index 4096c02..4f8dc1c 100644
--- a/src/com/android/telecomm/Timeouts.java
+++ b/src/com/android/telecomm/Timeouts.java
@@ -49,14 +49,14 @@
* @return The longest period in milliseconds each {@link CallServiceProvider} lookup cycle is
* allowed to span over.
*/
- public static long getProviderLookupMs() {
+ public static long getProviderLookupMillis() {
return get("provider_lookup_ms", 1000);
}
/**
* @return How frequently, in milliseconds, to run {@link Switchboard}'s clean-up "tick" cycle.
*/
- public static long getTickMs() {
+ public static long getTickMillis() {
return get("tick_ms", 250);
}
@@ -67,7 +67,7 @@
* @return The longest period, in milliseconds, each new call is allowed to wait before being
* established.
*/
- public static long getNewOutgoingCallMs() {
+ public static long getNewOutgoingCallMillis() {
return get("new_outgoing_call_ms", 5000);
}
}