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