Merge remote-tracking branch 'goog/mirror-m-wireless-internal-release' into master_merge

Change-Id: I5d9ab761a1060a24680e69d1610ade206660e139
diff --git a/Android.mk b/Android.mk
index d3c3316..b2fbc16 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,9 +14,6 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
-# Workaround for "local variable type mismatch" error.
-LOCAL_DX_FLAGS += --no-locals
-
 include $(BUILD_PACKAGE)
 
 # Build the test package.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bbdb9a4..73d5967 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -204,13 +204,15 @@
             </intent-filter>
         </receiver>
 
-        <activity android:name=".RespondViaSmsSettings$Settings"
+        <activity android:name=".RespondViaSmsSettings"
                   android:label="@string/respond_via_sms_setting_title"
                   android:configChanges="orientation|screenSize|keyboardHidden"
                   android:theme="@style/Theme.Telecom.DialerSettings"
                   android:process=":ui">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
 
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 14fc640..ecab9f0 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -39,6 +39,6 @@
     <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"لإجراء مكالمة، أدخل رقمًا صالحًا."</string>
     <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"لا يمكن إضافة مكالمة في الوقت الحالي."</string>
     <string name="no_vm_number" msgid="4164780423805688336">"رقم البريد الصوتي مفقود"</string>
-    <string name="no_vm_number_msg" msgid="1300729501030053828">"‏لم يتم تخزين رقم بريد صوتي على بطاقة SIM."</string>
+    <string name="no_vm_number_msg" msgid="1300729501030053828">"‏لم يتم تخزين رقم بريد صوتي على شريحة SIM."</string>
     <string name="add_vm_number_str" msgid="4676479471644687453">"إضافة رقم"</string>
 </resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..ae6fbb4
--- /dev/null
+++ b/res/values-en-rAU/strings.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="telecommAppLabel" product="default" msgid="3477737022166975496">"Phone"</string>
+    <string name="unknown" msgid="6878797917991465859">"Unknown"</string>
+    <string name="notification_missedCallTitle" msgid="7554385905572364535">"Missed call"</string>
+    <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Missed calls"</string>
+    <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> missed calls"</string>
+    <string name="notification_missedCallTicker" msgid="504686252427747209">"Missed call from <xliff:g id="MISSED_CALL_FROM">%s</xliff:g>"</string>
+    <string name="notification_missedCall_call_back" msgid="2684890353590890187">"Call back"</string>
+    <string name="notification_missedCall_message" msgid="3049928912736917988">"Message"</string>
+    <string name="accessibility_call_muted" msgid="2776111226185342220">"Call muted."</string>
+    <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"Speakerphone enabled."</string>
+    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Can\'t talk now. What\'s up?"</string>
+    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"I\'ll call you right back."</string>
+    <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"I\'ll call you later."</string>
+    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Can\'t talk now. Call me later?"</string>
+    <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Quick responses"</string>
+    <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edit quick responses"</string>
+    <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
+    <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Quick response"</string>
+    <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message sent to <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
+    <string name="outgoing_call_not_allowed" msgid="1435394568102165287">"Only emergency calls are allowed by the device owner"</string>
+    <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"To place a call, enter a valid number."</string>
+    <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"Call cannot be added at this time."</string>
+    <string name="no_vm_number" msgid="4164780423805688336">"Missing voicemail number"</string>
+    <string name="no_vm_number_msg" msgid="1300729501030053828">"No voicemail number is stored on the SIM card."</string>
+    <string name="add_vm_number_str" msgid="4676479471644687453">"Add number"</string>
+</resources>
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 8d1144d..1fb682f 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -30,13 +30,14 @@
  * This class manages audio modes, streams and other properties.
  */
 final class CallAudioManager extends CallsManagerListenerBase
