Merge "Add USSD code running dialog to TeleService" into klp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d9576d5..4f9dbfb 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -91,6 +91,7 @@
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
 
     <!-- This tells the activity manager to not delay any of our activity
          start requests, even if they happen immediately after the user
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 2928bef..2569e3f 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -586,7 +586,7 @@
     <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Jeg ringer tilbage lige om lidt."</string>
     <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Jeg ringer til dig senere."</string>
     <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Kan ikke tale nu. Ringer du senere?"</string>
-    <string name="respond_via_sms_custom_message" msgid="6158880869935281078">"Skriv dit eget..."</string>
+    <string name="respond_via_sms_custom_message" msgid="6158880869935281078">"Skriv dit eget svar..."</string>
     <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Hurtige svar"</string>
     <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Rediger hurtige svar"</string>
     <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index f09e4d0..cf61a4d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -116,7 +116,7 @@
   </string-array>
     <string name="vm_changed" msgid="380744030726254139">"Pasikeitė balso pašto numeris."</string>
     <string name="vm_change_failed" msgid="3352934863246208918">"Balso pašto numerio pakeisti nepavyko.\nJei ši problema kartosis, kreipkitės į operatorių."</string>
-    <string name="fw_change_failed" msgid="5298103228470214665">"Persiuntimo numerio pakeisti nepavyko.\nJei ši problema kartosis, kreipkitės į operatorių."</string>
+    <string name="fw_change_failed" msgid="5298103228470214665">"Peradresavimo numerio pakeisti nepavyko.\nJei ši problema kartosis, kreipkitės į operatorių."</string>
     <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Nepavyko pateikti ir išsaugoti dabartinio peradresavimo numerio nustatymų.\nVis tiek perjungti naują teikėją?"</string>
     <string name="no_change" msgid="3186040086622435212">"Neatlikta jokių pakeitimų."</string>
     <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Pasirinkti balso pašto paslaugą"</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f4f4a31..59edb80 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -160,7 +160,7 @@
         <item name="android:windowCloseOnTouchOutside">true</item>
     </style>
 
-    <style name="SettingsLight" parent="@android:style/Theme.Holo.Light.DialogWhenLarge">
+    <style name="SettingsLight" parent="@android:style/Theme.Holo.Light">
         <item name="android:windowBackground">@color/phone_settings_background_color</item>
         <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
     </style>
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index 9f4bb76..e4ed147 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -36,6 +36,7 @@
 import com.android.services.telephony.common.Call.State;
 
 import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedSet;
@@ -46,6 +47,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -346,10 +348,14 @@
         PhoneGlobals.getInstance().updateWakeState();
     }
 
-
     /**
      * Go through the Calls from CallManager and return the list of calls that were updated.
-     * Or, the full list if requested.
+     * Method also finds any orphaned Calls (Connection objects no longer returned by telephony as
+     * either ringing, foreground, or background).  For each orphaned call, it sets the call state
+     * to IDLE and adds it to the list of calls to update.
+     *
+     * @param fullUpdate Add all calls to out parameter including those that have no updates.
+     * @param out List to populate with Calls that have been updated.
      */
     private void doUpdate(boolean fullUpdate, List<Call> out) {
         final List<com.android.internal.telephony.Call> telephonyCalls = Lists.newArrayList();
@@ -357,6 +363,14 @@
         telephonyCalls.addAll(mCallManager.getForegroundCalls());
         telephonyCalls.addAll(mCallManager.getBackgroundCalls());
 
+        // orphanedConnections starts out including all connections we know about.
+        // As we iterate through the connections we get from the telephony layer we
+        // prune this Set down to only the connections we have but telephony no longer
+        // recognizes.
+        final Set<Connection> orphanedConnections = Sets.newHashSet();
+        orphanedConnections.addAll(mCallMap.keySet());
+        orphanedConnections.addAll(mConfCallMap.keySet());
+
         // Cycle through all the Connections on all the Calls. Update our Call objects
         // to reflect any new state and send the updated Call objects to the handler service.
         for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
@@ -364,6 +378,10 @@
             for (Connection connection : telephonyCall.getConnections()) {
                 if (DBG) Log.d(TAG, "connection: " + connection + connection.getState());
 
+                if (orphanedConnections.contains(connection)) {
+                    orphanedConnections.remove(connection);
+                }
+
                 // We only send updates for live calls which are not incoming (ringing).
                 // Disconnected and incoming calls are handled by onDisconnect and
                 // onNewRingingConnection.
@@ -404,7 +422,26 @@
             for (Connection connection : telephonyCall.getConnections()) {
                 updateForConferenceCalls(connection, out);
             }
+        }
 
+        // Iterate through orphaned connections, set them to idle, and remove
+        // them from our internal structures.
+        for (Connection orphanedConnection : orphanedConnections) {
+            if (mCallMap.containsKey(orphanedConnection)) {
+                final Call call = mCallMap.get(orphanedConnection);
+                call.setState(Call.State.IDLE);
+                out.add(call);
+
+                mCallMap.remove(orphanedConnection);
+            }
+
+            if (mConfCallMap.containsKey(orphanedConnection)) {
+                final Call call = mCallMap.get(orphanedConnection);
+                call.setState(Call.State.IDLE);
+                out.add(call);
+
+                mConfCallMap.remove(orphanedConnection);
+            }
         }
     }
 
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
index 866f2be..47f0e54 100644
--- a/src/com/android/phone/EmergencyCallHelper.java
+++ b/src/com/android/phone/EmergencyCallHelper.java
@@ -20,7 +20,6 @@
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.phone.Constants.CallStatusCode;
 
 import android.content.Context;
 import android.content.Intent;
