Merge branch 'master' of ssh://android-git.corp.google.com:29418/platform/frameworks/base
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5bd8308..6512006 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1968,8 +1968,11 @@
     <!-- This string appears (on two lines) when you type a number into contacts search, to let you create a contact whose phone number is the number you typed.  The first line will be in bigger type than the second. -->
     <string name="create_contact_using">Create contact\nusing <xliff:g id="number" example="555">%s</xliff:g></string>
 
-    <!-- This string array should be overridden by the manufacture to present a list of carrier-id,locale pairs.  This is used at startup to set a default locale by checking the system property ro.carrier for the carrier-id and searching through this array -->
-    <string-array translatable="false" name="carrier_locales">
+    <!-- This string array should be overridden by the manufacture to present a list of carrier-id,locale,wifi-channel sets.  This is used at startup to set system defaults by checking the system property ro.carrier for the carrier-id and searching through this array -->
+    <!-- An Array of [[Carrier-ID]                     -->
+    <!--              [default-locale]                 -->
+    <!--              [default-wifi-allowed-channels]] -->
+    <string-array translatable="false" name="carrier_properties">
     </string-array>
 
      <!-- Title for the selected state of a CompoundButton. -->
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5fa8701..64d1ba2 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1360,14 +1360,17 @@
      * Set the number of radio frequency channels that are allowed to be used
      * in the current regulatory domain. This method should be used only
      * if the correct number of channels cannot be determined automatically
-     * for some reason. If the operation is successful, the new value is
+     * for some reason. If the operation is successful, the new value may be
      * persisted as a Secure setting.
      * @param numChannels the number of allowed channels. Must be greater than 0
      * and less than or equal to 16.
+     * @param persist {@code true} if the setting should be remembered.
      * @return {@code true} if the operation succeeds, {@code false} otherwise, e.g.,
      * {@code numChannels} is outside the valid range.
      */
