Files
app_Settings/src/com/android/settings/TetherSettings.java
Ben Clark 0008d219a2 Refactor to remove multiple in-loop Object[]->String[] castings
(This replaces Iaa0f3b25eaadb094a4c3fb4cecbd09e0322aae33)

This change removes the need to convert Object[]->String[] for each iteration
of each of available,tethered,errored states in updateStatus()
by converting these as soon as possible.

This fix (and the code before) is strange because each of available,tethered,
errored are defined as type ArrayList<String> but
intent.getStringArrayListExtra() returns type Object[] dispite its name.
Because other calls to updateState() use String[] it seems best to do the
conversion outside this method in the Object[] case and thus avoid the
per-iteration casting in the Object[] case and the downright wasteful
per-iteration String[]->Object[]->String[] casting in the String[] input cases.

I've also removed some unused imports and an unused variable.

Change-Id: I805ef19aa9ceff7e4fc491623cdcb413ce170798
2010-07-29 20:51:31 +01:00

317 lines
12 KiB
Java

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import com.android.settings.wifi.WifiApEnabler;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetManager;
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.webkit.WebView;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Locale;
/*
* Displays preferences for Tethering.
*/
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 String HELP_PATH = "html/%y%z/tethering_help.html";
private static final int DIALOG_TETHER_HELP = 1;
private WebView mView;
private CheckBoxPreference mUsbTether;
private CheckBoxPreference mEnableWifiAp;
private PreferenceScreen mWifiApSettings;
private WifiApEnabler mWifiApEnabler;
private PreferenceScreen mTetherHelp;
private BroadcastReceiver mTetherChangeReceiver;
private String[] mUsbRegexs;
private String[] mWifiRegexs;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.tether_prefs);
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);
setTitle(R.string.tether_settings_title_wifi);
}
mWifiRegexs = cm.getTetherableWifiRegexs();
if (mWifiRegexs.length == 0) {
getPreferenceScreen().removePreference(mEnableWifiAp);
getPreferenceScreen().removePreference(mWifiApSettings);
setTitle(R.string.tether_settings_title_usb);
} else if (mUsbRegexs.length != 0) {
// have both
setTitle(R.string.tether_settings_title_both);
}
mWifiApEnabler = new WifiApEnabler(this, mEnableWifiAp);
mView = new WebView(this);
}
@Override
protected Dialog onCreateDialog(int id) {
if (id == DIALOG_TETHER_HELP) {
Locale locale = Locale.getDefault();
// check for the full language + country resource, if not there, try just language
AssetManager am = getAssets();
String path = HELP_PATH.replace("%y", locale.getLanguage().toLowerCase());
path = path.replace("%z", "_"+locale.getCountry().toLowerCase());
boolean useCountry = true;
InputStream is = null;
try {
is = am.open(path);
} catch (Exception e) {
useCountry = false;
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {}
}
}
String url = HELP_URL.replace("%y", locale.getLanguage().toLowerCase());
url = url.replace("%z", (useCountry ? "_"+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) {
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((String[]) available.toArray(), (String[]) active.toArray(),
(String[]) errored.toArray());
} else if (intent.getAction().equals(Intent.ACTION_MEDIA_SHARED) ||
intent.getAction().equals(Intent.ACTION_MEDIA_UNSHARED)) {
updateState();
}
}
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
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();
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mTetherChangeReceiver);
mTetherChangeReceiver = null;
mWifiApEnabler.pause();
}
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(String[] available, String[] tethered,
String[] 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 massStorageActive =
Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState());
for (String s : available) {
for (String regex : mUsbRegexs) {
if (s.matches(regex)) {
usbAvailable = true;
if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
usbError = cm.getLastTetherError(s);
}
}
}
}
for (String s : tethered) {
for (String regex : mUsbRegexs) {
if (s.matches(regex)) usbTethered = true;
}
}
for (String s: errored) {
for (String regex : mUsbRegexs) {
if (s.matches(regex)) usbErrored = true;
}
}
if (usbTethered) {
mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
mUsbTether.setEnabled(true);
mUsbTether.setChecked(true);
} else if (usbAvailable) {
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;
}
}