resolved conflicts for merge e994d46a
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 237b8df..6052bda 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -402,7 +402,7 @@
                     case Phone.NT_MODE_GLOBAL:
                     case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
                     case Phone.NT_MODE_LTE_GSM_WCDMA:
-                    case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+                    case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
                     case Phone.NT_MODE_LTE_ONLY:
                     case Phone.NT_MODE_LTE_WCDMA:
                         // This is one of the modes we recognize
@@ -437,7 +437,7 @@
                     case Phone.NT_MODE_WCDMA_PREF:
                     case Phone.NT_MODE_GSM_ONLY:
                     case Phone.NT_MODE_LTE_GSM_WCDMA:
-                    case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+                    case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
                     case Phone.NT_MODE_CDMA:
                     case Phone.NT_MODE_CDMA_NO_EVDO:
                     case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
@@ -514,7 +514,7 @@
                         modemNetworkMode == Phone.NT_MODE_GLOBAL ||
                         modemNetworkMode == Phone.NT_MODE_LTE_CDMA_AND_EVDO ||
                         modemNetworkMode == Phone.NT_MODE_LTE_GSM_WCDMA ||
-                        modemNetworkMode == Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA ||
+                        modemNetworkMode == Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA ||
                         modemNetworkMode == Phone.NT_MODE_LTE_ONLY ||
                         modemNetworkMode == Phone.NT_MODE_LTE_WCDMA) {
                     if (DBG) {
@@ -637,7 +637,7 @@
                 mButtonPreferredNetworkMode.setSummary(
                         R.string.preferred_network_mode_lte_cdma_evdo_summary);
                 break;
-            case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+            case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
                 mButtonPreferredNetworkMode.setSummary(
                         R.string.preferred_network_mode_global_summary);
                 break;
@@ -666,7 +666,7 @@
                     mButtonEnabledNetworks.setSummary(R.string.network_3G);
                 } else {
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA));
+                            Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                     mButtonEnabledNetworks.setSummary(R.string.network_global);
                 }
                 break;
@@ -677,7 +677,7 @@
                     mButtonEnabledNetworks.setSummary(R.string.network_2G);
                 } else {
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA));
+                            Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                     mButtonEnabledNetworks.setSummary(R.string.network_global);
                 }
                 break;
@@ -691,7 +691,7 @@
                             ? R.string.network_4G : R.string.network_lte);
                 } else {
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA));
+                            Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                     mButtonEnabledNetworks.setSummary(R.string.network_global);
                 }
                 break;
@@ -712,9 +712,9 @@
                         Integer.toString(Phone.NT_MODE_CDMA_NO_EVDO));
                 mButtonEnabledNetworks.setSummary(R.string.network_1x);
                 break;
-            case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+            case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
                 mButtonEnabledNetworks.setValue(
-                        Integer.toString(Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA));
+                        Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                 mButtonEnabledNetworks.setSummary(R.string.network_global);
                 break;
             default:
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 02dea1c..2d0597d 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -33,28 +33,30 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.telephony.NeighboringCellInfo;
 import android.telephony.CellInfo;
+import android.telephony.NeighboringCellInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.DefaultPhoneNotifier;
-import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.IThirdPartyCallProvider;
+import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.thirdpartyphone.ThirdPartyPhone;
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccController;
+import com.android.internal.util.HexDump;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Implementation of the ITelephony interface.
@@ -77,7 +79,19 @@
     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
     private static final int CMD_CLOSE_CHANNEL = 11;
     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
-    private static final int CMD_NEW_INCOMING_THIRD_PARTY_CALL = 13;
+    // TODO: Remove this.
+    private static final int CMD_NEW_INCOMING_THIRD_PARTY_CALL = 100;
+    private static final int CMD_NV_READ_ITEM = 13;
+    private static final int EVENT_NV_READ_ITEM_DONE = 14;
+    private static final int CMD_NV_WRITE_ITEM = 15;
+    private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
+    private static final int CMD_NV_WRITE_CDMA_PRL = 17;
+    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;
+
 
     /** The singleton instance. */
     private static PhoneInterfaceManager sInstance;
