Merge "Modified call settings styles to ensure actionbar coloring is consistent with the Dialer app. This required copying over some shared style information and icons from the Dialer."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2721a8b..93320f7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -64,6 +64,7 @@
     <uses-permission android:name="android.permission.WRITE_SMS" />
     <uses-permission android:name="android.permission.SEND_SMS" />
     <uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" />
+    <uses-permission android:name="android.permission.SET_TIME" />
     <uses-permission android:name="android.permission.SET_TIME_ZONE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index f12ceef..81d7167 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -46,7 +46,7 @@
     <string name="no_vm_number_msg" msgid="1300729501030053828">"በSIM ካርዱ ላይምንም የድምፅመልዕክት ቁጥር አልከተቀመጠም።"</string>
     <string name="add_vm_number_str" msgid="4676479471644687453">"ቁጥር አክል"</string>
     <string name="puk_unlocked" msgid="2284912838477558454">"የSIM ካርድዎ አልታገደም። ስልክዎ በመከፈት ላይነው..."</string>
-    <string name="label_ndp" msgid="780479633159517250">"የSIM አውታረመረብ መክፈቻ PIN"</string>
+    <string name="label_ndp" msgid="780479633159517250">"የSIM አውታረመረብ መክፈቻ ፒን"</string>
     <string name="sim_ndp_unlock_text" msgid="683628237760543009">"ክፈት"</string>
     <string name="sim_ndp_dismiss_text" msgid="1604823375752456947">"አጥፋ"</string>
     <string name="requesting_unlock" msgid="6412629401033249351">"አውታረመረብ ለማስከፈት በመጠየቅ ላይ..."</string>
@@ -310,7 +310,7 @@
     <string name="enable_fdn_ok" msgid="7215588870329688132">"FDN አታስችል"</string>
     <string name="disable_fdn_ok" msgid="5727046928930740173">"FDN አታስችል"</string>
     <string name="sum_fdn" msgid="1959399454900272878">"የቋሚ መደወያቁጥሮችአደራጅ"</string>
-    <string name="sum_fdn_change_pin" msgid="6666549734792827932">"ለFDN ድረስ PIN ለውጥ"</string>
+    <string name="sum_fdn_change_pin" msgid="6666549734792827932">"ለFDN ድረስ ፒን  ለውጥ"</string>
     <string name="sum_fdn_manage_list" msgid="8431088265332628316">"የስልክ ቁጥር ዝርዝር አደራጅ"</string>
     <string name="voice_privacy" msgid="3776841382844614716">"የድምፅ ብቸኝነት"</string>
     <string name="voice_privacy_summary" msgid="3159383389833516214">"የተሻሻለውን የብሕትውነት ሁነታ አስችል"</string>
@@ -342,27 +342,27 @@
     <string name="simContacts_empty" msgid="5270660846489561932">"በ SIM ካርድዎ ላይ ዕውቂያዎች የሉም።"</string>
     <string name="simContacts_title" msgid="1861472842524839921">"ለማስገባት ዕውቂያዎች ምረጥ"</string>
     <string name="simContacts_airplaneMode" msgid="1846161429087789936">"ከሲም ካርድ ላይ ዕውቂያዎችን ለማስመጣት፣ የአይሮፕላን ሁኔታን መጀመሪያ  አጥፋ፡፡"</string>
-    <string name="enable_pin" msgid="5422767284133234860">"SIM PIN አንቃ/አቦዝን"</string>
-    <string name="change_pin" msgid="9174186126330785343">"የSIM PIN ለውጥ"</string>
-    <string name="enter_pin_text" msgid="8532615714751931951">"SIM PIN:"</string>
-    <string name="oldPinLabel" msgid="5287773661246368314">"የድሮ PIN"</string>
+    <string name="enable_pin" msgid="5422767284133234860">"SIM ፒን  አንቃ/አቦዝን"</string>
+    <string name="change_pin" msgid="9174186126330785343">"የSIM ፒን  ለውጥ"</string>
+    <string name="enter_pin_text" msgid="8532615714751931951">"SIM ፒን :"</string>
+    <string name="oldPinLabel" msgid="5287773661246368314">"የድሮ ፒን"</string>
     <string name="newPinLabel" msgid="207488227285336897">"አዲስPIN"</string>
-    <string name="confirmPinLabel" msgid="257597715098070206">"አዲስ PIN አረጋግጥ"</string>
+    <string name="confirmPinLabel" msgid="257597715098070206">"አዲስ ፒን  አረጋግጥ"</string>
     <string name="badPin" msgid="8955102849303984935">"የተየበከው የድሮ ፒን ትክክል አይደለም። እባክህ እንደገና ሞክር።"</string>
     <string name="mismatchPin" msgid="5923253370683071889">"ያስገባኸው ፒኖች አይዛመዱም። እንደገና ሞክር።"</string>
