am 0255f595: Merge "ApnEditor changes to support bearer as a bitmask." into mnc-dev

* commit '0255f595bd5ffbf39601296ac708130fccfc02ed':
  ApnEditor changes to support bearer as a bitmask.
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 032382e..3aff578 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -526,18 +526,57 @@
 
     <!-- Bearer Info used in APN editor -->
     <string-array name="bearer_entries">
-        <item>LTE</item>
-        <item>eHRPD</item>
         <item>Unspecified</item>
+        <item>LTE</item>
+        <item>HSPAP</item>
+        <item>HSPA</item>
+        <item>HSUPA</item>
+        <item>HSDPA</item>
+        <item>UMTS</item>
+        <item>EDGE</item>
+        <item>GPRS</item>
+        <item>eHRPD</item>
+        <item>EVDO_B</item>
+        <item>EVDO_A</item>
+        <item>EVDO_0</item>
+        <item>1xRTT</item>
+        <item>IS95B</item>
+        <item>IS95A</item>
     </string-array>
 
     <string-array translatable="false" name="bearer_values">
         <!-- Do not translate. -->
+        <item>0</item>
+        <!-- Do not translate. -->
         <item>14</item>
         <!-- Do not translate. -->
+        <item>15</item>
+        <!-- Do not translate. -->
+        <item>11</item>
+        <!-- Do not translate. -->
+        <item>10</item>
+        <!-- Do not translate. -->
+        <item>9</item>
+        <!-- Do not translate. -->
+        <item>3</item>
+        <!-- Do not translate. -->
+        <item>2</item>
+        <!-- Do not translate. -->
+        <item>1</item>
+        <!-- Do not translate. -->
         <item>13</item>
         <!-- Do not translate. -->
-        <item>0</item>
+        <item>12</item>
+        <!-- Do not translate. -->
+        <item>8</item>
+        <!-- Do not translate. -->
+        <item>7</item>
+        <!-- Do not translate. -->
+        <item>6</item>
+        <!-- Do not translate. -->
+        <item>5</item>
+        <!-- Do not translate. -->
+        <item>4</item>
     </string-array>
 
     <!-- MVNO Info used in APN editor -->
diff --git a/res/xml/apn_editor.xml b/res/xml/apn_editor.xml
index 979e1da..a05d547 100644
--- a/res/xml/apn_editor.xml
+++ b/res/xml/apn_editor.xml
@@ -135,9 +135,9 @@
         android:summaryOn="@string/carrier_enabled_summaryOn"
         android:summaryOff="@@string/carrier_enabled_summaryOff"
         />
-    <ListPreference
+    <MultiSelectListPreference
         android:title="@string/bearer"
-        android:key="bearer"
+        android:key="bearer_multi"
         android:entries="@array/bearer_entries"
         android:entryValues="@array/bearer_values"
         />
@@ -154,4 +154,4 @@
         android:singleLine="true"
         android:inputType="text"
         />
-</PreferenceScreen>   
+</PreferenceScreen>
diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java
index f8db3d8..a040a91 100644
--- a/src/com/android/settings/ApnEditor.java
+++ b/src/com/android/settings/ApnEditor.java
@@ -28,18 +28,23 @@
 import android.os.Bundle;
 import android.preference.EditTextPreference;
 import android.preference.ListPreference;
+import android.preference.MultiSelectListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.SwitchPreference;
 import android.provider.Telephony;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import com.android.internal.logging.MetricsLogger;
 
+import java.util.HashSet;
+import java.util.Set;
 
 public class ApnEditor extends InstrumentedPreferenceActivity
         implements SharedPreferences.OnSharedPreferenceChangeListener,
@@ -52,7 +57,7 @@
     private final static String KEY_PROTOCOL = "apn_protocol";
     private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol";
     private final static String KEY_CARRIER_ENABLED = "carrier_enabled";
-    private final static String KEY_BEARER = "bearer";
+    private final static String KEY_BEARER_MULTI = "bearer_multi";
     private final static String KEY_MVNO_TYPE = "mvno_type";
 
     private static final int MENU_DELETE = Menu.FIRST;
@@ -78,7 +83,7 @@
     private ListPreference mProtocol;
     private ListPreference mRoamingProtocol;
     private SwitchPreference mCarrierEnabled;
