Home | History | Annotate | Download | only in settings
      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.wifi.WifiApEnabler;
     20 import com.android.settings.wifi.WifiApDialog;
     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.bluetooth.BluetoothProfile;
     28 import android.content.BroadcastReceiver;
     29 import android.content.Context;
     30 import android.content.DialogInterface;
     31 import android.content.Intent;
     32 import android.content.IntentFilter;
     33 import android.content.res.AssetManager;
     34 import android.hardware.usb.UsbManager;
     35 import android.net.ConnectivityManager;
     36 import android.net.wifi.WifiConfiguration;
     37 import android.net.wifi.WifiManager;
     38 import android.os.Bundle;
     39 import android.os.Environment;
     40 import android.os.SystemProperties;
     41 import android.os.UserHandle;
     42 import android.os.UserManager;
     43 import android.preference.CheckBoxPreference;
     44 import android.preference.Preference;
     45 import android.preference.PreferenceScreen;
     46 import android.text.TextUtils;
     47 import android.view.ViewGroup;
     48 import android.view.ViewParent;
     49 import android.webkit.WebView;
     50 
     51 import java.io.InputStream;
     52 import java.util.ArrayList;
     53 import java.util.concurrent.atomic.AtomicReference;
     54 import java.util.Locale;
     55 
     56 /*
     57  * Displays preferences for Tethering.
     58  */
     59 public class TetherSettings extends SettingsPreferenceFragment
     60         implements DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener {
     61     private static final String TAG = "TetherSettings";
     62 
     63     private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
     64     private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
     65     private static final String ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
     66 
     67     private static final int DIALOG_AP_SETTINGS = 1;
     68 
     69     private WebView mView;
     70     private CheckBoxPreference mUsbTether;
     71 
     72     private WifiApEnabler mWifiApEnabler;
     73     private CheckBoxPreference mEnableWifiAp;
     74 
     75     private CheckBoxPreference mBluetoothTether;
     76 
     77     private BroadcastReceiver mTetherChangeReceiver;
     78 
     79     private String[] mUsbRegexs;
     80 
     81     private String[] mWifiRegexs;
     82 
     83     private String[] mBluetoothRegexs;
     84     private AtomicReference<BluetoothPan> mBluetoothPan = new AtomicReference<BluetoothPan>();
     85 
     86     private static final String WIFI_AP_SSID_AND_SECURITY = "wifi_ap_ssid_and_security";
     87     private static final int CONFIG_SUBTEXT = R.string.wifi_tether_configure_subtext;
     88 
     89     private String[] mSecurityType;
     90     private Preference mCreateNetwork;
     91 
     92     private WifiApDialog mDialog;
     93     private WifiManager mWifiManager;
     94     private WifiConfiguration mWifiConfig = null;
     95 
     96     private boolean mUsbConnected;
     97     private boolean mMassStorageActive;
     98 
     99     private boolean mBluetoothEnableForTether;
    100 
    101     private static final int INVALID             = -1;
    102     private static final int WIFI_TETHERING      = 0;
    103     private static final int USB_TETHERING       = 1;
    104     private static final int BLUETOOTH_TETHERING = 2;
    105 
    106     /* One of INVALID, WIFI_TETHERING, USB_TETHERING or BLUETOOTH_TETHERING */
    107     private int mTetherChoice = INVALID;
    108 
    109     /* Stores the package name and the class name of the provisioning app */
    110     private String[] mProvisionApp;
    111     private static final int PROVISION_REQUEST = 0;
    112 
    113     @Override
    114     public void onCreate(Bundle icicle) {
    115         super.onCreate(icicle);
    116         addPreferencesFromResource(R.xml.tether_prefs);
    117 
    118         final Activity activity = getActivity();
    119         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    120         if (adapter != null) {
    121             adapter.getProfileProxy(activity.getApplicationContext(), mProfileServiceListener,
    122                     BluetoothProfile.PAN);
    123         }
    124 
    125         mEnableWifiAp =
    126                 (CheckBoxPreference) findPreference(ENABLE_WIFI_AP);
    127         Preference wifiApSettings = findPreference(WIFI_AP_SSID_AND_SECURITY);
    128         mUsbTether = (CheckBoxPreference) findPreference(USB_TETHER_SETTINGS);
    129         mBluetoothTether = (CheckBoxPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
    130 
    131         ConnectivityManager cm =
    132                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    133 
    134         mUsbRegexs = cm.getTetherableUsbRegexs();
    135         mWifiRegexs = cm.getTetherableWifiRegexs();
    136         mBluetoothRegexs = cm.getTetherableBluetoothRegexs();
    137 
    138         final boolean usbAvailable = mUsbRegexs.length != 0;
    139         final boolean wifiAvailable = mWifiRegexs.length != 0;
    140         final boolean bluetoothAvailable = mBluetoothRegexs.length != 0;
    141 
    142         if (!usbAvailable || Utils.isMonkeyRunning()) {
    143             getPreferenceScreen().removePreference(mUsbTether);
    144         }
    145 
    146         if (wifiAvailable && !Utils.isMonkeyRunning()) {
    147             mWifiApEnabler = new WifiApEnabler(activity, mEnableWifiAp);
    148             initWifiTethering();
    149         } else {
    150             getPreferenceScreen().removePreference(mEnableWifiAp);
    151             getPreferenceScreen().removePreference(wifiApSettings);
    152         }
    153 
    154         if (!bluetoothAvailable) {
    155             getPreferenceScreen().removePreference(mBluetoothTether);
    156         } else {
    157             BluetoothPan pan = mBluetoothPan.get();
    158             if (pan != null && pan.isTetheringOn()) {
    159                 mBluetoothTether.setChecked(true);
    160             } else {
    161                 mBluetoothTether.setChecked(false);
    162             }
    163         }
    164 
    165         mProvisionApp = getResources().getStringArray(
    166                 com.android.internal.R.array.config_mobile_hotspot_provision_app);
    167 
    168         mView = new WebView(activity);
    169     }
    170 
    171     private void initWifiTethering() {
    172         final Activity activity = getActivity();
    173         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    174         mWifiConfig = mWifiManager.getWifiApConfiguration();
    175         mSecurityType = getResources().getStringArray(R.array.wifi_ap_security);
    176 
    177         mCreateNetwork = findPreference(WIFI_AP_SSID_AND_SECURITY);
    178 
    179         if (mWifiConfig == null) {
    180             final String s = activity.getString(
    181                     com.android.internal.R.string.wifi_tether_configure_ssid_default);
    182             mCreateNetwork.setSummary(String.format(activity.getString(CONFIG_SUBTEXT),
    183                     s, mSecurityType[WifiApDialog.OPEN_INDEX]));
    184         } else {
    185             int index = WifiApDialog.getSecurityTypeIndex(mWifiConfig);
    186             mCreateNetwork.setSummary(String.format(activity.getString(CONFIG_SUBTEXT),
    187                     mWifiConfig.SSID,
    188                     mSecurityType[index]));
    189         }
    190     }
    191 
    192     private BluetoothProfile.ServiceListener mProfileServiceListener =
    193         new BluetoothProfile.ServiceListener() {
    194         public void onServiceConnected(int profile, BluetoothProfile proxy) {
    195             mBluetoothPan.set((BluetoothPan) proxy);
    196         }
    197         public void onServiceDisconnected(int profile) {
    198             mBluetoothPan.set(null);
    199         }
    200     };
    201 
    202     @Override
    203     public Dialog onCreateDialog(int id) {
    204         if (id == DIALOG_AP_SETTINGS) {
    205             final Activity activity = getActivity();
    206             mDialog = new WifiApDialog(activity, this, mWifiConfig);
    207             return mDialog;
    208         }
    209 
    210         return null;
    211     }
    212 
    213     private class TetherChangeReceiver extends BroadcastReceiver {
    214         @Override
    215         public void onReceive(Context content, Intent intent) {
    216             String action = intent.getAction();
    217             if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
    218                 // TODO - this should understand the interface types
    219                 ArrayList<String> available = intent.getStringArrayListExtra(
    220                         ConnectivityManager.EXTRA_AVAILABLE_TETHER);
    221                 ArrayList<String> active = intent.getStringArrayListExtra(
    222                         ConnectivityManager.EXTRA_ACTIVE_TETHER);
    223                 ArrayList<String> errored = intent.getStringArrayListExtra(
    224                         ConnectivityManager.EXTRA_ERRORED_TETHER);
    225                 updateState(available.toArray(new String[available.size()]),
    226                         active.toArray(new String[active.size()]),
    227                         errored.toArray(new String[errored.size()]));
    228             } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) {
    229                 mMassStorageActive = true;
    230                 updateState();
    231             } else if (action.equals(Intent.ACTION_MEDIA_UNSHARED)) {
    232                 mMassStorageActive = false;
    233                 updateState();
    234             } else if (action.equals(UsbManager.ACTION_USB_STATE)) {
    235                 mUsbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
    236                 updateState();
    237             } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
    238                 if (mBluetoothEnableForTether) {
    239                     switch (intent
    240                             .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) {
    241                         case BluetoothAdapter.STATE_ON:
    242                             BluetoothPan bluetoothPan = mBluetoothPan.get();
    243                             if (bluetoothPan != null) {
    244                                 bluetoothPan.setBluetoothTethering(true);
    245                                 mBluetoothEnableForTether = false;
    246                             }
    247                             break;
    248 
    249                         case BluetoothAdapter.STATE_OFF:
    250                         case BluetoothAdapter.ERROR:
    251                             mBluetoothEnableForTether = false;
    252                             break;
    253 
    254                         default:
    255                             // ignore transition states
    256                     }
    257                 }
    258                 updateState();
    259             }
    260         }
    261     }
    262 
    263     @Override
    264     public void onStart() {
    265         super.onStart();
    266 
    267         final Activity activity = getActivity();
    268 
    269         mMassStorageActive = Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState());
    270         mTetherChangeReceiver = new TetherChangeReceiver();
    271         IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
    272         Intent intent = activity.registerReceiver(mTetherChangeReceiver, filter);
    273 
    274         filter = new IntentFilter();
    275         filter.addAction(UsbManager.ACTION_USB_STATE);
    276         activity.registerReceiver(mTetherChangeReceiver, filter);
    277 
    278         filter = new IntentFilter();
    279         filter.addAction(Intent.ACTION_MEDIA_SHARED);
    280         filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
    281         filter.addDataScheme("file");
    282         activity.registerReceiver(mTetherChangeReceiver, filter);
    283 
    284         filter = new IntentFilter();
    285         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
    286         activity.registerReceiver(mTetherChangeReceiver, filter);
    287 
    288         if (intent != null) mTetherChangeReceiver.onReceive(activity, intent);
    289         if (mWifiApEnabler != null) {
    290             mEnableWifiAp.setOnPreferenceChangeListener(this);
    291             mWifiApEnabler.resume();
    292         }
    293 
    294         updateState();
    295     }
    296 
    297     @Override
    298     public void onStop() {
    299         super.onStop();
    300         getActivity().unregisterReceiver(mTetherChangeReceiver);
    301         mTetherChangeReceiver = null;
    302         if (mWifiApEnabler != null) {
    303             mEnableWifiAp.setOnPreferenceChangeListener(null);
    304             mWifiApEnabler.pause();
    305         }
    306     }
    307 
    308     private void updateState() {
    309         ConnectivityManager cm =
    310                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    311 
    312         String[] available = cm.getTetherableIfaces();
    313         String[] tethered = cm.getTetheredIfaces();
    314         String[] errored = cm.getTetheringErroredIfaces();
    315         updateState(available, tethered, errored);
    316     }
    317 
    318     private void updateState(String[] available, String[] tethered,
    319             String[] errored) {
    320         updateUsbState(available, tethered, errored);
    321         updateBluetoothState(available, tethered, errored);
    322     }
    323 
    324 
    325     private void updateUsbState(String[] available, String[] tethered,
    326             String[] errored) {
    327         ConnectivityManager cm =
    328                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    329         boolean usbAvailable = mUsbConnected && !mMassStorageActive;
    330         int usbError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
    331         for (String s : available) {
    332             for (String regex : mUsbRegexs) {
    333                 if (s.matches(regex)) {
    334                     if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
    335                         usbError = cm.getLastTetherError(s);
    336                     }
    337                 }
    338             }
    339         }
    340         boolean usbTethered = false;
    341         for (String s : tethered) {
    342             for (String regex : mUsbRegexs) {
    343                 if (s.matches(regex)) usbTethered = true;
    344             }
    345         }
    346         boolean usbErrored = false;
    347         for (String s: errored) {
    348             for (String regex : mUsbRegexs) {
    349                 if (s.matches(regex)) usbErrored = true;
    350             }
    351         }
    352 
    353         if (usbTethered) {
    354             mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
    355             mUsbTether.setEnabled(true);
    356             mUsbTether.setChecked(true);
    357         } else if (usbAvailable) {
    358             if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
    359                 mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
    360             } else {
    361                 mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
    362             }
    363             mUsbTether.setEnabled(true);
    364             mUsbTether.setChecked(false);
    365         } else if (usbErrored) {
    366             mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
    367             mUsbTether.setEnabled(false);
    368             mUsbTether.setChecked(false);
    369         } else if (mMassStorageActive) {
    370             mUsbTether.setSummary(R.string.usb_tethering_storage_active_subtext);
    371             mUsbTether.setEnabled(false);
    372             mUsbTether.setChecked(false);
    373         } else {
    374             mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
    375             mUsbTether.setEnabled(false);
    376             mUsbTether.setChecked(false);
    377         }
    378     }
    379 
    380     private void updateBluetoothState(String[] available, String[] tethered,
    381             String[] errored) {
    382         boolean bluetoothErrored = false;
    383         for (String s: errored) {
    384             for (String regex : mBluetoothRegexs) {
    385                 if (s.matches(regex)) bluetoothErrored = true;
    386             }
    387         }
    388 
    389         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    390         int btState = adapter.getState();
    391         if (btState == BluetoothAdapter.STATE_TURNING_OFF) {
    392             mBluetoothTether.setEnabled(false);
    393             mBluetoothTether.setSummary(R.string.bluetooth_turning_off);
    394         } else if (btState == BluetoothAdapter.STATE_TURNING_ON) {
    395             mBluetoothTether.setEnabled(false);
    396             mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
    397         } else {
    398             BluetoothPan bluetoothPan = mBluetoothPan.get();
    399             if (btState == BluetoothAdapter.STATE_ON && bluetoothPan != null &&
    400                     bluetoothPan.isTetheringOn()) {
    401                 mBluetoothTether.setChecked(true);
    402                 mBluetoothTether.setEnabled(true);
    403                 int bluetoothTethered = bluetoothPan.getConnectedDevices().size();
    404                 if (bluetoothTethered > 1) {
    405                     String summary = getString(
    406                             R.string.bluetooth_tethering_devices_connected_subtext,
    407                             bluetoothTethered);
    408                     mBluetoothTether.setSummary(summary);
    409                 } else if (bluetoothTethered == 1) {
    410                     mBluetoothTether.setSummary(
    411                             R.string.bluetooth_tethering_device_connected_subtext);
    412                 } else if (bluetoothErrored) {
    413                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
    414                 } else {
    415                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
    416                 }
    417             } else {
    418                 mBluetoothTether.setEnabled(true);
    419                 mBluetoothTether.setChecked(false);
    420                 mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
    421             }
    422         }
    423     }
    424 
    425     public boolean onPreferenceChange(Preference preference, Object value) {
    426         boolean enable = (Boolean) value;
    427 
    428         if (enable) {
    429             startProvisioningIfNecessary(WIFI_TETHERING);
    430         } else {
    431             mWifiApEnabler.setSoftapEnabled(false);
    432         }
    433         return false;
    434     }
    435 
    436     boolean isProvisioningNeeded() {
    437         if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
    438             return false;
    439         }
    440         return mProvisionApp.length == 2;
    441     }
    442 
    443     private void startProvisioningIfNecessary(int choice) {
    444         mTetherChoice = choice;
    445         if (isProvisioningNeeded()) {
    446             Intent intent = new Intent(Intent.ACTION_MAIN);
    447             intent.setClassName(mProvisionApp[0], mProvisionApp[1]);
    448             startActivityForResult(intent, PROVISION_REQUEST);
    449         } else {
    450             startTethering();
    451         }
    452     }
    453 
    454     public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    455         super.onActivityResult(requestCode, resultCode, intent);
    456         if (requestCode == PROVISION_REQUEST) {
    457             if (resultCode == Activity.RESULT_OK) {
    458                 startTethering();
    459             } else {
    460                 //BT and USB need checkbox turned off on failure
    461                 //Wifi tethering is never turned on until afterwards
    462                 switch (mTetherChoice) {
    463                     case BLUETOOTH_TETHERING:
    464                         mBluetoothTether.setChecked(false);
    465                         break;
    466                     case USB_TETHERING:
    467                         mUsbTether.setChecked(false);
    468                         break;
    469                 }
    470                 mTetherChoice = INVALID;
    471             }
    472         }
    473     }
    474 
    475     private void startTethering() {
    476         switch (mTetherChoice) {
    477             case WIFI_TETHERING:
    478                 mWifiApEnabler.setSoftapEnabled(true);
    479                 break;
    480             case BLUETOOTH_TETHERING:
    481                 // turn on Bluetooth first
    482                 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    483                 if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
    484                     mBluetoothEnableForTether = true;
    485                     adapter.enable();
    486                     mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
    487                     mBluetoothTether.setEnabled(false);
    488                 } else {
    489                     BluetoothPan bluetoothPan = mBluetoothPan.get();
    490                     if (bluetoothPan != null) bluetoothPan.setBluetoothTethering(true);
    491                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
    492                 }
    493                 break;
    494             case USB_TETHERING:
    495                 setUsbTethering(true);
    496                 break;
    497             default:
    498                 //should not happen
    499                 break;
    500         }
    501     }
    502 
    503     private void setUsbTethering(boolean enabled) {
    504         ConnectivityManager cm =
    505             (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    506         mUsbTether.setChecked(false);
    507         if (cm.setUsbTethering(enabled) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
    508             mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
    509             return;
    510         }
    511         mUsbTether.setSummary("");
    512     }
    513 
    514     @Override
    515     public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
    516         ConnectivityManager cm =
    517                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    518 
    519         if (preference == mUsbTether) {
    520             boolean newState = mUsbTether.isChecked();
    521 
    522             if (newState) {
    523                 startProvisioningIfNecessary(USB_TETHERING);
    524             } else {
    525                 setUsbTethering(newState);
    526             }
    527         } else if (preference == mBluetoothTether) {
    528             boolean bluetoothTetherState = mBluetoothTether.isChecked();
    529 
    530             if (bluetoothTetherState) {
    531                 startProvisioningIfNecessary(BLUETOOTH_TETHERING);
    532             } else {
    533                 boolean errored = false;
    534 
    535                 String [] tethered = cm.getTetheredIfaces();
    536                 String bluetoothIface = findIface(tethered, mBluetoothRegexs);
    537                 if (bluetoothIface != null &&
    538                         cm.untether(bluetoothIface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
    539                     errored = true;
    540                 }
    541 
    542                 BluetoothPan bluetoothPan = mBluetoothPan.get();
    543                 if (bluetoothPan != null) bluetoothPan.setBluetoothTethering(false);
    544                 if (errored) {
    545                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
    546                 } else {
    547                     mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
    548                 }
    549             }
    550         } else if (preference == mCreateNetwork) {
    551             showDialog(DIALOG_AP_SETTINGS);
    552         }
    553 
    554         return super.onPreferenceTreeClick(screen, preference);
    555     }
    556 
    557     private static String findIface(String[] ifaces, String[] regexes) {
    558         for (String iface : ifaces) {
    559             for (String regex : regexes) {
    560                 if (iface.matches(regex)) {
    561                     return iface;
    562                 }
    563             }
    564         }
    565         return null;
    566     }
    567 
    568     public void onClick(DialogInterface dialogInterface, int button) {
    569         if (button == DialogInterface.BUTTON_POSITIVE) {
    570             mWifiConfig = mDialog.getConfig();
    571             if (mWifiConfig != null) {
    572                 /**
    573                  * if soft AP is stopped, bring up
    574                  * else restart with new config
    575                  * TODO: update config on a running access point when framework support is added
    576                  */
    577                 if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) {
    578                     mWifiManager.setWifiApEnabled(null, false);
    579                     mWifiManager.setWifiApEnabled(mWifiConfig, true);
    580                 } else {
    581                     mWifiManager.setWifiApConfiguration(mWifiConfig);
    582                 }
    583                 int index = WifiApDialog.getSecurityTypeIndex(mWifiConfig);
    584                 mCreateNetwork.setSummary(String.format(getActivity().getString(CONFIG_SUBTEXT),
    585                         mWifiConfig.SSID,
    586                         mSecurityType[index]));
    587             }
    588         }
    589     }
    590 
    591     @Override
    592     public int getHelpResource() {
    593         return R.string.help_url_tether;
    594     }
    595 
    596     /**
    597      * Checks whether this screen will have anything to show on this device. This is called by
    598      * the shortcut picker for Settings shortcuts (home screen widget).
    599      * @param context a context object for getting a system service.
    600      * @return whether Tether & portable hotspot should be shown in the shortcuts picker.
    601      */
    602     public static boolean showInShortcuts(Context context) {
    603         final ConnectivityManager cm =
    604                 (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    605         final boolean isSecondaryUser = UserHandle.myUserId() != UserHandle.USER_OWNER;
    606         return !isSecondaryUser && cm.isTetheringSupported();
    607     }
    608 }
    609