@@ -67,7 +66,6 @@
     private CallController mCallController;
     private PhoneGlobals mApp;
     private CallManager mCM;
-    private Phone mPhone;
     private String mNumber;  // The emergency number we're trying to dial
     private int mNumRetriesSoFar;
 
@@ -136,7 +134,7 @@
     /**
      * Actual implementation of startEmergencyCallFromAirplaneModeSequence(),
      * guaranteed to run on the handler thread.
-     * @see startEmergencyCallFromAirplaneModeSequence()
+     * @see #startEmergencyCallFromAirplaneModeSequence
      */
     private void startSequenceInternal(Message msg) {
         if (DBG) log("startSequenceInternal(): msg = " + msg);
@@ -153,9 +151,6 @@
 
         mNumRetriesSoFar = 0;
 
-        // Reset mPhone to whatever the current default phone is right now.
-        mPhone = mApp.mCM.getDefaultPhone();
-
         // Wake lock to make sure the processor doesn't go to sleep midway
         // through the emergency call sequence.
         PowerManager pm = (PowerManager) mApp.getSystemService(Context.POWER_SERVICE);
@@ -269,7 +264,7 @@
      */
     private void onRetryTimeout() {
         PhoneConstants.State phoneState = mCM.getState();
-        int serviceState = mPhone.getServiceState().getState();
+        int serviceState = mCM.getDefaultPhone().getServiceState().getState();
         if (DBG) log("onRetryTimeout():  phone state " + phoneState
                      + ", service state " + serviceState
                      + ", mNumRetriesSoFar = " + mNumRetriesSoFar);
@@ -346,7 +341,7 @@
             // in airplane mode.)  In this case just turn the radio
             // back on.
             if (DBG) log("==> (Apparently) not in airplane mode; manually powering radio on...");
-            mPhone.setRadioPower(true);
+            mCM.getDefaultPhone().setRadioPower(true);
         }
     }
 
@@ -370,7 +365,7 @@
 
         if (DBG) log("- placing call to '" + mNumber + "'...");
         int callStatus = PhoneUtils.placeCall(mApp,
-                                              mPhone,
+                                              mCM.getDefaultPhone(),
                                               mNumber,
                                               null,  // contactUri
                                               true); // isEmergencyCall
@@ -479,14 +474,16 @@
         // Unregister first, just to make sure we never register ourselves
         // twice.  (We need this because Phone.registerForServiceStateChanged()
         // does not prevent multiple registration of the same handler.)
-        mPhone.unregisterForServiceStateChanged(this);  // Safe even if not currently registered
-        mPhone.registerForServiceStateChanged(this, SERVICE_STATE_CHANGED, null);
+        Phone phone = mCM.getDefaultPhone();
+        phone.unregisterForServiceStateChanged(this);  // Safe even if not currently registered
+        phone.registerForServiceStateChanged(this, SERVICE_STATE_CHANGED, null);
     }
 
     private void unregisterForServiceStateChanged() {
         // This method is safe to call even if we haven't set mPhone yet.
-        if (mPhone != null) {
-            mPhone.unregisterForServiceStateChanged(this);  // Safe even if unnecessary
+        Phone phone = mCM.getDefaultPhone();
+        if (phone != null) {
+            phone.unregisterForServiceStateChanged(this);  // Safe even if unnecessary
         }
         removeMessages(SERVICE_STATE_CHANGED);  // Clean up any pending messages too
     }