-    private ListPreference mBearer;
+    private MultiSelectListPreference mBearerMulti;
     private ListPreference mMvnoType;
     private EditTextPreference mMvnoMatchData;
 
@@ -92,6 +97,7 @@
     private int mSubId;
     private Resources mRes;
     private TelephonyManager mTelephonyManager;
+    private int mBearerInitialVal = 0;
 
     /**
      * Standard projection for the interesting columns of a normal note.
@@ -116,9 +122,10 @@
             Telephony.Carriers.PROTOCOL, // 16
             Telephony.Carriers.CARRIER_ENABLED, // 17
             Telephony.Carriers.BEARER, // 18
-            Telephony.Carriers.ROAMING_PROTOCOL, // 19
-            Telephony.Carriers.MVNO_TYPE,   // 20
-            Telephony.Carriers.MVNO_MATCH_DATA  // 21
+            Telephony.Carriers.BEARER_BITMASK, // 19
+            Telephony.Carriers.ROAMING_PROTOCOL, // 20
+            Telephony.Carriers.MVNO_TYPE,   // 21
+            Telephony.Carriers.MVNO_MATCH_DATA  // 22
     };
 
     private static final int ID_INDEX = 0;
@@ -139,9 +146,10 @@
     private static final int PROTOCOL_INDEX = 16;
     private static final int CARRIER_ENABLED_INDEX = 17;
     private static final int BEARER_INDEX = 18;
-    private static final int ROAMING_PROTOCOL_INDEX = 19;
-    private static final int MVNO_TYPE_INDEX = 20;
-    private static final int MVNO_MATCH_DATA_INDEX = 21;
+    private static final int BEARER_BITMASK_INDEX = 19;
+    private static final int ROAMING_PROTOCOL_INDEX = 20;
+    private static final int MVNO_TYPE_INDEX = 21;
+    private static final int MVNO_MATCH_DATA_INDEX = 22;
 
 
     @Override
@@ -176,8 +184,8 @@
 
         mCarrierEnabled = (SwitchPreference) findPreference(KEY_CARRIER_ENABLED);
 
-        mBearer = (ListPreference) findPreference(KEY_BEARER);
-        mBearer.setOnPreferenceChangeListener(this);
+        mBearerMulti = (MultiSelectListPreference) findPreference(KEY_BEARER_MULTI);
+        mBearerMulti.setOnPreferenceChangeListener(this);
 
         mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE);
         mMvnoType.setOnPreferenceChangeListener(this);
@@ -289,7 +297,31 @@
             mProtocol.setValue(mCursor.getString(PROTOCOL_INDEX));
             mRoamingProtocol.setValue(mCursor.getString(ROAMING_PROTOCOL_INDEX));
             mCarrierEnabled.setChecked(mCursor.getInt(CARRIER_ENABLED_INDEX)==1);
-            mBearer.setValue(mCursor.getString(BEARER_INDEX));
+            mBearerInitialVal = mCursor.getInt(BEARER_INDEX);
+
+            HashSet<String> bearers = new HashSet<String>();
+            int bearerBitmask = mCursor.getInt(BEARER_BITMASK_INDEX);
+            if (bearerBitmask == 0) {
+                if (mBearerInitialVal == 0) {
+                    bearers.add("" + 0);
+                }
+            } else {
+                int i = 1;
+                while (bearerBitmask != 0) {
+                    if ((bearerBitmask & 1) == 1) {
+                        bearers.add("" + i);
+                    }
+                    bearerBitmask >>= 1;
+                    i++;
+                }
+            }
+
+            if (mBearerInitialVal != 0 && bearers.contains("" + mBearerInitialVal) == false) {
+                // add mBearerInitialVal to bearers
+                bearers.add("" + mBearerInitialVal);
+            }
+            mBearerMulti.setValues(bearers);
+
             mMvnoType.setValue(mCursor.getString(MVNO_TYPE_INDEX));
             mMvnoMatchData.setEnabled(false);
             mMvnoMatchData.setText(mCursor.getString(MVNO_MATCH_DATA_INDEX));
@@ -324,8 +356,8 @@
                 checkNull(protocolDescription(mProtocol.getValue(), mProtocol)));
         mRoamingProtocol.setSummary(
                 checkNull(protocolDescription(mRoamingProtocol.getValue(), mRoamingProtocol)));
-        mBearer.setSummary(
-                checkNull(bearerDescription(mBearer.getValue())));
+        mBearerMulti.setSummary(
+                checkNull(bearerMultiDescription(mBearerMulti.getValues())));
         mMvnoType.setSummary(
                 checkNull(mvnoDescription(mMvnoType.getValue())));
         mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText()));
@@ -358,7 +390,7 @@
     }
 
     private String bearerDescription(String raw) {
-        int mBearerIndex = mBearer.findIndexOfValue(raw);
+        int mBearerIndex = mBearerMulti.findIndexOfValue(raw);
         if (mBearerIndex == -1) {
             return null;
         } else {
@@ -371,6 +403,30 @@
         }
     }
 
+    private String bearerMultiDescription(Set<String> raw) {
+        String[] values = mRes.getStringArray(R.array.bearer_entries);
+        StringBuilder retVal = new StringBuilder();
+        boolean first = true;
+        for (String bearer : raw) {
+            int bearerIndex = mBearerMulti.findIndexOfValue(bearer);
+            try {
+                if (first) {
+                    retVal.append(values[bearerIndex]);
+                    first = false;
+                } else {
+                    retVal.append(", " + values[bearerIndex]);
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // ignore
+            }
+        }
+        String val = retVal.toString();
+        if (!TextUtils.isEmpty(val)) {
+            return val;
+        }
+        return null;
+    }
+
     private String mvnoDescription(String newValue) {
         int mvnoIndex = mMvnoType.findIndexOfValue(newValue);
         String oldValue = mMvnoType.getValue();
@@ -429,13 +485,13 @@
             }
             mRoamingProtocol.setSummary(protocol);
             mRoamingProtocol.setValue((String) newValue);
-        } else if (KEY_BEARER.equals(key)) {
-            String bearer = bearerDescription((String) newValue);
+        } else if (KEY_BEARER_MULTI.equals(key)) {
+            String bearer = bearerMultiDescription((Set<String>) newValue);
             if (bearer == null) {
                 return false;
             }
-            mBearer.setValue((String) newValue);
-            mBearer.setSummary(bearer);
+            mBearerMulti.setValues((Set<String>) newValue);
+            mBearerMulti.setSummary(bearer);
         } else if (KEY_MVNO_TYPE.equals(key)) {
             String mvno = mvnoDescription((String) newValue);
             if (mvno == null) {
@@ -536,7 +592,7 @@
 
         ContentValues values = new ContentValues();
 
-        // Add a dummy name "Untitled", if the user exits the screen without adding a name but 
+        // Add a dummy name "Untitled", if the user exits the screen without adding a name but
         // entered other information worth keeping.
         values.put(Telephony.Carriers.NAME,
                 name.length() < 1 ? getResources().getString(R.string.untitled_apn) : name);
@@ -571,10 +627,30 @@
             }
         }
 
-        String bearerVal = mBearer.getValue();
-        if (bearerVal != null) {
-            values.put(Telephony.Carriers.BEARER, Integer.parseInt(bearerVal));
+        Set<String> bearerSet = mBearerMulti.getValues();
+        int bearerBitmask = 0;
+        for (String bearer : bearerSet) {
+            if (Integer.parseInt(bearer) == 0) {
+                bearerBitmask = 0;
+                break;
+            } else {
+                bearerBitmask |= ServiceState.getBitmaskForTech(Integer.parseInt(bearer));
+            }
         }
+        values.put(Telephony.Carriers.BEARER_BITMASK, bearerBitmask);
+
+        int bearerVal;
+        if (bearerBitmask == 0 || mBearerInitialVal == 0) {
+            bearerVal = 0;
+        } else if (ServiceState.bitmaskHasTech(bearerBitmask, mBearerInitialVal)) {
+            bearerVal = mBearerInitialVal;
+        } else {
+            // bearer field was being used but bitmask has changed now and does not include the
+            // initial bearer value -- setting bearer to 0 but maybe better behavior is to choose a
+            // random tech from the new bitmask??
+            bearerVal = 0;
+        }
+        values.put(Telephony.Carriers.BEARER, bearerVal);
 
         values.put(Telephony.Carriers.MVNO_TYPE, checkNotSet(mMvnoType.getValue()));
         values.put(Telephony.Carriers.MVNO_MATCH_DATA, checkNotSet(mMvnoMatchData.getText()));