-        implements WiredHeadsetManager.Listener {
+        implements WiredHeadsetManager.Listener, DockManager.Listener {
     private static final int STREAM_NONE = -1;
 
     private final StatusBarNotifier mStatusBarNotifier;
     private final AudioManager mAudioManager;
     private final BluetoothManager mBluetoothManager;
     private final WiredHeadsetManager mWiredHeadsetManager;
+    private final DockManager mDockManager;
     private final CallsManager mCallsManager;
 
     private AudioState mAudioState;
@@ -59,6 +60,8 @@
         mCallsManager = callsManager;
 
         mWiredHeadsetManager.addListener(this);
+        mDockManager = DockManager;
+        mDockManager.addListener(this);
 
         saveAudioState(getInitialAudioState(null));
         mAudioFocusStreamType = STREAM_NONE;
@@ -176,6 +179,27 @@
         setSystemAudioState(mAudioState.isMuted(), newRoute, calculateSupportedRoutes());
     }
 
+    @Override
+    public void onDockChanged(boolean isDocked) {
+        // This can happen even when there are no calls and we don't have focus.
+        if (!hasFocus()) {
+            return;
+        }
+
+        if (isDocked) {
+            // Device just docked, turn to speakerphone. Only do so if the route is currently
+            // earpiece so that we dont switch out of a BT headset or a wired headset.
+            if (mAudioState.route == AudioState.ROUTE_EARPIECE) {
+                setAudioRoute(AudioState.ROUTE_SPEAKER);
+            }
+        } else {
+            // Device just undocked, remove from speakerphone if possible.
+            if (mAudioState.route == AudioState.ROUTE_SPEAKER) {
+                setAudioRoute(AudioState.ROUTE_WIRED_OR_EARPIECE);
+            }
+        }
+    }
+
     void toggleMute() {
         mute(!mAudioState.isMuted());
     }
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 1a82498..7ec83cb 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -80,7 +80,7 @@
             clientExtras = intent.getBundleExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS);
         }
         if (clientExtras == null) {
-            clientExtras = Bundle.EMPTY;
+            clientExtras = new Bundle();
         }
 
         final boolean isDefaultDialer = intent.getBooleanExtra(KEY_IS_DEFAULT_DIALER, false);
@@ -125,7 +125,7 @@
             clientExtras = intent.getBundleExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS);
         }
         if (clientExtras == null) {
-            clientExtras = Bundle.EMPTY;
+            clientExtras = new Bundle();
         }
 
         Log.d(CallIntentProcessor.class,
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 781f2b1..22be8b3 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -140,7 +140,13 @@
 
         Log.d(TAG, "logNumber set to: %s", Log.pii(logNumber));
 
-        final PhoneAccountHandle accountHandle = call.getTargetPhoneAccount();
+        final PhoneAccountHandle emergencyAccountHandle =
+                TelephonyUtil.getDefaultEmergencyPhoneAccount().getAccountHandle();
+
+        PhoneAccountHandle accountHandle = call.getTargetPhoneAccount();
+        if (emergencyAccountHandle.equals(accountHandle)) {
+            accountHandle = null;
+        }
 
         // TODO(vt): Once data usage is available, wire it up here.
         int callFeatures = getCallFeatures(call.getVideoStateHistory());
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index aaa075a..df750c4 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -115,6 +115,7 @@
             new ConcurrentHashMap<CallsManagerListener, Boolean>(16, 0.9f, 1));
     private final HeadsetMediaButton mHeadsetMediaButton;
     private final WiredHeadsetManager mWiredHeadsetManager;
+    private final DockManager mDockManager;
     private final TtyManager mTtyManager;
     private final ProximitySensorManager mProximitySensorManager;
     private final PhoneStateBroadcaster mPhoneStateBroadcaster;
@@ -158,6 +159,7 @@
         mMissedCallNotifier = missedCallNotifier;
         StatusBarNotifier statusBarNotifier = new StatusBarNotifier(context, this);
         mWiredHeadsetManager = new WiredHeadsetManager(context);
+        mDockManager = new DockManager(context);
         mCallAudioManager = new CallAudioManager(
                 context, statusBarNotifier, mWiredHeadsetManager, this);
         InCallTonePlayer.Factory playerFactory = new InCallTonePlayer.Factory(mCallAudioManager);
@@ -611,9 +613,15 @@
 
         call.setHandle(uriHandle);
         call.setGatewayInfo(gatewayInfo);
-        call.setStartWithSpeakerphoneOn(speakerphoneOn);
         call.setVideoState(videoState);
 