-    <string name="invalidPin" msgid="5981171102258684792">"ከ4 እስከ 8 ቁጥሮች የያዘ PIN ተይብ"</string>
-    <string name="disable_sim_pin" msgid="3992926931620188855">"የSIM PIN አቦዝን"</string>
-    <string name="enable_sim_pin" msgid="5803702443844458831">"SIM PIN አንቃ"</string>
+    <string name="invalidPin" msgid="5981171102258684792">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን  ተይብ"</string>
+    <string name="disable_sim_pin" msgid="3992926931620188855">"የSIM ፒን  አቦዝን"</string>
+    <string name="enable_sim_pin" msgid="5803702443844458831">"SIM ፒን  አንቃ"</string>
     <string name="enable_in_progress" msgid="3695303775100109650">"እባክዎ ይጠብቁ…"</string>
-    <string name="enable_pin_ok" msgid="9166061915030865848">"SIM PIN ነቅቷል"</string>
+    <string name="enable_pin_ok" msgid="9166061915030865848">"SIM ፒን  ነቅቷል"</string>
     <string name="disable_pin_ok" msgid="5596999379593924850">"SIM ፒን  ቦዝኗል"</string>
-    <string name="pin_failed" msgid="2298841192582192277">"የተየብከው PIN የተሳሳተ ነበር።"</string>
-    <string name="pin_changed" msgid="4365538014588501049">"SIM PIN በተሳካ ተለውጧል"</string>
+    <string name="pin_failed" msgid="2298841192582192277">"የተየብከው ፒን  የተሳሳተ ነበር።"</string>
+    <string name="pin_changed" msgid="4365538014588501049">"SIM ፒን  በተሳካ ተለውጧል"</string>
     <string name="puk_requested" msgid="1796577128488773946">"የይለፍ ቃሉ የተሳሳተ ነው፣ ን ታግዷል! PUK ያስፈልጋል።"</string>
     <string name="enter_pin2_text" msgid="8339444124477720345">"PIN2"</string>
     <string name="oldPin2Label" msgid="8559146795026261502">"የድሮ PIN2"</string>
     <string name="newPin2Label" msgid="4573956902204349054">"አዲስPIN2"</string>
-    <string name="confirmPin2Label" msgid="8100319484454787708">"አዲስ PIN አረጋግጥ"</string>
+    <string name="confirmPin2Label" msgid="8100319484454787708">"አዲስ ፒን  አረጋግጥ"</string>
     <string name="badPuk2" msgid="4851734468010000418">"የተየብክው PUK2 ኮድ ትክክል አይደለም።እንደገና ሞክር።"</string>
     <string name="badPin2" msgid="1041576234483629991">"የተየብከው የድሮ PIN2 ትክክል አይደለም።እባክህ እንደገና ሞክር።"</string>
     <string name="mismatchPin2" msgid="523029155918113440">"ያስገባኸው PIN2 አይዛመድም። እንደገና ሞክር።"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index c452cd3..8771747 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -521,7 +521,7 @@
     <string name="pstn_phone" msgid="8782554491484326429">"Kupiga simu ya mkononi"</string>
     <string name="internet_phone" msgid="1147922660195095810">"Simu ya wavuti"</string>
     <string name="no_sip_account_found_title" msgid="6266249392379373628">"Hakuna akaunti ya upigaji simu wa Mtandao"</string>
-    <string name="no_sip_account_found" msgid="724325811961769997">"Hakuna akaunti za kupiga simu za mtandao kwenye simu hii. Je, unataka kuongeza moja sasa?"</string>
+    <string name="no_sip_account_found" msgid="724325811961769997">"Hakuna akaunti za kupiga simu za mtandao kwenye simu hii. Je, ungependa kuongeza akaunti sasa?"</string>
     <string name="sip_menu_add" msgid="8757508498518881500">"Ongeza"</string>
     <string name="add_sip_account" msgid="5904858426290097611">"Ongeza akaunti"</string>
     <string name="remove_sip_account" msgid="7645900420385682570">"Ondoa akaunti"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 25e7290..9178574 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -75,7 +75,7 @@
     <string name="sum_cw_disabled" msgid="3648693907300104575">"通話時如有來電請通知我"</string>
     <string name="call_forwarding_settings" msgid="3378927671091537173">"來電轉接設定"</string>
     <string name="labelCF" msgid="2574386948026924737">"來電轉接"</string>
