Merge "Fix bug 2446811 Ensure the default locale is never constructed  with a null string."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 67f0cde..ad4596e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -171,8 +171,7 @@
         </activity>
 
         <activity android:name=".TetherSettings"
-                android:configChanges="orientation|keyboardHidden"
-                android:launchMode="singleTask">
+                android:clearTaskOnLaunch="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/res/xml/wireless_settings.xml b/res/xml/wireless_settings.xml
index 9977505..5ee758a 100644
--- a/res/xml/wireless_settings.xml
+++ b/res/xml/wireless_settings.xml
@@ -57,6 +57,7 @@
     </PreferenceScreen>
 
     <PreferenceScreen
+        android:key="tether_settings"
         android:title="@string/tether_settings_title"
         android:summary="@string/tether_settings_summary">
         <intent
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index 94cf714..126af6b 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -20,7 +20,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.DeviceAdmin;
+import android.app.DeviceAdminReceiver;
 import android.app.DeviceAdminInfo;
 import android.app.DevicePolicyManager;
 import android.app.Dialog;
@@ -146,14 +146,16 @@
                         @Override
                         protected void onResult(Bundle bundle) {
                             CharSequence msg = bundle != null
-                                    ? bundle.getCharSequence(DeviceAdmin.EXTRA_DISABLE_WARNING)
+                                    ? bundle.getCharSequence(
+                                            DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
                                     : null;
                             if (msg == null) {
                                 mDPM.removeActiveAdmin(mDeviceAdmin.getComponent());
                                 finish();
                             } else {
                                 Bundle args = new Bundle();
-                                args.putCharSequence(DeviceAdmin.EXTRA_DISABLE_WARNING, msg);
+                                args.putCharSequence(
+                                        DeviceAdminReceiver.EXTRA_DISABLE_WARNING, msg);
                                 showDialog(DIALOG_WARNING, args);
                             }
                         }
@@ -173,7 +175,7 @@
     protected Dialog onCreateDialog(int id, Bundle args) {
         switch (id) {
             case DIALOG_WARNING: {
-                CharSequence msg = args.getCharSequence(DeviceAdmin.EXTRA_DISABLE_WARNING);
+                CharSequence msg = args.getCharSequence(DeviceAdminReceiver.EXTRA_DISABLE_WARNING);
                 AlertDialog.Builder builder = new AlertDialog.Builder(
                         DeviceAdminAdd.this);
                 builder.setMessage(msg);
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index a36fc8a..d866966 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -20,7 +20,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.DeviceAdmin;
+import android.app.DeviceAdminReceiver;
 import android.app.DeviceAdminInfo;
 import android.app.DevicePolicyManager;
 import android.app.Dialog;
@@ -85,7 +85,7 @@
         
         mAvailableAdmins.clear();
         List<ResolveInfo> avail = getPackageManager().queryBroadcastReceivers(
-                new Intent(DeviceAdmin.ACTION_DEVICE_ADMIN_ENABLED),
+                new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
                 PackageManager.GET_META_DATA);
         int count = avail == null ? 0 : avail.size();
         for (int i=0; i<count; i++) {
diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
index 0a63de3..1e9c4e2 100644
--- a/src/com/android/settings/TetherSettings.java
+++ b/src/com/android/settings/TetherSettings.java
@@ -30,6 +30,7 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import java.util.ArrayList;
 /*
  * Displays preferences for Tethering.
  */
@@ -43,6 +44,12 @@
 
     private BroadcastReceiver mTetherChangeReceiver;
 
+    private String[] mUsbRegexs;
+    private ArrayList mUsbIfaces;
+
+    private String[] mWifiRegexs;
+    private ArrayList mWifiIfaces;
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -51,12 +58,27 @@
 
         mEnableTetherNotice = (CheckBoxPreference) findPreference(ENABLE_TETHER_NOTICE);
         mUsbTether = (PreferenceScreen) findPreference(USB_TETHER_SETTINGS);
+
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+        mUsbRegexs = cm.getTetherableUsbRegexs();
+        if (mUsbRegexs.length == 0) {
+            getPreferenceScreen().removePreference(mUsbTether);
+            getPreferenceScreen().removePreference(mEnableTetherNotice);
+        }
+        mWifiRegexs = cm.getTetherableWifiRegexs();
     }
 
+
     private class TetherChangeReceiver extends BroadcastReceiver {
         public void onReceive(Context content, Intent intent) {
-            updateState(intent.getIntExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER_COUNT,0)>0,
-                    intent.getIntExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER_COUNT,0)>0);
+            // TODO - this should understand the interface types
+            ArrayList<String> available = intent.getStringArrayListExtra(
+                    ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+            ArrayList<String> active = intent.getStringArrayListExtra(
+                    ConnectivityManager.EXTRA_ACTIVE_TETHER);
+
+            updateState(available, active);
         }
     }
 
@@ -68,11 +90,9 @@
 
         IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
         mTetherChangeReceiver = new TetherChangeReceiver();
-        registerReceiver(mTetherChangeReceiver, filter);
+        Intent intent = registerReceiver(mTetherChangeReceiver, filter);
 
-        ConnectivityManager cm =
-                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
-        updateState(cm.getTetherableIfaces().length>0, cm.getTetheredIfaces().length>0);
+        if (intent != null) mTetherChangeReceiver.onReceive(this, intent);
     }
 
     @Override
@@ -82,11 +102,33 @@
         mTetherChangeReceiver = null;
     }
 
-    private void updateState(boolean isAvailable, boolean isTethered) {
-        if (isTethered) {
+    private void updateState(ArrayList<String> available, ArrayList<String> tethered) {
+        boolean usbTethered = false;
+        boolean usbAvailable = false;
+        boolean wifiTethered = false;
+        boolean wifiAvailable = false;
+
+        for (String s : available) {
+            for (String regex : mUsbRegexs) {
+                if (s.matches(regex)) usbAvailable = true;
+            }
+            for (String regex : mWifiRegexs) {
+                if (s.matches(regex)) wifiAvailable = true;
+            }
+        }
+        for (String s : tethered) {
+            for (String regex : mUsbRegexs) {
+                if (s.matches(regex)) usbTethered = true;
+            }
+            for (String regex : mWifiRegexs) {
+                if (s.matches(regex)) wifiTethered = true;
+            }
+        }
+
+        if (usbTethered) {
             mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
             mUsbTether.setEnabled(true);
-        } else if (isAvailable) {
+        } else if (usbAvailable) {
             mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
             mUsbTether.setEnabled(true);
         } else {
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index bf75e27..6db2001 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -19,6 +19,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
 import android.content.Intent;
+import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.ServiceManager;
@@ -28,6 +29,7 @@
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
+import android.util.Log;
 
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
@@ -42,6 +44,7 @@
     private static final String KEY_WIFI_SETTINGS = "wifi_settings";
     private static final String KEY_BT_SETTINGS = "bt_settings";
     private static final String KEY_VPN_SETTINGS = "vpn_settings";
+    private static final String KEY_TETHER_SETTINGS = "tether_settings";
     public static final String EXIT_ECM_RESULT = "exit_ecm_result";
     public static final int REQUEST_CODE_EXIT_ECM = 1;
 
@@ -114,8 +117,15 @@
         if (ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE) == null) {
             findPreference(KEY_BT_SETTINGS).setEnabled(false);
         }
+
+        // Disable Tethering if it's not allowed
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+        if (!cm.isTetheringSupported()) {
+            getPreferenceScreen().removePreference(findPreference(KEY_TETHER_SETTINGS));
+        }
     }
-    
+
     @Override
     protected void onResume() {
         super.onResume();