@@ -158,8 +172,7 @@
             switch (msg.what) {
                 case CMD_HANDLE_PIN_MMI:
                     request = (MainThreadRequest) msg.obj;
-                    request.result = Boolean.valueOf(
-                            mPhone.handlePinMmi((String) request.argument));
+                    request.result = mPhone.handlePinMmi((String) request.argument);
                     // Wake up the requesting thread
                     synchronized (request) {
                         request.notifyAll();
@@ -180,7 +193,7 @@
                         request.result = ar.result;
                     } else {
                         // create an empty list to notify the waiting thread
-                        request.result = new ArrayList<NeighboringCellInfo>();
+                        request.result = new ArrayList<NeighboringCellInfo>(0);
                     }
                     // Wake up the requesting thread
                     synchronized (request) {
@@ -198,7 +211,7 @@
 
                 case CMD_END_CALL:
                     request = (MainThreadRequest) msg.obj;
-                    boolean hungUp = false;
+                    boolean hungUp;
                     int phoneType = mPhone.getPhoneType();
                     if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                         // CDMA: If the user presses the Power button we treat it as
@@ -246,10 +259,9 @@
                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
                         if (ar.result == null) {
                             loge("iccTransmitApduLogicalChannel: Empty response");
-                        } else if (ar.exception != null &&
-                            (ar.exception instanceof CommandException)) {
+                        } else if (ar.exception instanceof CommandException) {
                             loge("iccTransmitApduLogicalChannel: CommandException: " +
-                                    (CommandException)ar.exception);
+                                    ar.exception);
                         } else {
                             loge("iccTransmitApduLogicalChannel: Unknown exception");
                         }
@@ -270,15 +282,14 @@
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
                     if (ar.exception == null && ar.result != null) {
-                        request.result = new Integer(((int[])ar.result)[0]);
+                        request.result = ((int[]) ar.result)[0];
                     } else {
-                        request.result = new Integer(-1);
+                        request.result = -1;
                         if (ar.result == null) {
                             loge("iccOpenLogicalChannel: Empty response");
-                        } else if (ar.exception != null &&
-                            (ar.exception instanceof CommandException)) {
+                        } else if (ar.exception instanceof CommandException) {
                             loge("iccOpenLogicalChannel: CommandException: " +
-                                    (CommandException)ar.exception);
+                                    ar.exception);
                         } else {
                             loge("iccOpenLogicalChannel: Unknown exception");
                         }
@@ -293,22 +304,34 @@
                     onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE,
                             request);
                     UiccController.getInstance().getUiccCard().iccCloseLogicalChannel(
-                            ((Integer)request.argument).intValue(),
+                            (Integer) request.argument,
                             onCompleted);
                     break;
 
                 case EVENT_CLOSE_CHANNEL_DONE:
+                    handleNullReturnEvent(msg, "iccCloseLogicalChannel");
+                    break;
+
+                case CMD_NV_READ_ITEM:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
+                    mPhone.nvReadItem((Integer) request.argument, onCompleted);
+                    break;
+
+                case EVENT_NV_READ_ITEM_DONE:
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
-                    if (ar.exception == null) {
-                        request.result = new Boolean(true);
+                    if (ar.exception == null && ar.result != null) {
+                        request.result = ar.result;     // String
                     } else {
-                        request.result = new Boolean(false);
-                        if (ar.exception instanceof CommandException) {
-                            loge("iccCloseLogicalChannel: CommandException: " +
-                                    (CommandException)ar.exception);
+                        request.result = "";
+                        if (ar.result == null) {
+                            loge("nvReadItem: Empty response");
+                        } else if (ar.exception instanceof CommandException) {
+                            loge("nvReadItem: CommandException: " +
+                                    ar.exception);
                         } else {
-                            loge("iccCloseLogicalChannel: Unknown exception");
+                            loge("nvReadItem: Unknown exception");
                         }
                     }
                     synchronized (request) {
@@ -316,11 +339,70 @@
                     }
                     break;
 
+                case CMD_NV_WRITE_ITEM:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
+                    Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
+                    mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted);
+                    break;
+
+                case EVENT_NV_WRITE_ITEM_DONE:
+                    handleNullReturnEvent(msg, "nvWriteItem");
+                    break;
+
+                case CMD_NV_WRITE_CDMA_PRL:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
+                    mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
+                    break;
+
+                case EVENT_NV_WRITE_CDMA_PRL_DONE:
+                    handleNullReturnEvent(msg, "nvWriteCdmaPrl");
+                    break;
+
+                case CMD_NV_RESET_CONFIG:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
+                    mPhone.nvResetConfig((Integer) request.argument, onCompleted);
+                    break;
+
+                case EVENT_NV_RESET_CONFIG_DONE:
+                    handleNullReturnEvent(msg, "nvResetConfig");
+                    break;
+
+                case CMD_SET_RADIO_MODE:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_SET_RADIO_MODE_DONE, request);
+                    mPhone.setRadioMode((Integer) request.argument, onCompleted);
+                    break;
+
+                case EVENT_SET_RADIO_MODE_DONE:
+                    handleNullReturnEvent(msg, "setRadioMode");
+                    break;
+
                 default:
                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
                     break;
             }
         }
