OSDN Git Service

Fix window leak on orientation change
[android-x86/packages-apps-Settings.git] / src / com / android / settings / TetherSettings.java
index 9430c19..79b081f 100644 (file)
@@ -18,6 +18,8 @@ package com.android.settings;
 
 import com.android.settings.wifi.WifiApEnabler;
 
+import android.app.AlertDialog;
+import android.app.Dialog;
 import android.os.Bundle;
 import android.os.SystemProperties;
 import android.content.BroadcastReceiver;
@@ -26,14 +28,16 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.os.Environment;
+import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
-import android.preference.CheckBoxPreference;
 import android.provider.Settings;
 import android.util.Log;
+import android.webkit.WebView;
 
 import java.util.ArrayList;
+import java.util.Locale;
 
 /*
  * Displays preferences for Tethering.
@@ -42,12 +46,20 @@ public class TetherSettings extends PreferenceActivity {
     private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
     private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
     private static final String WIFI_AP_SETTINGS = "wifi_ap_settings";
+    private static final String TETHERING_HELP = "tethering_help";
+    private static final String USB_HELP_MODIFIER = "usb_";
+    private static final String WIFI_HELP_MODIFIER = "wifi_";
+    private static final String HELP_URL = "file:///android_asset/html/%y_%z/tethering_%xhelp.html";
+
+    private static final int DIALOG_TETHER_HELP = 1;
 
-    private PreferenceScreen mUsbTether;
+    private WebView mView;
+    private CheckBoxPreference mUsbTether;
 
     private CheckBoxPreference mEnableWifiAp;
     private PreferenceScreen mWifiApSettings;
     private WifiApEnabler mWifiApEnabler;
+    private PreferenceScreen mTetherHelp;
 
     private BroadcastReceiver mTetherChangeReceiver;
 
@@ -55,7 +67,6 @@ public class TetherSettings extends PreferenceActivity {
     private ArrayList mUsbIfaces;
 
     private String[] mWifiRegexs;
-    private ArrayList mWifiIfaces;
 
     @Override
     protected void onCreate(Bundle icicle) {
@@ -63,12 +74,14 @@ public class TetherSettings extends PreferenceActivity {
 
         addPreferencesFromResource(R.xml.tether_prefs);
 
-        mUsbTether = (PreferenceScreen) findPreference(USB_TETHER_SETTINGS);
         mEnableWifiAp = (CheckBoxPreference) findPreference(ENABLE_WIFI_AP);
         mWifiApSettings = (PreferenceScreen) findPreference(WIFI_AP_SETTINGS);
+        mUsbTether = (CheckBoxPreference) findPreference(USB_TETHER_SETTINGS);
+        mTetherHelp = (PreferenceScreen) findPreference(TETHERING_HELP);
 
         ConnectivityManager cm =
                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+
         mUsbRegexs = cm.getTetherableUsbRegexs();
         if (mUsbRegexs.length == 0) {
             getPreferenceScreen().removePreference(mUsbTether);
@@ -80,20 +93,51 @@ public class TetherSettings extends PreferenceActivity {
             getPreferenceScreen().removePreference(mWifiApSettings);
         }
         mWifiApEnabler = new WifiApEnabler(this, mEnableWifiAp);
+        mView = new WebView(this);
     }
 
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        if (id == DIALOG_TETHER_HELP) {
+            Locale locale = Locale.getDefault();
+            String url = HELP_URL.replace("%y", locale.getLanguage().toLowerCase());
+            url = url.replace("%z", locale.getCountry().toLowerCase());
+
+            if ((mUsbRegexs.length != 0) && (mWifiRegexs.length == 0)) {
+                url = url.replace("%x", USB_HELP_MODIFIER);
+            } else if ((mWifiRegexs.length != 0) && (mUsbRegexs.length == 0)) {
+                url = url.replace("%x", WIFI_HELP_MODIFIER);
+            } else {
+                // could assert that both wifi and usb have regexs, but the default
+                // is to use this anyway so no check is needed
+                url = url.replace("%x", "");
+            }
+            mView.loadUrl(url);
+
+            return new AlertDialog.Builder(this)
+                .setCancelable(true)
+                .setTitle(R.string.tethering_help_button_text)
+                .setView(mView)
+                .create();
+        }
+        return null;
+    }
 
     private class TetherChangeReceiver extends BroadcastReceiver {
         public void onReceive(Context content, Intent intent) {
-            // 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);
-            ArrayList<String> errored = intent.getStringArrayListExtra(
-                    ConnectivityManager.EXTRA_ERRORED_TETHER);
-
-            updateState(available, active, errored);
+            if (intent.getAction().equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
+                // 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);
+                ArrayList<String> errored = intent.getStringArrayListExtra(
+                        ConnectivityManager.EXTRA_ERRORED_TETHER);
+                updateState(available.toArray(), active.toArray(), errored.toArray());
+            } else if (intent.getAction().equals(Intent.ACTION_MEDIA_SHARED) ||
+                       intent.getAction().equals(Intent.ACTION_MEDIA_UNSHARED)) {
+                updateState();
+            }
         }
     }
 
@@ -102,11 +146,15 @@ public class TetherSettings extends PreferenceActivity {
         super.onResume();
 
         IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
-        filter.addAction(Intent.ACTION_MEDIA_SHARED);
-        filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
         mTetherChangeReceiver = new TetherChangeReceiver();
         Intent intent = registerReceiver(mTetherChangeReceiver, filter);
 
+        filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_MEDIA_SHARED);
+        filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
+        filter.addDataScheme("file");
+        registerReceiver(mTetherChangeReceiver, filter);
+
         if (intent != null) mTetherChangeReceiver.onReceive(this, intent);
         mWifiApEnabler.resume();
     }
@@ -119,57 +167,128 @@ public class TetherSettings extends PreferenceActivity {
         mWifiApEnabler.pause();
     }
 
-    private void updateState(ArrayList<String> available, ArrayList<String> tethered,
-            ArrayList<String> errored) {
+    private void updateState() {
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+
+        String[] available = cm.getTetherableIfaces();
+        String[] tethered = cm.getTetheredIfaces();
+        String[] errored = cm.getTetheringErroredIfaces();
+        updateState(available, tethered, errored);
+    }
+
+    private void updateState(Object[] available, Object[] tethered,
+            Object[] errored) {
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
         boolean usbTethered = false;
         boolean usbAvailable = false;
+        int usbError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
         boolean usbErrored = false;
-        boolean wifiTethered = false;
-        boolean wifiAvailable = false;
         boolean massStorageActive =
                 Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState());
-        boolean wifiErrored = false;
-
-        for (String s : available) {
+        for (Object o : available) {
+            String s = (String)o;
             for (String regex : mUsbRegexs) {
-                if (s.matches(regex)) usbAvailable = true;
-            }
-            for (String regex : mWifiRegexs) {
-                if (s.matches(regex)) wifiAvailable = true;
+                if (s.matches(regex)) {
+                    usbAvailable = true;
+                    if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                        usbError = cm.getLastTetherError(s);
+                    }
+                }
             }
         }
-        for (String s : tethered) {
+        for (Object o : tethered) {
+            String s = (String)o;
             for (String regex : mUsbRegexs) {
                 if (s.matches(regex)) usbTethered = true;
             }
-            for (String regex : mWifiRegexs) {
-                if (s.matches(regex)) wifiTethered = true;
-            }
         }
-        for (String s: errored) {
+        for (Object o: errored) {
+            String s = (String)o;
             for (String regex : mUsbRegexs) {
                 if (s.matches(regex)) usbErrored = true;
             }
-            for (String regex : mWifiRegexs) {
-                if (s.matches(regex)) wifiErrored = true;
-            }
         }
 
         if (usbTethered) {
             mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
             mUsbTether.setEnabled(true);
-        } else if (massStorageActive) {
-            mUsbTether.setSummary(R.string.usb_tethering_storage_active_subtext);
-            mUsbTether.setEnabled(false);
+            mUsbTether.setChecked(true);
         } else if (usbAvailable) {
-            mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
+            if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
+            } else {
+                mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
+            }
             mUsbTether.setEnabled(true);
+            mUsbTether.setChecked(false);
         } else if (usbErrored) {
             mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
             mUsbTether.setEnabled(false);
+            mUsbTether.setChecked(false);
+        } else if (massStorageActive) {
+            mUsbTether.setSummary(R.string.usb_tethering_storage_active_subtext);
+            mUsbTether.setEnabled(false);
+            mUsbTether.setChecked(false);
         } else {
             mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
             mUsbTether.setEnabled(false);
+            mUsbTether.setChecked(false);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mUsbTether) {
+            boolean newState = mUsbTether.isChecked();
+
+            ConnectivityManager cm =
+                    (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+
+            if (newState) {
+                String[] available = cm.getTetherableIfaces();
+
+                String usbIface = findIface(available, mUsbRegexs);
+                if (usbIface == null) {
+                    updateState();
+                    return true;
+                }
+                if (cm.tether(usbIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                    mUsbTether.setChecked(false);
+                    mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
+                    return true;
+                }
+                mUsbTether.setSummary("");
+            } else {
+                String [] tethered = cm.getTetheredIfaces();
+
+                String usbIface = findIface(tethered, mUsbRegexs);
+                if (usbIface == null) {
+                    updateState();
+                    return true;
+                }
+                if (cm.untether(usbIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                    mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
+                    return true;
+                }
+                mUsbTether.setSummary("");
+            }
+        } else if (preference == mTetherHelp) {
+
+            showDialog(DIALOG_TETHER_HELP);
+        }
+        return false;
+    }
+
+    private String findIface(String[] ifaces, String[] regexes) {
+        for (String iface : ifaces) {
+            for (String regex : regexes) {
+                if (iface.matches(regex)) {
+                    return iface;
+                }
+            }
         }
+        return null;
     }
 }