+        if (speakerphoneOn) {
+            Log.i(this, "%s Starting with speakerphone as requested", call);
+        } else {
+            Log.i(this, "%s Starting with speakerphone because car is docked.", call);
+        }
+        call.setStartWithSpeakerphoneOn(speakerphoneOn || mDockManager.isDocked());
+
         boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext,
                 call.getHandle());
         if (isEmergencyCall) {
diff --git a/src/com/android/server/telecom/DockManager.java b/src/com/android/server/telecom/DockManager.java
new file mode 100644
index 0000000..e6ad446
--- /dev/null
+++ b/src/com/android/server/telecom/DockManager.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/** Listens for and caches car dock state. */
+class DockManager {
+    interface Listener {
+        void onDockChanged(boolean isDocked);
+    }
+
+    /** Receiver for car dock plugged and unplugged events. */
+    private class DockBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
+                int dockState = intent.getIntExtra(
+                        Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                onDockChanged(dockState);
+            }
+        }
+    }
+
+    private final DockBroadcastReceiver mReceiver;
+
+    /**
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Set<Listener> mListeners = Collections.newSetFromMap(
+            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
+
+    private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+
+    DockManager(Context context) {
+        mReceiver = new DockBroadcastReceiver();
+
+        // Register for misc other intent broadcasts.
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
+        context.registerReceiver(mReceiver, intentFilter);
+    }
+
+    void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    void removeListener(Listener listener) {
+        if (listener != null) {
+            mListeners.remove(listener);
+        }
+    }
+
+    boolean isDocked() {
+        switch (mDockState) {
+            case Intent.EXTRA_DOCK_STATE_DESK:
+            case Intent.EXTRA_DOCK_STATE_HE_DESK:
+            case Intent.EXTRA_DOCK_STATE_LE_DESK:
+            case Intent.EXTRA_DOCK_STATE_CAR:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private void onDockChanged(int dockState) {
+        if (mDockState != dockState) {
+            Log.v(this, "onDockChanged: is docked?%b", dockState == Intent.EXTRA_DOCK_STATE_CAR);
+            mDockState = dockState;
+            for (Listener listener : mListeners) {
+                listener.onDockChanged(isDocked());
+            }
+        }
+    }
+
+    /**
+     * Dumps the state of the {@link DockManager}.
+     *
+     * @param pw The {@code IndentingPrintWriter} to write the state to.
+     */
+    public void dump(IndentingPrintWriter pw) {
+        pw.println("mIsDocked: " + isDocked());
+    }
+}
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index a2441ce..c1cf7f8 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -105,7 +105,8 @@
             // Once the NEW_OUTGOING_CALL broadcast is finished, the resultData is used as the
             // actual number to call. (If null, no call will be placed.)
             String resultNumber = getResultData();
-            Log.v(this, "- got number from resultData: %s", Log.pii(resultNumber));
+            Log.i(this, "Received new-outgoing-call-broadcast for %s with data %s", mCall,
+                    Log.pii(resultNumber));
 
             boolean endEarly = false;
             if (resultNumber == null) {
@@ -255,6 +256,7 @@
             // initiate the call again because of the presence of the EXTRA_ALREADY_CALLED extra.
         }
 
+        Log.i(this, "Sending NewOutgoingCallBroadcast for %s", mCall);
         broadcastIntent(intent, number, !callImmediately);
         return DisconnectCause.NOT_DISCONNECTED;
     }
diff --git a/src/com/android/server/telecom/RespondViaSmsSettings.java b/src/com/android/server/telecom/RespondViaSmsSettings.java
index f5876a0..2283a88 100644
--- a/src/com/android/server/telecom/RespondViaSmsSettings.java
+++ b/src/com/android/server/telecom/RespondViaSmsSettings.java
@@ -27,105 +27,98 @@
 import android.view.Menu;
 import android.view.MenuItem;
 
-// TODO: Needed for move to system service: import com.android.internal.R;
+// TODO: This class is newly copied into Telecom (com.android.server.telecom) from it previous
+// location in Telephony (com.android.phone). User's preferences stored in the old location
+// will be lost. We need code here to migrate KLP -> LMP settings values.
 
 /**
- * Helper class to manage the "Respond via SMS Message" feature for incoming calls.
+ * Settings activity to manage the responses available for the "Respond via SMS Message" feature to
+ * respond to incoming calls.
  */
