OSDN Git Service

am 28539897: am 8815f032: Merge "Always set right auth_type value in apn."
[android-x86/packages-apps-Settings.git] / src / com / android / settings / TetherSettings.java
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.settings;
18
19 import com.android.settings.bluetooth.BluetoothSettings;
20 import com.android.settings.wifi.WifiApEnabler;
21
22 import android.app.Activity;
23 import android.app.AlertDialog;
24 import android.app.Dialog;
25 import android.bluetooth.BluetoothAdapter;
26 import android.bluetooth.BluetoothPan;
27 import android.content.BroadcastReceiver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.res.AssetManager;
32 import android.net.ConnectivityManager;
33 import android.os.Bundle;
34 import android.os.Environment;
35 import android.preference.CheckBoxPreference;
36 import android.preference.Preference;
37 import android.preference.PreferenceScreen;
38 import android.webkit.WebView;
39
40 import java.io.InputStream;
41 import java.util.ArrayList;
42 import java.util.Locale;
43
44 /*
45  * Displays preferences for Tethering.
46  */
47 public class TetherSettings extends SettingsPreferenceFragment {
48     private static final String TAG = "TetheringSettings";
49
50     private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
51     private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
52     private static final String WIFI_AP_SETTINGS = "wifi_ap_settings";
53     private static final String ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
54     private static final String BLUETOOTH_TETHER_SETTINGS = "bluetooth_tether_settings";
55     private static final String TETHERING_HELP = "tethering_help";
56     private static final String USB_HELP_MODIFIER = "usb_";
57     private static final String WIFI_HELP_MODIFIER = "wifi_";
58     private static final String HELP_URL = "file:///android_asset/html/%y%z/tethering_%xhelp.html";
59     private static final String HELP_PATH = "html/%y%z/tethering_help.html";
60
61     private static final int DIALOG_TETHER_HELP = 1;
62
63     private WebView mView;
64     private CheckBoxPreference mUsbTether;
65
66     private CheckBoxPreference mEnableWifiAp;
67     private PreferenceScreen mWifiApSettings;
68     private WifiApEnabler mWifiApEnabler;
69
70     private CheckBoxPreference mBluetoothTether;
71     private PreferenceScreen mBluetoothSettings;
72
73     private PreferenceScreen mTetherHelp;
74
75     private BroadcastReceiver mTetherChangeReceiver;
76
77     private String[] mUsbRegexs;
78
79     private String[] mWifiRegexs;
80
81     private String[] mBluetoothRegexs;
82     private BluetoothPan mBluetoothPan;
83
84     @Override
85     public void onCreate(Bundle icicle) {
86         super.onCreate(icicle);
87         addPreferencesFromResource(R.xml.tether_prefs);
88     }
89
90     @Override
91     public void onActivityCreated(Bundle savedInstanceState) {
92         super.onActivityCreated(savedInstanceState);
93         final Activity activity = getActivity();
94         mBluetoothPan = new BluetoothPan(activity);
95
96         mEnableWifiAp = (CheckBoxPreference) findPreference(ENABLE_WIFI_AP);
97         mWifiApSettings = (PreferenceScreen) findPreference(WIFI_AP_SETTINGS);
98         mUsbTether = (CheckBoxPreference) findPreference(USB_TETHER_SETTINGS);
99         mBluetoothTether = (CheckBoxPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
100         mBluetoothSettings = (PreferenceScreen) findPreference(BLUETOOTH_TETHER_SETTINGS);
101         mTetherHelp = (PreferenceScreen) findPreference(TETHERING_HELP);
102
103         ConnectivityManager cm =
104                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
105
106         mUsbRegexs = cm.getTetherableUsbRegexs();
107         mWifiRegexs = cm.getTetherableWifiRegexs();
108         mBluetoothRegexs = cm.getTetherableBluetoothRegexs();
109
110         boolean usbAvailable = mUsbRegexs.length != 0;
111         boolean wifiAvailable = mWifiRegexs.length != 0;
112         boolean bluetoothAvailable = mBluetoothRegexs.length != 0;
113
114
115         if (!usbAvailable || Utils.isMonkeyRunning()) {
116             getPreferenceScreen().removePreference(mUsbTether);
117         }
118         if (!wifiAvailable) {
119             getPreferenceScreen().removePreference(mEnableWifiAp);
120             getPreferenceScreen().removePreference(mWifiApSettings);
121         }
122         if (!bluetoothAvailable) {
123             getPreferenceScreen().removePreference(mBluetoothTether);
124             getPreferenceScreen().removePreference(mBluetoothSettings);
125         } else {
126             if (mBluetoothPan.isTetheringOn()) {
127                 mBluetoothTether.setChecked(true);
128                 mBluetoothSettings.setEnabled(true);
129             } else {
130                 mBluetoothTether.setChecked(false);
131                 mBluetoothSettings.setEnabled(false);
132             }
133         }
134         if (wifiAvailable && usbAvailable && bluetoothAvailable){
135             activity.setTitle(R.string.tether_settings_title_all);
136         } else if (wifiAvailable && usbAvailable){
137             activity.setTitle(R.string.tether_settings_title_all);
138         } else if (wifiAvailable && bluetoothAvailable){
139             activity.setTitle(R.string.tether_settings_title_all);
140         } else if (wifiAvailable) {
141             activity.setTitle(R.string.tether_settings_title_wifi);
142         } else if (usbAvailable && bluetoothAvailable) {
143             activity.setTitle(R.string.tether_settings_title_usb_bluetooth);
144         } else if (usbAvailable) {
145             activity.setTitle(R.string.tether_settings_title_usb);
146         } else {
147             activity.setTitle(R.string.tether_settings_title_bluetooth);
148         }
149         mWifiApEnabler = new WifiApEnabler(activity, mEnableWifiAp);
150         mView = new WebView(activity);
151     }
152
153     @Override
154     public Dialog onCreateDialog(int id) {
155         if (id == DIALOG_TETHER_HELP) {
156             Locale locale = Locale.getDefault();
157
158             // check for the full language + country resource, if not there, try just language
159             final AssetManager am = getActivity().getAssets();
160             String path = HELP_PATH.replace("%y", locale.getLanguage().toLowerCase());
161             path = path.replace("%z", "_"+locale.getCountry().toLowerCase());
162             boolean useCountry = true;
163             InputStream is = null;
164             try {
165                 is = am.open(path);
166             } catch (Exception e) {
167                 useCountry = false;
168             } finally {
169                 if (is != null) {
170                     try {
171                         is.close();
172                     } catch (Exception e) {}
173                 }
174             }
175             String url = HELP_URL.replace("%y", locale.getLanguage().toLowerCase());
176             url = url.replace("%z", (useCountry ? "_"+locale.getCountry().toLowerCase() : ""));
177             if ((mUsbRegexs.length != 0) && (mWifiRegexs.length == 0)) {
178                 url = url.replace("%x", USB_HELP_MODIFIER);
179             } else if ((mWifiRegexs.length != 0) && (mUsbRegexs.length == 0)) {
180                 url = url.replace("%x", WIFI_HELP_MODIFIER);
181             } else {
182                 // could assert that both wifi and usb have regexs, but the default
183                 // is to use this anyway so no check is needed
184                 url = url.replace("%x", "");
185             }
186
187             mView.loadUrl(url);
188
189             return new AlertDialog.Builder(getActivity())
190                 .setCancelable(true)
191                 .setTitle(R.string.tethering_help_button_text)
192                 .setView(mView)
193                 .create();
194         }
195         return null;
196     }
197
198     private class TetherChangeReceiver extends BroadcastReceiver {
199         @Override
200         public void onReceive(Context content, Intent intent) {
201             if (intent.getAction().equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
202                 // TODO - this should understand the interface types
203                 ArrayList<String> available = intent.getStringArrayListExtra(
204                         ConnectivityManager.EXTRA_AVAILABLE_TETHER);
205                 ArrayList<String> active = intent.getStringArrayListExtra(
206                         ConnectivityManager.EXTRA_ACTIVE_TETHER);
207                 ArrayList<String> errored = intent.getStringArrayListExtra(
208                         ConnectivityManager.EXTRA_ERRORED_TETHER);
209                 updateState(available.toArray(new String[available.size()]),
210                         active.toArray(new String[active.size()]),
211                         errored.toArray(new String[errored.size()]));
212             } else if (intent.getAction().equals(Intent.ACTION_MEDIA_SHARED) ||
213                        intent.getAction().equals(Intent.ACTION_MEDIA_UNSHARED)) {
214                 updateState();
215             } else if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
216                 updateState();
217             }
218         }
219     }
220
221     @Override
222     public void onStart() {
223         super.onStart();
224
225         final Activity activity = getActivity();
226
227         mTetherChangeReceiver = new TetherChangeReceiver();
228         IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
229         Intent intent = activity.registerReceiver(mTetherChangeReceiver, filter);
230
231         filter = new IntentFilter();
232         filter.addAction(Intent.ACTION_MEDIA_SHARED);
233         filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
234         filter.addDataScheme("file");
235         activity.registerReceiver(mTetherChangeReceiver, filter);
236
237         filter = new IntentFilter();
238         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
239         activity.registerReceiver(mTetherChangeReceiver, filter);
240
241         if (intent != null) mTetherChangeReceiver.onReceive(activity, intent);
242         mWifiApEnabler.resume();
243     }
244
245     @Override
246     public void onStop() {
247         super.onStop();
248         getActivity().unregisterReceiver(mTetherChangeReceiver);
249         mTetherChangeReceiver = null;
250         mWifiApEnabler.pause();
251     }
252
253     private void updateState() {
254         ConnectivityManager cm =
255                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
256
257         String[] available = cm.getTetherableIfaces();
258         String[] tethered = cm.getTetheredIfaces();
259         String[] errored = cm.getTetheringErroredIfaces();
260         updateState(available, tethered, errored);
261     }
262
263     private void updateState(String[] available, String[] tethered,
264             String[] errored) {
265         updateUsbState(available, tethered, errored);
266         updateBluetoothState(available, tethered, errored);
267     }
268
269
270     private void updateUsbState(String[] available, String[] tethered,
271             String[] errored) {
272         ConnectivityManager cm =
273                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
274         boolean usbTethered = false;
275         boolean usbAvailable = false;
276         int usbError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
277         boolean usbErrored = false;
278         boolean massStorageActive =
279                 Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState());
280         for (String s : available) {
281             for (String regex : mUsbRegexs) {
282                 if (s.matches(regex)) {
283                     usbAvailable = true;
284                     if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
285                         usbError = cm.getLastTetherError(s);
286                     }
287                 }
288             }
289         }
290         for (String s : tethered) {
291             for (String regex : mUsbRegexs) {
292                 if (s.matches(regex)) usbTethered = true;
293             }
294         }
295         for (String s: errored) {
296             for (String regex : mUsbRegexs) {
297                 if (s.matches(regex)) usbErrored = true;
298             }
299         }
300
301         if (usbTethered) {
302             mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
303             mUsbTether.setEnabled(true);
304             mUsbTether.setChecked(true);
305         } else if (usbAvailable) {
306             if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
307                 mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
308             } else {
309                 mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
310             }
311             mUsbTether.setEnabled(true);
312             mUsbTether.setChecked(false);
313         } else if (usbErrored) {
314             mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
315             mUsbTether.setEnabled(false);
316             mUsbTether.setChecked(false);
317         } else if (massStorageActive) {
318             mUsbTether.setSummary(R.string.usb_tethering_storage_active_subtext);
319             mUsbTether.setEnabled(false);
320             mUsbTether.setChecked(false);
321         } else {
322             mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
323             mUsbTether.setEnabled(false);
324             mUsbTether.setChecked(false);
325         }
326     }
327
328     private void updateBluetoothState(String[] available, String[] tethered,
329             String[] errored) {
330         ConnectivityManager cm =
331                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
332         boolean bluetoothTethered = false;
333         boolean bluetoothAvailable = false;
334         int bluetoothError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
335         boolean bluetoothErrored = false;
336         for (String s : available) {
337             for (String regex : mBluetoothRegexs) {
338                 if (s.matches(regex)) {
339                     bluetoothAvailable = true;
340                     if (bluetoothError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
341                         bluetoothError = cm.getLastTetherError(s);
342                     }
343                 }
344             }
345         }
346         for (String s : tethered) {
347             for (String regex : mBluetoothRegexs) {
348                 if (s.matches(regex)) bluetoothTethered = true;
349             }
350         }
351         for (String s: errored) {
352             for (String regex : mBluetoothRegexs) {
353                 if (s.matches(regex)) bluetoothErrored = true;
354             }
355         }
356
357         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
358         int btState = adapter.getState();
359         if (btState == BluetoothAdapter.STATE_TURNING_OFF) {
360             mBluetoothTether.setEnabled(false);
361             mBluetoothSettings.setEnabled(false);
362             mBluetoothTether.setSummary(R.string.wifi_stopping);
363         } else if (btState == BluetoothAdapter.STATE_TURNING_ON) {
364             mBluetoothTether.setEnabled(false);
365             mBluetoothSettings.setEnabled(false);
366             mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
367         } else if (mBluetoothPan.isTetheringOn()) {
368             mBluetoothTether.setChecked(true);
369             if (btState == BluetoothAdapter.STATE_ON) {
370                 mBluetoothTether.setEnabled(true);
371                 mBluetoothSettings.setEnabled(true);
372                 if (bluetoothTethered) {
373                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_connected_subtext);
374                 } else if (bluetoothErrored) {
375                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
376                 } else {
377                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
378                 }
379             }
380         } else {
381             mBluetoothTether.setEnabled(true);
382             mBluetoothTether.setChecked(false);
383             mBluetoothSettings.setEnabled(false);
384             mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
385         }
386     }
387
388     @Override
389     public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
390         if (preference == mUsbTether) {
391             boolean newState = mUsbTether.isChecked();
392
393             ConnectivityManager cm =
394                     (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
395
396             if (newState) {
397                 String[] available = cm.getTetherableIfaces();
398
399                 String usbIface = findIface(available, mUsbRegexs);
400                 if (usbIface == null) {
401                     updateState();
402                     return true;
403                 }
404                 if (cm.tether(usbIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
405                     mUsbTether.setChecked(false);
406                     mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
407                     return true;
408                 }
409                 mUsbTether.setSummary("");
410             } else {
411                 String [] tethered = cm.getTetheredIfaces();
412
413                 String usbIface = findIface(tethered, mUsbRegexs);
414                 if (usbIface == null) {
415                     updateState();
416                     return true;
417                 }
418                 if (cm.untether(usbIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
419                     mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
420                     return true;
421                 }
422                 mUsbTether.setSummary("");
423             }
424         } else if(preference == mBluetoothTether) {
425             boolean bluetoothTetherState = mBluetoothTether.isChecked();
426
427             if (bluetoothTetherState) {
428                 // turn on Bluetooth first
429                 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
430                 if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
431                     adapter.enable();
432                     mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
433                     mBluetoothTether.setEnabled(false);
434                     mBluetoothSettings.setEnabled(false);
435                 } else {
436                     mBluetoothSettings.setEnabled(true);
437                 }
438
439                 mBluetoothPan.setBluetoothTethering(true);
440                 mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
441             } else {
442                 boolean errored = false;
443
444                 ConnectivityManager cm =
445                     (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
446                 String [] tethered = cm.getTetheredIfaces();
447                 String bluetoothIface = findIface(tethered, mBluetoothRegexs);
448                 if (bluetoothIface != null &&
449                         cm.untether(bluetoothIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
450                     errored = true;
451                 }
452
453                 mBluetoothPan.setBluetoothTethering(false);
454                 mBluetoothSettings.setEnabled(false);
455                 if (errored) {
456                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
457                 } else {
458                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
459                 }
460             }
461         } else if (preference == mBluetoothSettings) {
462             preference.getExtras().putString(BluetoothSettings.ACTION,
463                     BluetoothSettings.ACTION_LAUNCH_TETHER_PICKER);
464         } else if (preference == mTetherHelp) {
465             showDialog(DIALOG_TETHER_HELP);
466             return true;
467         }
468
469         return super.onPreferenceTreeClick(screen, preference);
470     }
471
472     private String findIface(String[] ifaces, String[] regexes) {
473         for (String iface : ifaces) {
474             for (String regex : regexes) {
475                 if (iface.matches(regex)) {
476                     return iface;
477                 }
478             }
479         }
480         return null;
481     }
482 }