+
+        private void handleNullReturnEvent(Message msg, String command) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+            MainThreadRequest request = (MainThreadRequest) ar.userObj;
+            if (ar.exception == null) {
+                request.result = true;
+            } else {
+                request.result = false;
+                if (ar.exception instanceof CommandException) {
+                    loge(command + ": CommandException: " + ar.exception);
+                } else {
+                    loge(command + ": Unknown exception");
+                }
+            }
+            synchronized (request) {
+                request.notifyAll();
+            }
+        }
     }
 
     /**
@@ -795,7 +877,7 @@
                 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
         }
 
-        if (checkIfCallerIsSelfOrForegoundUser()) {
+        if (checkIfCallerIsSelfOrForegroundUser()) {
             if (DBG_LOC) log("getCellLocation: is active user");
             Bundle data = new Bundle();
             mPhone.getCellLocation().fillInNotifierBundle(data);
@@ -839,7 +921,7 @@
                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
             return null;
         }
-        if (checkIfCallerIsSelfOrForegoundUser()) {
+        if (checkIfCallerIsSelfOrForegroundUser()) {
             if (DBG_LOC) log("getNeighboringCellInfo: is active user");
 
             ArrayList<NeighboringCellInfo> cells = null;
@@ -871,7 +953,7 @@
                 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
         }
 
-        if (checkIfCallerIsSelfOrForegoundUser()) {
+        if (checkIfCallerIsSelfOrForegroundUser()) {
             if (DBG_LOC) log("getAllCellInfo: is active user");
             return mPhone.getAllCellInfo();
         } else {
@@ -901,7 +983,7 @@
     // Internal helper methods.
     //
 
-    private boolean checkIfCallerIsSelfOrForegoundUser() {
+    private static boolean checkIfCallerIsSelfOrForegroundUser() {
         boolean ok;
 
         boolean self = Binder.getCallingUid() == Process.myUid();
@@ -974,9 +1056,7 @@
             return null;
         }
 
-        StringBuilder buf = new StringBuilder("tel:");
-        buf.append(number);
-        return buf.toString();
+        return "tel:" + number;
     }
 
     private static void log(String msg) {
@@ -1067,7 +1147,7 @@
      * the mode may be unknown.
      *
      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link PHone#LTE_ON_CDMA_TRUE}
+     * or {@link Phone#LTE_ON_CDMA_TRUE}
      */
     public int getLteOnCdmaMode() {
         return mPhone.getLteOnCdmaMode();
@@ -1102,7 +1182,7 @@
         if (DBG) log("iccOpenLogicalChannel: " + AID);
         Integer channel = (Integer)sendRequest(CMD_OPEN_CHANNEL, AID);
         if (DBG) log("iccOpenLogicalChannel: " + channel);
-        return channel.intValue();
+        return channel;
     }
 
     @Override
@@ -1113,8 +1193,7 @@
         if (channel < 0) {
           return false;
         }
-        Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL,
-            new Integer(channel));
+        Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel);
         if (DBG) log("iccCloseLogicalChannel: " + success);
         return success;
     }
@@ -1150,4 +1229,87 @@
         s = IccUtils.bytesToHexString(response.payload) + s;
         return s;
     }
+
+    /**
+     * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
+     * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read
+     * @return the NV item as a String, or null on error.
+     */
+    @Override
+    public String nvReadItem(int itemID) {
+        enforceModifyPermission();
+        if (DBG) log("nvReadItem: item " + itemID);
+        String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID);
+        if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
+        return value;
+    }
+
+    /**
+     * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
+     * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read
+     * @param itemValue the value to write, as a String
+     * @return true on success; false on any failure
+     */
+    @Override
+    public boolean nvWriteItem(int itemID, String itemValue) {
+        enforceModifyPermission();
+        if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
+        Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
+                new Pair<Integer, String>(itemID, itemValue));
+        if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
+        return success;
+    }
+
+    /**
+     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param preferredRoamingList byte array containing the new PRL
+     * @return true on success; false on any failure
+     */
+    @Override
+    public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
+        enforceModifyPermission();
+        if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
+        Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
+        if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
+        return success;
+    }
+
+    /**
+     * Perform the specified type of NV config reset.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
+     * @return true on success; false on any failure
+     */
+    @Override
+    public boolean nvResetConfig(int resetType) {
+        enforceModifyPermission();
+        if (DBG) log("nvResetConfig: type " + resetType);
+        Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
+        if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
+        return success;
+    }
+
+    /**
+     * Change the radio to the specified mode.
+     * Used for device configuration by some operators.
+     *
+     * @param radioMode is 0 for offline mode, 1 for online mode, 2 for low-power mode,
+     *                  or 3 to reset the radio.
+     * @return true on success; false on any failure
+     */
+    @Override
+    public boolean setRadioMode(int radioMode) {
+        enforceModifyPermission();
+        if (DBG) log("setRadioMode: mode " + radioMode);
+        Boolean success = (Boolean) sendRequest(CMD_SET_RADIO_MODE, radioMode);
+        if (DBG) log("setRadioMode: mode " + radioMode + ' ' + (success ? "ok" : "fail"));
+        return success;
+    }
 }