-public class RespondViaSmsSettings {
-    // TODO: This class is newly copied into Telecom (com.android.server.telecom) from it previous
-    // location in Telephony (com.android.phone). User's preferences stored in the old location
-    // will be lost. We need code here to migrate KLP -> LMP settings values.
+public class RespondViaSmsSettings extends PreferenceActivity
+        implements Preference.OnPreferenceChangeListener {
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.d(this, "Settings: onCreate()...");
 
-    /**
-     * Settings activity under "Call settings" to let you manage the
-     * canned responses; see respond_via_sms_settings.xml
-     */
-    public static class Settings extends PreferenceActivity
-            implements Preference.OnPreferenceChangeListener {
-        @Override
-        protected void onCreate(Bundle icicle) {
-            super.onCreate(icicle);
-            Log.d(this, "Settings: onCreate()...");
+        // This function guarantees that QuickResponses will be in our
+        // SharedPreferences with the proper values considering there may be
+        // old QuickResponses in Telephony pre L.
+        QuickResponseUtils.maybeMigrateLegacyQuickResponses(this);
 
-            // This function guarantees that QuickResponses will be in our
-            // SharedPreferences with the proper values considering there may be
-            // old QuickResponses in Telephony pre L.
-            QuickResponseUtils.maybeMigrateLegacyQuickResponses(this);
+        getPreferenceManager().setSharedPreferencesName(
+                QuickResponseUtils.SHARED_PREFERENCES_NAME);
 
-            getPreferenceManager().setSharedPreferencesName(
-                    QuickResponseUtils.SHARED_PREFERENCES_NAME);
+        // This preference screen is ultra-simple; it's just 4 plain
+        // <EditTextPreference>s, one for each of the 4 "canned responses".
+        //
+        // The only nontrivial thing we do here is copy the text value of
+        // each of those EditTextPreferences and use it as the preference's
+        // "title" as well, so that the user will immediately see all 4
+        // strings when they arrive here.
+        //
+        // Also, listen for change events (since we'll need to update the
+        // title any time the user edits one of the strings.)
 
-            // This preference screen is ultra-simple; it's just 4 plain
-            // <EditTextPreference>s, one for each of the 4 "canned responses".
-            //
-            // The only nontrivial thing we do here is copy the text value of
-            // each of those EditTextPreferences and use it as the preference's
-            // "title" as well, so that the user will immediately see all 4
-            // strings when they arrive here.
-            //
-            // Also, listen for change events (since we'll need to update the
-            // title any time the user edits one of the strings.)
+        addPreferencesFromResource(R.xml.respond_via_sms_settings);
 
-            addPreferencesFromResource(R.xml.respond_via_sms_settings);
+        EditTextPreference pref;
+        pref = (EditTextPreference) findPreference(
+                QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_1);
+        pref.setTitle(pref.getText());
+        pref.setOnPreferenceChangeListener(this);
 
-            EditTextPreference pref;
-            pref = (EditTextPreference) findPreference(
-                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_1);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
+        pref = (EditTextPreference) findPreference(
+                QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_2);
+        pref.setTitle(pref.getText());
+        pref.setOnPreferenceChangeListener(this);
 
-            pref = (EditTextPreference) findPreference(
-                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_2);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
+        pref = (EditTextPreference) findPreference(
+                QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_3);
+        pref.setTitle(pref.getText());
+        pref.setOnPreferenceChangeListener(this);
 
-            pref = (EditTextPreference) findPreference(
-                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_3);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
+        pref = (EditTextPreference) findPreference(
+                QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_4);
+        pref.setTitle(pref.getText());
+        pref.setOnPreferenceChangeListener(this);
 
-            pref = (EditTextPreference) findPreference(
-                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_4);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
-
-            ActionBar actionBar = getActionBar();
-            if (actionBar != null) {
-                // android.R.id.home will be triggered in onOptionsItemSelected()
-                actionBar.setDisplayHomeAsUpEnabled(true);
-            }
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
         }
+    }
 
-        // Preference.OnPreferenceChangeListener implementation
-        @Override
-        public boolean onPreferenceChange(Preference preference, Object newValue) {
-            Log.d(this, "onPreferenceChange: key = %s", preference.getKey());
-            Log.d(this, "  preference = '%s'", preference);
-            Log.d(this, "  newValue = '%s'", newValue);
+    // Preference.OnPreferenceChangeListener implementation
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        Log.d(this, "onPreferenceChange: key = %s", preference.getKey());
+        Log.d(this, "  preference = '%s'", preference);
+        Log.d(this, "  newValue = '%s'", newValue);
 
-            EditTextPreference pref = (EditTextPreference) preference;
+        EditTextPreference pref = (EditTextPreference) preference;
 
-            // Copy the new text over to the title, just like in onCreate().
-            // (Watch out: onPreferenceChange() is called *before* the
-            // Preference itself gets updated, so we need to use newValue here
-            // rather than pref.getText().)
-            pref.setTitle((String) newValue);
+        // Copy the new text over to the title, just like in onCreate().
+        // (Watch out: onPreferenceChange() is called *before* the
+        // Preference itself gets updated, so we need to use newValue here
+        // rather than pref.getText().)
+        pref.setTitle((String) newValue);
 
-            return true;  // means it's OK to update the state of the Preference with the new value
+        return true;  // means it's OK to update the state of the Preference with the new value
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        switch (itemId) {
+            case android.R.id.home:
+                goUpToTopLevelSetting(this);
+                return true;
+            default:
         }
-
-        @Override
-        public boolean onOptionsItemSelected(MenuItem item) {
-            final int itemId = item.getItemId();
-            switch (itemId) {
-                case android.R.id.home:
-                    goUpToTopLevelSetting(this);
-                    return true;
-                default:
-            }
-            return super.onOptionsItemSelected(item);
-        }
+        return super.onOptionsItemSelected(item);
     }
 
     /**
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index e987dee..08548f0 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -61,6 +61,7 @@
         </service>
 
         <activity android:name="com.android.server.telecom.testapps.TestCallActivity"
+                android:theme="@android:style/Theme.NoDisplay"
                 android:label="@string/testCallActivityLabel">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -82,40 +83,6 @@
                 <action android:name="com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT" />
             </intent-filter>
         </receiver>
-
-        <activity android:name="com.android.server.telecom.testapps.TestDialerActivity"
-                android:label="@string/testDialerActivityLabel"
-                android:process="com.android.server.telecom.testapps.TestInCallService">
-            <intent-filter>
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:mimeType="vnd.android.cursor.item/phone" />
-                <data android:mimeType="vnd.android.cursor.item/person" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="voicemail" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="tel" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
     </application>
 
     <!--
diff --git a/tests/src/com/android/server/telecom/testapps/TestConnectionService.java b/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
index 2e01276..196448f 100644
--- a/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ b/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -281,7 +281,8 @@
                     handle.getSchemeSpecificPart() + "..", ""),
                     originalRequest.getExtras(),
                     originalRequest.getVideoState());
-
+            connection.setVideoState(originalRequest.getVideoState());
+            maybeAddVideoProvider(connection);
             addCall(connection);
             connection.startOutgoing();
 
@@ -312,14 +313,6 @@
             Uri address = providedHandle == null ?
                     Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(isVideoCall), null)
                     : providedHandle;
-            if (isVideoCall) {
-                TestVideoProvider testVideoCallProvider =
-                        new TestVideoProvider(getApplicationContext());
-                connection.setVideoProvider(testVideoCallProvider);
-
-                // Keep reference to original so we can clean up the media players later.
-                connection.setTestVideoCallProvider(testVideoCallProvider);
-            }
 
             int videoState = isVideoCall ?
                     VideoProfile.VideoState.BIDIRECTIONAL :
@@ -327,6 +320,8 @@
             connection.setVideoState(videoState);
             connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
 
+            maybeAddVideoProvider(connection);
+
             addCall(connection);
 
             ConnectionRequest newRequest = new ConnectionRequest(
@@ -367,6 +362,17 @@
         }
     }
 
+    private void maybeAddVideoProvider(TestConnection connection) {
+        if (connection.getVideoState() == VideoProfile.VideoState.BIDIRECTIONAL) {
+            TestVideoProvider testVideoCallProvider =
+                    new TestVideoProvider(getApplicationContext());
+            connection.setVideoProvider(testVideoCallProvider);
+
+            // Keep reference to original so we can clean up the media players later.
+            connection.setTestVideoCallProvider(testVideoCallProvider);
+        }
+    }
+
     private void activateCall(TestConnection connection) {
         if (mMediaPlayer == null) {
             mMediaPlayer = createMediaPlayer();
@@ -386,7 +392,7 @@
         if (mCalls.isEmpty() && mMediaPlayer != null && mMediaPlayer.isPlaying()) {
             mMediaPlayer.stop();
             mMediaPlayer.release();
-            mMediaPlayer = createMediaPlayer();
+            mMediaPlayer = null;
         }
 
         updateConferenceable();
diff --git a/tests/src/com/android/server/telecom/testapps/TestDialerActivity.java b/tests/src/com/android/server/telecom/testapps/TestDialerActivity.java
deleted file mode 100644
index 7a9ed3f..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestDialerActivity.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.android.server.telecom.testapps;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.EditText;
-
-import com.android.server.telecom.tests.R;
-
-public class TestDialerActivity extends Activity {
-    private EditText mNumberView;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.testdialer_main);
-        findViewById(R.id.set_default_button).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                setDefault();
-            }
-        });
-        findViewById(R.id.place_call_button).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                placeCall();
-            }
-        });
-
-        mNumberView = (EditText) findViewById(R.id.number);
-        updateEditTextWithNumber();
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        updateEditTextWithNumber();
-    }
-
-    private void updateEditTextWithNumber() {
-        Intent intent = getIntent();
-        if (intent != null) {
-            mNumberView.setText(intent.getDataString());
-        }
-    }
-
-    private void setDefault() {
-        // TODO: Send a request to become the default dialer application
-    }
-
-    private void placeCall() {
-        // TODO: Place a call with the number entered in the number field
-    }
-}