-    public boolean setNumAllowedChannels(int numChannels) {
+    public boolean setNumAllowedChannels(int numChannels, boolean persist) {
+        Log.i(TAG, "WifiService trying to setNumAllowed to "+numChannels+
+                " with persist set to "+persist);
         enforceChangePermission();
         /*
          * Validate the argument. We'd like to let the Wi-Fi driver do this,
@@ -1386,9 +1389,11 @@
             return false;
         }
 
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                               Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS,
-                               numChannels);
+        if (persist) {
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                                   Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS,
+                                   numChannels);
+        }
         mWifiStateTracker.setNumAllowedChannels(numChannels);
         return true;
     }
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 7234aa3..2849988 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.SharedPreferences;
+import android.net.wifi.WifiManager;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
@@ -28,6 +29,7 @@
 import android.os.RegistrantList;
 import android.os.SystemProperties;
 import android.preference.PreferenceManager;
+import android.provider.Settings;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.text.TextUtils;
@@ -194,7 +196,7 @@
         this.mContext = context;
         mLooper = Looper.myLooper();
 
-        setLocaleByCarrier();
+        setPropertiesByCarrier();
 
         setUnitTestMode(unitTestMode);
 
@@ -489,10 +491,10 @@
     }
 
     /**
-     * Set the locale by matching the carrier string in
+     * Set the properties by matching the carrier string in
      * a string-array resource
      */
-    private void setLocaleByCarrier() {
+    private void setPropertiesByCarrier() {
         String carrier = SystemProperties.get("ro.carrier");
 
         if (null == carrier || 0 == carrier.length()) {
@@ -500,18 +502,36 @@
         }
 
         CharSequence[] carrierLocales = mContext.
-                getResources().getTextArray(R.array.carrier_locales);
+                getResources().getTextArray(R.array.carrier_properties);
 
-        for (int i = 0; i < carrierLocales.length-1; i+=2) {
+        for (int i = 0; i < carrierLocales.length; i+=3) {
             String c = carrierLocales[i].toString();
-            String l = carrierLocales[i+1].toString();
             if (carrier.equals(c)) {
+                String l = carrierLocales[i+1].toString();
+                int wifiChannels = 0;
+                try {
+                    wifiChannels = Integer.parseInt(
+                            carrierLocales[i+2].toString());
+                } catch (NumberFormatException e) { }
+
                 String language = l.substring(0, 2);
                 String country = "";
                 if (l.length() >=5) {
                     country = l.substring(3, 5);
                 }
                 setSystemLocale(language, country);
+
+                if (wifiChannels != 0) {
+                    try {
+                        Settings.Secure.getInt(mContext.getContentResolver(),
+                                Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
+                    } catch (Settings.SettingNotFoundException e) {
+                        // note this is not persisting
+                        WifiManager wM = (WifiManager)
+                                mContext.getSystemService(Context.WIFI_SERVICE);
+                        wM.setNumAllowedChannels(wifiChannels, false);
+                    }
+                }
                 return;
             }
         }
diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
index e18da56..22b1f4f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
@@ -35,6 +35,7 @@
         int smallestDigitsMnc;
         String timezone;
         String language;
+        int wifiChannelsAllowed;
 
         MccEntry(int mnc, String iso, int smallestDigitsMCC) {
             this(mnc, iso, smallestDigitsMCC, null);
@@ -45,11 +46,16 @@
         }
 
         MccEntry(int mnc, String iso, int smallestDigitsMCC, String timezone, String language) {
+            this(mnc, iso, smallestDigitsMCC, timezone, language, 0);
+        }
+
+        MccEntry(int mnc, String iso, int smallestDigitsMCC, String timezone, String language, int wifiChannels) {
             this.mcc = mnc;
             this.iso = iso;
             this.smallestDigitsMnc = smallestDigitsMCC;
             this.timezone = timezone;
             this.language = language;
+            this.wifiChannelsAllowed = wifiChannels;
         }
 
         public int compareTo(MccEntry o)
@@ -148,6 +154,23 @@
         }
     }
 
+    /**
+     * Given a GSM Mobile Country Code, returns
+     * the number of wifi channels allowed in that country.
+     * Returns 0 if unavailable
+     */
+    public static int wifiChannelsForMcc(int mcc) {
+        MccEntry entry;
+
+        entry = entryForMcc(mcc);
+
+        if (entry == null) {
+            return 0;
+        } else {
+            return entry.wifiChannelsAllowed;
+        }
+    }
+
     static {
         table = new ArrayList<MccEntry>(240);
 
@@ -169,7 +192,7 @@
          */
 
 		table.add(new MccEntry(202,"gr",2));	//Greece
-		table.add(new MccEntry(204,"nl",2,"Europe/Amsterdam","nl"));	//Netherlands (Kingdom of the)
+		table.add(new MccEntry(204,"nl",2,"Europe/Amsterdam","nl",13)); //Netherlands (Kingdom of the)
 		table.add(new MccEntry(206,"be",2));	//Belgium
 		table.add(new MccEntry(208,"fr",2,"Europe/Paris","fr"));	//France
 		table.add(new MccEntry(212,"mc",2));	//Monaco (Principality of)
@@ -183,11 +206,11 @@
 		table.add(new MccEntry(225,"va",2,"Europe/Rome","it"));	//Vatican City State
 		table.add(new MccEntry(226,"ro",2));	//Romania
 		table.add(new MccEntry(228,"ch",2,"Europe/Zurich","de"));	//Switzerland (Confederation of)
-		table.add(new MccEntry(230,"cz",2,"Europe/Prague","cs"));	//Czech Republic
+		table.add(new MccEntry(230,"cz",2,"Europe/Prague","cs", 13));	//Czech Republic
 		table.add(new MccEntry(231,"sk",2));	//Slovak Republic
-		table.add(new MccEntry(232,"at",2,"Europe/Vienna","de"));	//Austria
-		table.add(new MccEntry(234,"gb",2,"Europe/London","en"));	//United Kingdom of Great Britain and Northern Ireland
-		table.add(new MccEntry(235,"gb",2,"Europe/London","en"));	//United Kingdom of Great Britain and Northern Ireland
+		table.add(new MccEntry(232,"at",2,"Europe/Vienna","de", 13));   //Austria
+		table.add(new MccEntry(234,"gb",2,"Europe/London","en", 13));   //United Kingdom of Great Britain and Northern Ireland
+		table.add(new MccEntry(235,"gb",2,"Europe/London","en", 13));   //United Kingdom of Great Britain and Northern Ireland
 		table.add(new MccEntry(238,"dk",2));	//Denmark
 		table.add(new MccEntry(240,"se",2));	//Sweden
 		table.add(new MccEntry(242,"no",2));	//Norway
@@ -200,7 +223,7 @@
 		table.add(new MccEntry(257,"by",2));	//Belarus (Republic of)
 		table.add(new MccEntry(259,"md",2));	//Moldova (Republic of)
 		table.add(new MccEntry(260,"pl",2,"Europe/Warsaw"));	//Poland (Republic of)
-		table.add(new MccEntry(262,"de",2,"Europe/Berlin","de"));	//Germany (Federal Republic of)
+		table.add(new MccEntry(262,"de",2,"Europe/Berlin","de", 13));   //Germany (Federal Republic of)
 		table.add(new MccEntry(266,"gi",2));	//Gibraltar
 		table.add(new MccEntry(268,"pt",2));	//Portugal
 		table.add(new MccEntry(270,"lu",2));	//Luxembourg
@@ -219,15 +242,15 @@
 		table.add(new MccEntry(293,"sl",2));	//Slovenia (Republic of)
                 table.add(new MccEntry(294,"mk",2));   //The Former Yugoslav Republic of Macedonia
 		table.add(new MccEntry(295,"li",2));	//Liechtenstein (Principality of)
-		table.add(new MccEntry(302,"ca",2));	//Canada
+		table.add(new MccEntry(302,"ca",2, "", "", 11));        //Canada
 		table.add(new MccEntry(308,"pm",2));	//Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
-		table.add(new MccEntry(310,"us",3,"","en"));	//United States of America
-		table.add(new MccEntry(311,"us",3,"","en"));	//United States of America
-		table.add(new MccEntry(312,"us",3,"","en"));	//United States of America
-		table.add(new MccEntry(313,"us",3,"","en"));	//United States of America
-		table.add(new MccEntry(314,"us",3,"","en"));	//United States of America
-		table.add(new MccEntry(315,"us",3,"","en"));	//United States of America
-		table.add(new MccEntry(316,"us",3,"","en"));	//United States of America
+		table.add(new MccEntry(310,"us",3,"","en", 11));        //United States of America
+		table.add(new MccEntry(311,"us",3,"","en", 11));        //United States of America
+		table.add(new MccEntry(312,"us",3,"","en", 11));        //United States of America
+		table.add(new MccEntry(313,"us",3,"","en", 11));        //United States of America
+		table.add(new MccEntry(314,"us",3,"","en", 11));        //United States of America
+		table.add(new MccEntry(315,"us",3,"","en", 11));        //United States of America
+		table.add(new MccEntry(316,"us",3,"","en", 11));        //United States of America
 		table.add(new MccEntry(330,"pr",2));	//Puerto Rico
 		table.add(new MccEntry(332,"vi",2));	//United States Virgin Islands
 		table.add(new MccEntry(334,"mx",3));	//Mexico
@@ -283,8 +306,8 @@
 		table.add(new MccEntry(436,"tj",2));	//Tajikistan (Republic of)
 		table.add(new MccEntry(437,"kg",2));	//Kyrgyz Republic
 		table.add(new MccEntry(438,"tm",2));	//Turkmenistan
-		table.add(new MccEntry(440,"jp",2,"Asia/Tokyo","ja"));	//Japan
-		table.add(new MccEntry(441,"jp",2,"Asia/Tokyo","ja"));	//Japan
+		table.add(new MccEntry(440,"jp",2,"Asia/Tokyo","ja", 14));              //Japan
+		table.add(new MccEntry(441,"jp",2,"Asia/Tokyo","ja", 14));              //Japan
 		table.add(new MccEntry(450,"kr",2));	//Korea (Republic of)
 		table.add(new MccEntry(452,"vn",2));	//Viet Nam (Socialist Republic of)
 		table.add(new MccEntry(454,"hk",2));	//"Hong Kong, China"
@@ -298,12 +321,12 @@
 		table.add(new MccEntry(470,"bd",2));	//Bangladesh (People's Republic of)
 		table.add(new MccEntry(472,"mv",2));	//Maldives (Republic of)
 		table.add(new MccEntry(502,"my",2));	//Malaysia
-		table.add(new MccEntry(505,"au",2,"Australia/Sydney","en"));	//Australia
+		table.add(new MccEntry(505,"au",2,"Australia/Sydney","en", 11));        //Australia
 		table.add(new MccEntry(510,"id",2));	//Indonesia (Republic of)
 		table.add(new MccEntry(514,"tl",2));	//Democratic Republic of Timor-Leste
 		table.add(new MccEntry(515,"ph",2));	//Philippines (Republic of the)
 		table.add(new MccEntry(520,"th",2));	//Thailand
-		table.add(new MccEntry(525,"sg",2,"Singapore","en"));	//Singapore (Republic of)
+		table.add(new MccEntry(525,"sg",2,"Singapore","en", 11));               //Singapore (Republic of)
 		table.add(new MccEntry(528,"bn",2));	//Brunei Darussalam
 		table.add(new MccEntry(530,"nz",2,"Pacific/Auckland", "en"));	//New Zealand
 		table.add(new MccEntry(534,"mp",2));	//Northern Mariana Islands (Commonwealth of the)
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index f9015d9..fb45c7c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -21,11 +21,13 @@
 import android.app.IActivityManager;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.net.wifi.WifiManager;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
 import android.os.Registrant;
+import android.provider.Settings;
 import android.util.Log;
 import java.util.ArrayList;
 
@@ -513,6 +515,29 @@
         phone.setSystemLocale(language, country);
     }
 
+    /**
+     * If the number of allowed wifi channels has not been set, set it based on
+     * the MCC of the SIM.
+     * @param mcc Mobile Country Code of the SIM
+     */
+    private void setWifiChannelsFromMccIfNeeded(int mcc) {
+        int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
+
+        if (wifiChannels != 0) {
+            Context context = phone.getContext();
+            // only set to this default if the user hasn't manually set it
+            try {
+                Settings.Secure.getInt(context.getContentResolver(),
+                        Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
+            } catch (Settings.SettingNotFoundException e) {
+                WifiManager wM = (WifiManager)
+                        context.getSystemService(Context.WIFI_SERVICE);
+                // don't persist
+                wM.setNumAllowedChannels(wifiChannels, false);
+            }
+        }
+    }
+
     //***** Overridden from Handler
     public void handleMessage(Message msg) {
         AsyncResult ar;
@@ -559,6 +584,7 @@
                 int mcc = Integer.parseInt(imsi.substring(0, 3));
                 setTimezoneFromMccIfNeeded(mcc);
                 setLocaleFromMccIfNeeded(mcc);
+                setWifiChannelsFromMccIfNeeded(mcc);
             break;
 
             case EVENT_GET_MBI_DONE:
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 7c3af69..0db868e 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -58,7 +58,7 @@
 
     int getNumAllowedChannels();
 
-    boolean setNumAllowedChannels(int numChannels);
+    boolean setNumAllowedChannels(int numChannels, boolean persist);
 
     int[] getValidChannelCounts();
     
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 1a7caef..141d53f 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -538,14 +538,15 @@
      * for some reason.
      * @param numChannels the number of allowed channels. Must be greater than 0
      * and less than or equal to 16.
+     * @param persist {@code true} if you want this remembered
      * @return {@code true} if the operation succeeds, {@code false} otherwise, e.g.,
      * {@code numChannels} is out of range.
      *
      * @hide pending API council
      */
-    public boolean setNumAllowedChannels(int numChannels) {
+    public boolean setNumAllowedChannels(int numChannels, boolean persist) {
         try {
-            return mService.setNumAllowedChannels(numChannels);
+            return mService.setNumAllowedChannels(numChannels, persist);
         } catch (RemoteException e) {
             return false;
         }
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 6771136..7ba124fd 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -183,6 +183,10 @@
     private boolean mUseStaticIp = false;
     private int mReconnectCount;
 
+    // used to store the (non-persisted) num determined during device boot 
+    // (from mcc or other phone info) before the driver is started.
+    private int mNumAllowedChannels = 0;
+
     // Variables relating to the 'available networks' notification
     
     /**
@@ -571,9 +575,12 @@
         try {
             return setNumAllowedChannels(
                     Settings.Secure.getInt(mContext.getContentResolver(),
-                                           Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS));
+                    Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS));
         } catch (Settings.SettingNotFoundException e) {
-            // if setting doesn't exist, stick with the driver default
+            if (mNumAllowedChannels != 0) {
+                WifiNative.setNumAllowedChannelsCommand(mNumAllowedChannels);
+            }
+            // otherwise, use the driver default
         }
         return true;
     }
@@ -587,6 +594,7 @@
      * {@code numChannels} is outside the valid range.
      */
     public synchronized boolean setNumAllowedChannels(int numChannels) {
+        mNumAllowedChannels = numChannels;
         return WifiNative.setNumAllowedChannelsCommand(numChannels);
     }