Merge "Add a utility class for logging" into master-nova
diff --git a/src/com/android/telecomm/BinderDeallocator.java b/src/com/android/telecomm/BinderDeallocator.java
index ab7db25..fc57158 100644
--- a/src/com/android/telecomm/BinderDeallocator.java
+++ b/src/com/android/telecomm/BinderDeallocator.java
@@ -65,7 +65,7 @@
      * The set of all known binders, either in use or potentially about to be used.
      */
     @SuppressWarnings("rawtypes")
-    private Set<ServiceBinder> mBinders = Sets.newHashSet();
+    private final Set<ServiceBinder> mBinders = Sets.newHashSet();
 
     /**
      * Accounts for the action entering a critical section (i.e. potentially needing access to
@@ -87,7 +87,9 @@
     void updateBinders(Set<? extends ServiceBinder> binders) {
         ThreadUtil.checkOnMainThread();
 
-        mBinders.addAll(binders);
+        if (binders != null) {
+            mBinders.addAll(binders);
+        }
     }
 
     /**
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 1f9ffab..9347c2e 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -126,7 +126,12 @@
             return;
         }
 
+        Bundle clientExtras = Bundle.EMPTY;
+        if (intent.hasExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS)) {
+            clientExtras = intent.getBundleExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS);
+        }
+
         Log.d(TAG, "Processing incoming call from call service [" + descriptor + "]");
-        mCallsManager.processIncomingCallIntent(descriptor);
+        mCallsManager.processIncomingCallIntent(descriptor, clientExtras);
     }
 }
diff --git a/src/com/android/telecomm/CallServiceRepository.java b/src/com/android/telecomm/CallServiceRepository.java
index 5567e51..93f133f 100644
--- a/src/com/android/telecomm/CallServiceRepository.java
+++ b/src/com/android/telecomm/CallServiceRepository.java
@@ -52,13 +52,6 @@
 
     private static final String TAG = CallServiceRepository.class.getSimpleName();
 
-    /**
-     * The longest period in milliseconds each lookup cycle is allowed to span over, see
-     * {@link #mLookupTerminator}.
-     * TODO(gilad): Likely requires tuning.
-     */
-    private static final int LOOKUP_TIMEOUT_MS = 100;
-
     private final Switchboard mSwitchboard;
 
     private final OutgoingCallsManager mOutgoingCallsManager;
@@ -70,11 +63,12 @@
 
     /**
      * Used to interrupt lookup cycles that didn't terminate naturally within the allowed
-     * period, see LOOKUP_TIMEOUT_MS.
+     * period, see {@link Timeouts#getProviderLookupMs()}.
      */
     private final Runnable mLookupTerminator = new Runnable() {
         @Override
         public void run() {
+            Log.d(TAG, "Timed out processing providers");
             terminateLookup();
         }
     };
@@ -98,7 +92,7 @@
      * responses are received, the partial (potentially empty) set gets passed (to the switchboard)
      * instead. Entries are removed from this set as providers are processed.
      */
-    private Set<ComponentName> mOutstandingProviders;
+    private final Set<ComponentName> mOutstandingProviders = Sets.newHashSet();
 
     /**
      * The map of call-service wrappers keyed by their ComponentName.  Used to ensure at most one
@@ -107,7 +101,7 @@
      * include only active call services (ones that are associated with one or more active calls)
      * upon {@link #purgeInactiveCallServices()} invocations.
      */