-    <string name="labelCFU" msgid="8147177368148660600">"永遠轉接"</string>
+    <string name="labelCFU" msgid="8147177368148660600">"一律轉接"</string>
     <string name="messageCFU" msgid="3560082430662923687">"永遠使用此號碼"</string>
     <string name="sum_cfu_enabled_indicator" msgid="4014187342724130197">"轉接所有來電"</string>
     <string name="sum_cfu_enabled" msgid="2450052502198827927">"將所有來電轉接至 <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 7c8ace7..f5b6116 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -58,6 +58,7 @@
     public static final int RETRY_DELAY_MILLIS = 2000;
     public static final int RETRY_DELAY_LONG_MILLIS = 30 * 1000; // 30 seconds
     private static final int BIND_RETRY_MSG = 1;
+    private static final int BIND_TIME_OUT = 2;
     private static final int MAX_SHORT_DELAY_RETRY_COUNT = 5;
 
     private AudioRouter mAudioRouter;
@@ -79,8 +80,28 @@
 
         switch (msg.what) {
             case BIND_RETRY_MSG:
+                // Remove any pending messages since we're already performing the action.
+                // If the call to setupServiceConnection() fails, it will queue up another retry.
+                removeMessages(BIND_RETRY_MSG);
                 handleConnectRetry();
                 break;
+            case BIND_TIME_OUT:
+                // Remove any pending messages since we're already performing the action.
+                // If the call to setupServiceConnection() fails, it will queue up another retry.
+                removeMessages(BIND_TIME_OUT);
+                synchronized (mServiceAndQueueLock) {
+                    if(mCallHandlerServiceGuarded == null) {
+                        Log.w(TAG, "Binding time out. InCallUI did not respond in time.");
+                        try {
+                            mContext.unbindService(mConnection);
+                        } catch(Exception e) {
+                            Log.w(TAG, "unbindservice exception", e);
+                        }
+                        mConnection = null;
+                        handleConnectRetry();
+                    }
+                }
+                break;
         }
     }
 
@@ -290,6 +311,10 @@
                 Log.d(TAG, "Service Connected");
             }
             onCallHandlerServiceConnected(ICallHandlerService.Stub.asInterface(service));
+            removeMessages(BIND_TIME_OUT);
+            if (DBG) {
+                Log.d(TAG, "Service Connected. Cancel timer");
+            }
             resetConnectRetryCount();
         }
 
@@ -390,7 +415,9 @@
 
                 if (failedConnection) {
                     mConnection = null;
-                    enqueueConnectRetry();
+                    enqueueConnectRetry(BIND_RETRY_MSG);
+                } else {
+                    enqueueConnectRetry(BIND_TIME_OUT);
                 }
             } else {
                 Log.d(TAG, "Service connection to in call service already started.");
@@ -412,10 +439,6 @@
     }
 
     private void handleConnectRetry() {
-        // Remove any pending messages since we're already performing the action.
-        // If the call to setupServiceConnection() fails, it will queue up another retry.
-        removeMessages(BIND_RETRY_MSG);
-
         // Something else triggered the connection, cancel.
         if (mConnection != null) {
             Log.i(TAG, "Retry: already connected.");
@@ -449,14 +472,14 @@
      * Called after the connection failed and a retry is needed.
      * Queues up a retry to happen with a delay.
      */
-    private void enqueueConnectRetry() {
+    private void enqueueConnectRetry(int msg) {
         final boolean isLongDelay = (mBindRetryCount > MAX_SHORT_DELAY_RETRY_COUNT);
         final int delay = isLongDelay ? RETRY_DELAY_LONG_MILLIS : RETRY_DELAY_MILLIS;
 
         Log.w(TAG, "InCallUI Connection failed. Enqueuing delayed retry for " + delay + " ms." +
                 " retries(" + mBindRetryCount + ")");
 
-        sendEmptyMessageDelayed(BIND_RETRY_MSG, delay);
+        sendEmptyMessageDelayed(msg, delay);
     }
 
     private void unbind() {
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index 6e0c13e..0f6b1e0 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -46,30 +46,35 @@
 import com.android.internal.telephony.TelephonyCapabilities;
 
 /**
- * OutgoingCallBroadcaster receives CALL and CALL_PRIVILEGED Intents, and
- * broadcasts the ACTION_NEW_OUTGOING_CALL intent which allows other
- * applications to monitor, redirect, or prevent the outgoing call.
-
+ * OutgoingCallBroadcaster receives CALL and CALL_PRIVILEGED Intents, and broadcasts the
+ * ACTION_NEW_OUTGOING_CALL intent. ACTION_NEW_OUTGOING_CALL is an ordered broadcast intent which
+ * contains the phone number being dialed. Applications can use this intent to (1) see which numbers
+ * are being dialed, (2) redirect a call (change the number being dialed), or (3) prevent a call
+ * from being placed.
+ *
  * After the other applications have had a chance to see the
  * ACTION_NEW_OUTGOING_CALL intent, it finally reaches the
  * {@link OutgoingCallReceiver}, which passes the (possibly modified)
  * intent on to the {@link SipCallOptionHandler}, which will
  * ultimately start the call using the CallController.placeCall() API.
  *
- * Emergency calls and calls where no number is present (like for a CDMA
- * "empty flash" or a nonexistent voicemail number) are exempt from being
- * broadcast.
+ * Calls where no number is present (like for a CDMA "empty flash" or a nonexistent voicemail
+ * number) are exempt from being broadcast.
+ * Calls to emergency numbers are still broadcast for informative purposes. The call is placed
+ * prior to sending ACTION_NEW_OUTGOING_CALL and cannot be redirected nor prevented.
  */
 public class OutgoingCallBroadcaster extends Activity
         implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
 
-    private static final String PERMISSION = android.Manifest.permission.PROCESS_OUTGOING_CALLS;
     private static final String TAG = "OutgoingCallBroadcaster";
     private static final boolean DBG =
             (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
+    /** Required permission for any app that wants to consume ACTION_NEW_OUTGOING_CALL. */
+    private static final String PERMISSION = android.Manifest.permission.PROCESS_OUTGOING_CALLS;
+
     public static final String ACTION_SIP_SELECT_PHONE = "com.android.phone.SIP_SELECT_PHONE";
     public static final String EXTRA_ALREADY_CALLED = "android.phone.extra.ALREADY_CALLED";
     public static final String EXTRA_ORIGINAL_URI = "android.phone.extra.ORIGINAL_URI";
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 34ed832..ffae9ce 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -82,8 +82,10 @@
     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
     private static final int CMD_NV_RESET_CONFIG = 19;
     private static final int EVENT_NV_RESET_CONFIG_DONE = 20;
-    private static final int CMD_SET_RADIO_MODE = 21;
-    private static final int EVENT_SET_RADIO_MODE_DONE = 22;
+    private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
+    private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
+    private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
+    private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
 
 
     /** The singleton instance. */
@@ -341,6 +343,44 @@
                     handleNullReturnEvent(msg, "nvResetConfig");
                     break;
 
+                case CMD_GET_PREFERRED_NETWORK_TYPE:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
+                    mPhone.getPreferredNetworkType(onCompleted);
+                    break;
+
+                case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null && ar.result != null) {
+                        request.result = ar.result;     // Integer
+                    } else {
+                        request.result = -1;
+                        if (ar.result == null) {
+                            loge("getPreferredNetworkType: Empty response");
+                        } else if (ar.exception instanceof CommandException) {
+                            loge("getPreferredNetworkType: CommandException: " +
+                                    ar.exception);
+                        } else {
+                            loge("getPreferredNetworkType: Unknown exception");
+                        }
+                    }
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+
+                case CMD_SET_PREFERRED_NETWORK_TYPE:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
+                    int networkType = (Integer) request.argument;
+                    mPhone.setPreferredNetworkType(networkType, onCompleted);
+                    break;
+
+                case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
+                    handleNullReturnEvent(msg, "setPreferredNetworkType");
+                    break;
+
                 default:
                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
                     break;
@@ -1211,4 +1251,36 @@
         if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
         return success;
     }
+
+    /**
+     * Get the preferred network type.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @return the preferred network type, defined in RILConstants.java.
+     */
+    @Override
+    public int getPreferredNetworkType() {
+        enforceModifyPermission();
+        if (DBG) log("getPreferredNetworkType");
+        int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null);
+        int networkType = (result != null ? result[0] : -1);
+        if (DBG) log("getPreferredNetworkType: " + networkType);
+        return networkType;
+    }
+
+    /**
+     * Set the preferred network type.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param networkType the preferred network type, defined in RILConstants.java.
+     * @return true on success; false on any failure.
+     */
+    @Override
+    public boolean setPreferredNetworkType(int networkType) {
+        enforceModifyPermission();
+        if (DBG) log("setPreferredNetworkType: type " + networkType);
+        Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType);
+        if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
+        return success;
+    }
 }