-    private Map<ComponentName, CallServiceWrapper> mCallServices = Maps.newHashMap();
+    private final Map<ComponentName, CallServiceWrapper> mCallServices = Maps.newHashMap();
 
     /**
      * Persists the specified parameters.
@@ -149,7 +143,7 @@
         mLookupId = lookupId;
         mIsLookupInProgress = true;
 
-        mOutstandingProviders = Sets.newHashSet();
+        mOutstandingProviders.clear();
         for (ComponentName name : providerNames) {
             mOutstandingProviders.add(name);
             bindProvider(name);
@@ -158,8 +152,8 @@
         Log.i(TAG, "Found " + mOutstandingProviders.size() +
                 " implementations of ICallServiceProvider.");
 
-        // Schedule a lookup terminator to run after LOOKUP_TIMEOUT_MS milliseconds.
-        mHandler.postDelayed(mLookupTerminator, LOOKUP_TIMEOUT_MS);
+        // Schedule a lookup terminator to run after Timeouts.getProviderLookupMs() milliseconds.
+        mHandler.postDelayed(mLookupTerminator, Timeouts.getProviderLookupMs());
     }
 
     /**
@@ -347,7 +341,7 @@
      */
     private void terminateLookup() {
         mHandler.removeCallbacks(mLookupTerminator);
-        mOutstandingProviders = null;
+        mOutstandingProviders.clear();
 
         updateSwitchboard();
         mIsLookupInProgress = false;
diff --git a/src/com/android/telecomm/CallServiceSelectorRepository.java b/src/com/android/telecomm/CallServiceSelectorRepository.java
index 13249c5..d384604 100644
--- a/src/com/android/telecomm/CallServiceSelectorRepository.java
+++ b/src/com/android/telecomm/CallServiceSelectorRepository.java
@@ -46,13 +46,6 @@
     private static final String TAG = CallServiceSelectorRepository.class.getSimpleName();
 
     /**
-     * The longest period in milliseconds each lookup cycle is allowed to span over, see
-     * {@link #mLookupTerminator}.
-     * TODO(gilad): Likely requires tuning.
-     */
-    private static final int LOOKUP_TIMEOUT_MS = 100;
-
-    /**
      * Used to retrieve all known ICallServiceSelector implementations from the framework.
      */
     private static final String CALL_SERVICE_SELECTOR_CLASS_NAME =
@@ -60,11 +53,12 @@
 
     /**
      * Used to interrupt lookup cycles that didn't terminate naturally within the allowed
-     * period, see LOOKUP_TIMEOUT.
+     * period, see {@link Timeouts#getSelectorLookupMs()}.
      */
     private final Runnable mLookupTerminator = new Runnable() {
         @Override
         public void run() {
+            Log.d(TAG, "Timed out processing selectors");
             terminateLookup();
         }
     };
@@ -91,7 +85,7 @@
      * The set of bound call-service selectors.  Only populated via initiateLookup scenarios.
      * Selectors should only be removed upon unbinding.
      */
-    private Set<ICallServiceSelector> mSelectorRegistry = Sets.newHashSet();
+    private final Set<ICallServiceSelector> mSelectorRegistry = Sets.newHashSet();
 
     /**
      * Stores the names of the selectors to bind to in one lookup cycle.  The set size represents
@@ -103,7 +97,7 @@
      * selectors do not require finding and hence are excluded from this set.  Also note that
      * selectors are removed from this set as they register.
      */
-    private Set<ComponentName> mUnregisteredSelectors;
+    private final Set<ComponentName> mUnregisteredSelectors = Sets.newHashSet();
 
     /**
      * Persists the specified parameters and initializes the new instance.
@@ -136,7 +130,7 @@
 
         mLookupId = lookupId;
         mIsLookupInProgress = true;
-        mUnregisteredSelectors = Sets.newHashSet();
+        mUnregisteredSelectors.clear();
 
         for (ComponentName name : selectorNames) {
             if (!mSelectorRegistry.contains(name)) {
@@ -158,9 +152,10 @@
             // back to the switchboard.
             updateSwitchboard();
         } else {
-            // Schedule a lookup terminator to run after LOOKUP_TIMEOUT_MS milliseconds.
+            // Schedule a lookup terminator to run after Timeouts.getSelectorLookupMs()
+            // milliseconds.
             mHandler.removeCallbacks(mLookupTerminator);
-            mHandler.postDelayed(mLookupTerminator, LOOKUP_TIMEOUT_MS);
+            mHandler.postDelayed(mLookupTerminator, Timeouts.getSelectorLookupMs());
         }
     }
 
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
index bb9d649..067b715 100644
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ b/src/com/android/telecomm/CallServiceWrapper.java
@@ -16,16 +16,16 @@
 
 package com.android.telecomm;
 
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.telecomm.CallInfo;
+import android.telecomm.CallService;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.ICallService;
 import android.telecomm.ICallServiceAdapter;
 import android.util.Log;
 
-import com.android.telecomm.ServiceBinder.BindCallback;
-
 /**
  * Wrapper for {@link ICallService}s, handles binding to {@link ICallService} and keeps track of
  * when the object can safely be unbound. Other classes should not use {@link ICallService} directly
@@ -105,11 +105,11 @@
     }
 
     /** See {@link ICallService#setIncomingCallId}. */
-    public void setIncomingCallId(String callId) {
+    public void setIncomingCallId(String callId, Bundle extras) {
         if (isServiceValid("setIncomingCallId")) {
             mAdapter.addPendingIncomingCallId(callId);
             try {
-                mServiceInterface.setIncomingCallId(callId);
+                mServiceInterface.setIncomingCallId(callId, extras);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to setIncomingCallId for call " + callId, e);
                 mAdapter.removePendingIncomingCallId(callId);
@@ -155,13 +155,16 @@
      * call-service adapter using the specified call ID. Upon failure, the specified error callback
      * is invoked. Can be invoked even when the call service is unbound.
      *
-     * @param callID The call ID used for the incoming call.
+     * @param callId The call ID used for the incoming call.
+     * @param extras The {@link CallService}-provided extras which need to be sent back.
      * @param errorCallback The callback invoked upon failure.
      */
-    void retrieveIncomingCall(final String callId, final Runnable errorCallback) {
+    void retrieveIncomingCall(final String callId, final Bundle extras,
+            final Runnable errorCallback) {
+
         BindCallback callback = new BindCallback() {
             @Override public void onSuccess() {
-                setIncomingCallId(callId);
+                setIncomingCallId(callId, extras);
             }
             @Override public void onFailure() {
                 errorCallback.run();
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index a592ee3..7102cf4 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -16,6 +16,7 @@
 
 package com.android.telecomm;
 
+import android.os.Bundle;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.util.Log;
@@ -78,9 +79,9 @@
 
     private VoicemailManager mVoicemailManager;
 
-    private List<OutgoingCallValidator> mOutgoingCallValidators = Lists.newArrayList();
+    private final List<OutgoingCallValidator> mOutgoingCallValidators = Lists.newArrayList();
 
-    private List<IncomingCallValidator> mIncomingCallValidators = Lists.newArrayList();
+    private final List<IncomingCallValidator> mIncomingCallValidators = Lists.newArrayList();
 
     /**
      * Initializes the required Telecomm components.
@@ -101,15 +102,16 @@
      * to {@link #handleSuccessfulIncomingCall} to start the in-call UI.
      *
      * @param descriptor The descriptor of the call service to use for this incoming call.
+     * @param extras The optional extras Bundle passed with the intent used for the incoming call.
      */
-    void processIncomingCallIntent(CallServiceDescriptor descriptor) {
+    void processIncomingCallIntent(CallServiceDescriptor descriptor, Bundle extras) {
         Log.d(TAG, "processIncomingCallIntent");
         // Create a call with no handle. Eventually, switchboard will update the call with
         // additional information from the call service, but for now we just need one to pass around
         // with a unique call ID.
         Call call = new Call();
 
-        mSwitchboard.retrieveIncomingCall(call, descriptor);
+        mSwitchboard.retrieveIncomingCall(call, descriptor, extras);
     }
 
     /**
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 9faa472..170f66b 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -18,7 +18,6 @@
 
 import android.os.Handler;
 import android.os.Looper;
-import android.os.RemoteException;
 import android.telecomm.IInCallAdapter;
 import android.util.Log;
 
@@ -42,7 +41,7 @@
 
     /** {@inheritDoc} */
     @Override
-    public void answerCall(final String callId) throws RemoteException {
+    public void answerCall(final String callId) {
         Log.d(TAG, "answerCall(" + callId + ")");
         mHandler.post(new Runnable() {
             @Override public void run() {
@@ -53,7 +52,7 @@
 
     /** {@inheritDoc} */
     @Override
-    public void rejectCall(final String callId) throws RemoteException {
+    public void rejectCall(final String callId) {
         Log.d(TAG, "rejectCall(" + callId + ")");
         mHandler.post(new Runnable() {
             @Override public void run() {
@@ -64,12 +63,11 @@
 
     /** {@inheritDoc} */
     @Override
-    public void disconnectCall(final String callId) throws RemoteException {
+    public void disconnectCall(final String callId) {
         mHandler.post(new Runnable() {
             @Override public void run() {
                 mCallsManager.disconnectCall(callId);
             }
         });
     }
-
 }
diff --git a/src/com/android/telecomm/IncomingCallsManager.java b/src/com/android/telecomm/IncomingCallsManager.java
index 13f1319..d82a7de 100644
--- a/src/com/android/telecomm/IncomingCallsManager.java
+++ b/src/com/android/telecomm/IncomingCallsManager.java
@@ -16,7 +16,9 @@
 
 package com.android.telecomm;
 
+import android.os.Bundle;
 import android.telecomm.CallInfo;
+import android.telecomm.CallService;
 import android.util.Log;
 
 import com.google.common.base.Preconditions;
@@ -53,8 +55,10 @@
      * Starts the timeout sequence in case the call service is unresponsive.
      *
      * @param call The call object.
+     * @param extras The optional extras passed with the incoming call intent (to be returned to
+     *     the call service via {@link CallService#setIncomingCallId(String, android.os.Bundle)}).
      */
-    void retrieveIncomingCall(final Call call) {
+    void retrieveIncomingCall(final Call call, Bundle extras) {
         ThreadUtil.checkOnMainThread();
         Log.d(TAG, "retrieveIncomingCall");
 
@@ -71,7 +75,7 @@
         };
 
         // TODO(gilad): call.retrieve*Call() seems a bit unusual, consider revisiting.
-        call.getCallService().retrieveIncomingCall(callId, errorCallback);
+        call.getCallService().retrieveIncomingCall(callId, extras, errorCallback);
     }
 
     /**
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index a0875c9..42a16c6 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -175,10 +175,6 @@
         }
 
         mCall.setState(CallState.DIALING);
-
-        // TODO(gilad): Seems better/clearer not to invoke "abort" on successfully-connected calls.
-        abort();
-
         mSwitchboard.handleSuccessfulOutgoingCall(mCall);
     }
 
@@ -269,7 +265,7 @@
             return;
         }
 
-        if (mCallServiceDescriptorIterator.hasNext()) {
+        if (mCallServiceDescriptorIterator != null && mCallServiceDescriptorIterator.hasNext()) {
             CallServiceDescriptor descriptor = mCallServiceDescriptorIterator.next();
             final CallServiceWrapper callService =
                     mCallServicesById.get(descriptor.getCallServiceId());
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 4967c36..7587419 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -16,17 +16,17 @@
 
 package com.android.telecomm;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.ICallServiceSelector;
+import android.telecomm.TelecommConstants;
 import android.util.Log;
 
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -39,17 +39,6 @@
 final class Switchboard {
 
     private final static String TAG = Switchboard.class.getSimpleName();
-    /**
-     * The frequency of invoking tick in milliseconds.
-     * TODO(gilad): May require tuning.
-     */
-    private final static int TICK_FREQUENCY_MS = 250;
-
-    /**
-     * The timeout beyond which to drop ongoing attempts to place/receive calls.
-     * TODO(gilad): May require tuning.
-     */
-    private final static int NEW_CALL_TIMEOUT_MS = 5000;
 
     private final CallsManager mCallsManager;
 
@@ -92,14 +81,14 @@
      * {@link CallServiceRepository}.  Populated during call-service lookup cycles as part of the
      * {@link #placeOutgoingCall} flow and cleared upon zero-remaining new/pending outgoing calls.
      */
-    private Set<CallServiceWrapper> mCallServices;
+    private final Set<CallServiceWrapper> mCallServices = Sets.newHashSet();
 
     /**
      * The set of currently available call-service-selector implementations,
      * see {@link CallServiceSelectorRepository}.
-     * TODO(gilad): Null out once the active-call count goes to zero.
+     * TODO(gilad): Clear once the active-call count goes to zero.
      */
-    private Set<ICallServiceSelector> mSelectors;
+    private final Set<ICallServiceSelector> mSelectors = Sets.newHashSet();
 
     /**
      * The current lookup-cycle ID used with the repositories. Incremented with each invocation
@@ -137,8 +126,8 @@
         // reset, (5) the selector lookup completes but the call-services are missing.  This should
         // be okay since the call-service lookup completed. Specifically the already-available call
         // services are cached and will be provided in response to the second lookup cycle.
-        mCallServices = null;
-        mSelectors = null;
+        mCallServices.clear();
+        mSelectors.clear();
 
         mNewOutgoingCalls.add(call);
 
@@ -155,14 +144,16 @@
      *
      * @param call The call object.
      * @param descriptor The relevant call-service descriptor.
+     * @param extras The optional extras passed via
+     *     {@link TelecommConstants#EXTRA_INCOMING_CALL_EXTRAS}
      */
-    void retrieveIncomingCall(Call call, CallServiceDescriptor descriptor) {
+    void retrieveIncomingCall(Call call, CallServiceDescriptor descriptor, Bundle extras) {
         Log.d(TAG, "retrieveIncomingCall");
         mBinderDeallocator.acquireUsePermit();
 
         CallServiceWrapper callService = mCallServiceRepository.getCallService(descriptor);
         call.setCallService(callService);
-        mIncomingCallsManager.retrieveIncomingCall(call);
+        mIncomingCallsManager.retrieveIncomingCall(call, extras);
     }
 
     /**
@@ -176,7 +167,8 @@
     void setCallServices(Set<CallServiceWrapper> callServices) {
         mBinderDeallocator.updateBinders(mCallServices);
 
-        mCallServices = callServices;
+        mCallServices.clear();
+        mCallServices.addAll(callServices);
         processNewOutgoingCalls();
     }
 
@@ -198,7 +190,8 @@
         // emergency calls) and order the entire set prior to the assignment below. If the
         // built-in selectors can be implemented in a manner that does not require binding,
         // that's probably preferred.  May want to use a LinkedHashSet for the sorted set.
-        mSelectors = selectors;
+        mSelectors.clear();
+        mSelectors.addAll(selectors);
         processNewOutgoingCalls();
     }
 
@@ -272,14 +265,14 @@
      * Schedules the next tick invocation.
      */
     private void scheduleNextTick() {
-         mHandler.postDelayed(mTicker, TICK_FREQUENCY_MS);
+         mHandler.postDelayed(mTicker, Timeouts.getTickMs());
     }
 
     /**
      * Attempts to process the next new outgoing calls that have not yet been expired.
      */
     private void processNewOutgoingCalls() {
-        if (isNullOrEmpty(mCallServices) || isNullOrEmpty(mSelectors)) {
+        if (mCallServices.isEmpty() || mSelectors.isEmpty()) {
             // At least one call service and one selector are required to process outgoing calls.
             return;
         }
@@ -301,9 +294,6 @@
      * @param call The call to place.
      */
     private void processNewOutgoingCall(Call call) {
-        Preconditions.checkNotNull(mCallServices);
-        Preconditions.checkNotNull(mSelectors);
-
         // Convert to (duplicate-free) list to aid index-based iteration, see the comment under
         // setSelectors regarding using LinkedHashSet instead.
         List<ICallServiceSelector> selectors = Lists.newArrayList();
@@ -342,10 +332,12 @@
             return;
         }
 
+        final long newCallTimeoutMs = Timeouts.getNewOutgoingCallMs();
         Iterator<Call> iterator = calls.iterator();
         while (iterator.hasNext()) {
             Call call = iterator.next();
-            if (call.getAgeInMilliseconds() >= NEW_CALL_TIMEOUT_MS) {
+            if (call.getAgeInMilliseconds() >= newCallTimeoutMs) {
+                Log.d(TAG, "Call " + call.getId() + " timed out.");
                 mOutgoingCallsManager.abort(call);
                 calls.remove(call);
 
@@ -361,15 +353,4 @@
             }
         }
     }
-
-    /**
-     * Determines whether or not the specified collection is either null or empty.
-     *
-     * @param collection Either null or the collection object to be evaluated.
-     * @return True if the collection is null or empty.
-     */
-    @SuppressWarnings("rawtypes")
-    private boolean isNullOrEmpty(Collection collection) {
-        return collection == null || collection.isEmpty();
-    }
 }
diff --git a/src/com/android/telecomm/Timeouts.java b/src/com/android/telecomm/Timeouts.java
new file mode 100644
index 0000000..a69319d
--- /dev/null
+++ b/src/com/android/telecomm/Timeouts.java
@@ -0,0 +1,67 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+
+package com.android.telecomm;
+
+import android.provider.Settings;
+import android.telecomm.CallServiceProvider;
+import android.telecomm.CallServiceSelector;
+
+/**
+ * A helper class which serves only to make it easier to lookup timeout values. This class should
+ * never be instantiated, and only accessed through the {@link #get(String, long)} method.
+ *
+ * These methods are safe to call from any thread, including the UI thread.
+ */
+public final class Timeouts {
+    /** A prefix to use for all keys so to not clobber the global namespace. */
+    private static final String PREFIX = "telecomm.";
+
+    private Timeouts() {}
+
+    /**
+     * Returns the timeout value from Settings or the default value if it hasn't been changed. This
+     * method is safe to call from any thread, including the UI thread.
+     *
+     * @param key Settings key to retrieve.
+     * @param defaultValue Default value, in milliseconds.
+     * @return The timeout value from Settings or the default value if it hasn't been changed.
+     */
+    private static long get(String key, long defaultValue) {
+        return Settings.Secure.getLong(
+                TelecommApp.getInstance().getContentResolver(), PREFIX + key, defaultValue);
+    }
+
+    /**
+     * @return The longest period in milliseconds each {@link CallServiceProvider} lookup cycle is
+     *     allowed to span over.
+     */
+    public static long getProviderLookupMs() {
+        return get("provider_lookup_ms", 100);
+    }
+
+    /**
+     * @return The longest period in milliseconds each {@link CallServiceSelector} lookup cycle is
+     *     allowed to span over.
+     */
+    public static long getSelectorLookupMs() {
+        return get("selector_lookup_ms", 100);
+    }
+
+    /**
+     * @return How frequently, in milliseconds, to run {@link Switchboard}'s clean-up "tick" cycle.
+     */
+    public static long getTickMs() {
+        return get("tick_ms", 250);
+    }
+
+    /**
+     * Returns the longest period, in milliseconds, each new outgoing call is allowed to wait before
+     * being established. If the call does not connect before this time, abort the call.
+     *
+     * @return The longest period, in milliseconds, each new call is allowed to wait before being
+     *     established.
+     */
+    public static long getNewOutgoingCallMs() {
+        return get("new_outgoing_call_ms", 5000);
+    }
+}
diff --git a/tests/src/com/android/telecomm/testcallservice/TestCallService.java b/tests/src/com/android/telecomm/testcallservice/TestCallService.java
index 7c0d5c0..8fa1303 100644
--- a/tests/src/com/android/telecomm/testcallservice/TestCallService.java
+++ b/tests/src/com/android/telecomm/testcallservice/TestCallService.java
@@ -25,6 +25,7 @@
 
 import android.content.Intent;
 import android.media.MediaPlayer;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.telecomm.CallInfo;
 import android.telecomm.CallService;
@@ -117,21 +118,15 @@
 
     /** {@inheritDoc} */
     @Override
-    public void disconnect(String callId) {
-        Log.i(TAG, "disconnect(" + callId + ")");
-
-        try {
-            destroyCall(callId);
-            mCallsManagerAdapter.setDisconnected(callId);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to setDisconnected().", e);
-        }
+    public void abort(String callId) {
+        Log.i(TAG, "abort(" + callId + ")");
+        destroyCall(callId);
     }
 
     /** {@inheritDoc} */
     @Override
-    public void setIncomingCallId(String callId) {
-        Log.i(TAG, "setIncomingCallId(" + callId + ")");
+    public void setIncomingCallId(String callId, Bundle extras) {
+        Log.i(TAG, "setIncomingCallId(" + callId + ", " + extras + ")");
 
         // Use dummy number for testing incoming calls.
         String handle = "5551234";
@@ -166,6 +161,19 @@
 
     /** {@inheritDoc} */
     @Override
+    public void disconnect(String callId) {
+        Log.i(TAG, "disconnect(" + callId + ")");
+
+        destroyCall(callId);
+        try {
+            mCallsManagerAdapter.setDisconnected(callId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to setDisconnected().", e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
     public boolean onUnbind(Intent intent) {
         mMediaPlayer = null;