1 /* 2 * Copyright (C) 2011 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.wifi.p2p; 18 19 import android.app.Activity; 20 import android.app.Dialog; 21 import android.app.settings.SettingsEnums; 22 import android.content.BroadcastReceiver; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.DialogInterface.OnClickListener; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.net.NetworkInfo; 29 import android.net.wifi.WpsInfo; 30 import android.net.wifi.p2p.WifiP2pConfig; 31 import android.net.wifi.p2p.WifiP2pDevice; 32 import android.net.wifi.p2p.WifiP2pDeviceList; 33 import android.net.wifi.p2p.WifiP2pGroup; 34 import android.net.wifi.p2p.WifiP2pGroupList; 35 import android.net.wifi.p2p.WifiP2pInfo; 36 import android.net.wifi.p2p.WifiP2pManager; 37 import android.net.wifi.p2p.WifiP2pManager.DeviceInfoListener; 38 import android.net.wifi.p2p.WifiP2pManager.PeerListListener; 39 import android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener; 40 import android.os.Bundle; 41 import android.sysprop.TelephonyProperties; 42 import android.text.InputFilter; 43 import android.text.TextUtils; 44 import android.util.Log; 45 import android.view.LayoutInflater; 46 import android.view.Menu; 47 import android.view.MenuInflater; 48 import android.view.MenuItem; 49 import android.view.View; 50 import android.widget.EditText; 51 import android.widget.Toast; 52 53 import androidx.annotation.VisibleForTesting; 54 import androidx.appcompat.app.AlertDialog; 55 import androidx.preference.Preference; 56 import androidx.preference.PreferenceScreen; 57 58 import com.android.settings.R; 59 import com.android.settings.dashboard.DashboardFragment; 60 import com.android.settingslib.core.AbstractPreferenceController; 61 62 import java.util.ArrayList; 63 import java.util.List; 64 65 /* 66 * Displays Wi-fi p2p settings UI 67 */ 68 public class WifiP2pSettings extends DashboardFragment 69 implements PersistentGroupInfoListener, PeerListListener, DeviceInfoListener { 70 71 private static final String TAG = "WifiP2pSettings"; 72 private static final boolean DBG = false; 73 @VisibleForTesting static final int MENU_ID_SEARCH = Menu.FIRST; 74 @VisibleForTesting static final int MENU_ID_RENAME = Menu.FIRST + 1; 75 76 private final IntentFilter mIntentFilter = new IntentFilter(); 77 @VisibleForTesting WifiP2pManager mWifiP2pManager; 78 @VisibleForTesting WifiP2pManager.Channel mChannel; 79 @VisibleForTesting OnClickListener mRenameListener; 80 @VisibleForTesting OnClickListener mDisconnectListener; 81 @VisibleForTesting OnClickListener mCancelConnectListener; 82 @VisibleForTesting OnClickListener mDeleteGroupListener; 83 @VisibleForTesting WifiP2pPeer mSelectedWifiPeer; 84 @VisibleForTesting WifiP2pPersistentGroup mSelectedGroup; 85 @VisibleForTesting String mSelectedGroupName; 86 private EditText mDeviceNameText; 87 88 private boolean mWifiP2pEnabled; 89 @VisibleForTesting boolean mWifiP2pSearching; 90 @VisibleForTesting int mConnectedDevices; 91 @VisibleForTesting boolean mLastGroupFormed = false; 92 private boolean mIsIgnoreInitConnectionInfoCallback = false; 93 94 @VisibleForTesting P2pPeerCategoryPreferenceController mPeerCategoryController; 95 @VisibleForTesting P2pPersistentCategoryPreferenceController mPersistentCategoryController; 96 @VisibleForTesting P2pThisDevicePreferenceController mThisDevicePreferenceController; 97 98 @VisibleForTesting static final int DIALOG_DISCONNECT = 1; 99 @VisibleForTesting static final int DIALOG_CANCEL_CONNECT = 2; 100 @VisibleForTesting static final int DIALOG_RENAME = 3; 101 @VisibleForTesting static final int DIALOG_DELETE_GROUP = 4; 102 103 @VisibleForTesting static final String SAVE_DIALOG_PEER = "PEER_STATE"; 104 @VisibleForTesting static final String SAVE_DEVICE_NAME = "DEV_NAME"; 105 @VisibleForTesting static final String SAVE_SELECTED_GROUP = "GROUP_NAME"; 106 107 private WifiP2pDevice mThisDevice; 108 private WifiP2pDeviceList mPeers = new WifiP2pDeviceList(); 109 110 @VisibleForTesting String mSavedDeviceName; 111 112 @VisibleForTesting 113 final BroadcastReceiver mReceiver = new BroadcastReceiver() { 114 @Override 115 public void onReceive(Context context, Intent intent) { 116 String action = intent.getAction(); 117 118 if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { 119 mWifiP2pEnabled = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, 120 WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED; 121 handleP2pStateChanged(); 122 } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { 123 mPeers = (WifiP2pDeviceList) intent.getParcelableExtra( 124 WifiP2pManager.EXTRA_P2P_DEVICE_LIST); 125 handlePeersChanged(); 126 } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { 127 if (mWifiP2pManager == null) return; 128 NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra( 129 WifiP2pManager.EXTRA_NETWORK_INFO); 130 WifiP2pInfo wifip2pinfo = (WifiP2pInfo) intent.getParcelableExtra( 131 WifiP2pManager.EXTRA_WIFI_P2P_INFO); 132 if (networkInfo.isConnected()) { 133 if (DBG) Log.d(TAG, "Connected"); 134 } else if (mLastGroupFormed != true) { 135 //start a search when we are disconnected 136 //but not on group removed broadcast event 137 startSearch(); 138 } 139 mLastGroupFormed = wifip2pinfo.groupFormed; 140 mIsIgnoreInitConnectionInfoCallback = true; 141 } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { 142 // Do not use WifiP2pManager.EXTRA_WIFI_P2P_DEVICE from the extras, as the system 143 // broadcast does not contain the device's MAC. 144 // Requesting our own device info as an app holding the NETWORK_SETTINGS permission 145 // ensures that the MAC address will be available in the result. 146 if (DBG) Log.d(TAG, "This device changed. Requesting device info."); 147 if (mWifiP2pManager != null && mChannel != null) { 148 mWifiP2pManager.requestDeviceInfo(mChannel, WifiP2pSettings.this); 149 } 150 } else if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) { 151 int discoveryState = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, 152 WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED); 153 if (DBG) Log.d(TAG, "Discovery state changed: " + discoveryState); 154 if (discoveryState == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) { 155 updateSearchMenu(true); 156 } else { 157 updateSearchMenu(false); 158 } 159 } else if (WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED.equals(action)) { 160 if (mWifiP2pManager != null && mChannel != null) { 161 mWifiP2pManager.requestPersistentGroupInfo(mChannel, WifiP2pSettings.this); 162 } 163 } 164 } 165 }; 166 167 @Override getLogTag()168 protected String getLogTag() { 169 return TAG; 170 } 171 172 @Override getPreferenceScreenResId()173 protected int getPreferenceScreenResId() { 174 return R.xml.wifi_p2p_settings; 175 } 176 177 @Override getMetricsCategory()178 public int getMetricsCategory() { 179 return SettingsEnums.WIFI_P2P; 180 } 181 182 @Override getHelpResource()183 public int getHelpResource() { 184 return R.string.help_url_wifi_p2p; 185 } 186 187 @Override createPreferenceControllers(Context context)188 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { 189 final List<AbstractPreferenceController> controllers = new ArrayList<>(); 190 mPersistentCategoryController = 191 new P2pPersistentCategoryPreferenceController(context); 192 mPeerCategoryController = 193 new P2pPeerCategoryPreferenceController(context); 194 mThisDevicePreferenceController = new P2pThisDevicePreferenceController(context); 195 controllers.add(mPersistentCategoryController); 196 controllers.add(mPeerCategoryController); 197 controllers.add(mThisDevicePreferenceController); 198 return controllers; 199 } 200 201 @Override onActivityCreated(Bundle savedInstanceState)202 public void onActivityCreated(Bundle savedInstanceState) { 203 final Activity activity = getActivity(); 204 if (mWifiP2pManager == null) { 205 mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); 206 } 207 208 if (mWifiP2pManager != null) { 209 if (!initChannel()) { 210 //Failure to set up connection 211 Log.e(TAG, "Failed to set up connection with wifi p2p service"); 212 mWifiP2pManager = null; 213 } 214 } else { 215 Log.e(TAG, "mWifiP2pManager is null !"); 216 } 217 218 if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DIALOG_PEER)) { 219 WifiP2pDevice device = savedInstanceState.getParcelable(SAVE_DIALOG_PEER); 220 mSelectedWifiPeer = new WifiP2pPeer(getPrefContext(), device); 221 } 222 if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DEVICE_NAME)) { 223 mSavedDeviceName = savedInstanceState.getString(SAVE_DEVICE_NAME); 224 } 225 if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_SELECTED_GROUP)) { 226 mSelectedGroupName = savedInstanceState.getString(SAVE_SELECTED_GROUP); 227 } 228 229 mRenameListener = new OnClickListener() { 230 @Override 231 public void onClick(DialogInterface dialog, int which) { 232 if (which == DialogInterface.BUTTON_POSITIVE) { 233 if (mWifiP2pManager != null && mChannel != null) { 234 String name = mDeviceNameText.getText().toString(); 235 if (name != null) { 236 for (int i = 0; i < name.length(); i++) { 237 char cur = name.charAt(i); 238 if(!Character.isDigit(cur) && !Character.isLetter(cur) 239 && cur != '-' && cur != '_' && cur != ' ') { 240 Toast.makeText(getActivity(), 241 R.string.wifi_p2p_failed_rename_message, 242 Toast.LENGTH_LONG).show(); 243 return; 244 } 245 } 246 } 247 mWifiP2pManager.setDeviceName(mChannel, 248 mDeviceNameText.getText().toString(), 249 new WifiP2pManager.ActionListener() { 250 public void onSuccess() { 251 if (DBG) Log.d(TAG, " device rename success"); 252 } 253 public void onFailure(int reason) { 254 Toast.makeText(getActivity(), 255 R.string.wifi_p2p_failed_rename_message, 256 Toast.LENGTH_LONG).show(); 257 } 258 }); 259 } 260 } 261 } 262 }; 263 264 //disconnect dialog listener 265 mDisconnectListener = new OnClickListener() { 266 @Override 267 public void onClick(DialogInterface dialog, int which) { 268 if (which == DialogInterface.BUTTON_POSITIVE) { 269 if (mWifiP2pManager != null && mChannel != null) { 270 mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() { 271 public void onSuccess() { 272 if (DBG) Log.d(TAG, " remove group success"); 273 } 274 public void onFailure(int reason) { 275 if (DBG) Log.d(TAG, " remove group fail " + reason); 276 } 277 }); 278 } 279 } 280 } 281 }; 282 283 //cancel connect dialog listener 284 mCancelConnectListener = new OnClickListener() { 285 @Override 286 public void onClick(DialogInterface dialog, int which) { 287 if (which == DialogInterface.BUTTON_POSITIVE) { 288 if (mWifiP2pManager != null && mChannel != null) { 289 mWifiP2pManager.cancelConnect(mChannel, 290 new WifiP2pManager.ActionListener() { 291 public void onSuccess() { 292 if (DBG) Log.d(TAG, " cancel connect success"); 293 } 294 public void onFailure(int reason) { 295 if (DBG) Log.d(TAG, " cancel connect fail " + reason); 296 } 297 }); 298 } 299 } 300 } 301 }; 302 303 //delete persistent group dialog listener 304 mDeleteGroupListener = new OnClickListener() { 305 @Override 306 public void onClick(DialogInterface dialog, int which) { 307 if (which == DialogInterface.BUTTON_POSITIVE) { 308 if (mWifiP2pManager != null && mChannel != null) { 309 if (mSelectedGroup != null) { 310 if (DBG) Log.d(TAG, " deleting group " + mSelectedGroup.getGroupName()); 311 mWifiP2pManager.deletePersistentGroup(mChannel, 312 mSelectedGroup.getNetworkId(), 313 new WifiP2pManager.ActionListener() { 314 public void onSuccess() { 315 if (DBG) Log.d(TAG, " delete group success"); 316 } 317 318 public void onFailure(int reason) { 319 if (DBG) Log.d(TAG, " delete group fail " + reason); 320 } 321 }); 322 mSelectedGroup = null; 323 } else { 324 if (DBG) Log.w(TAG, " No selected group to delete!"); 325 } 326 } 327 } else if (which == DialogInterface.BUTTON_NEGATIVE) { 328 if (DBG) { 329 Log.d(TAG, " forgetting selected group " + mSelectedGroup.getGroupName()); 330 } 331 mSelectedGroup = null; 332 } 333 } 334 }; 335 336 super.onActivityCreated(savedInstanceState); 337 } 338 339 @Override onResume()340 public void onResume() { 341 super.onResume(); 342 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); 343 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); 344 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 345 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); 346 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION); 347 mIntentFilter.addAction(WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED); 348 final PreferenceScreen preferenceScreen = getPreferenceScreen(); 349 if (mWifiP2pManager != null && initChannel()) { 350 // Register receiver after make sure channel exist 351 getActivity().registerReceiver(mReceiver, mIntentFilter); 352 mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this); 353 mWifiP2pManager.requestDeviceInfo(mChannel, WifiP2pSettings.this); 354 mIsIgnoreInitConnectionInfoCallback = false; 355 mWifiP2pManager.requestNetworkInfo(mChannel, networkInfo -> { 356 mWifiP2pManager.requestConnectionInfo(mChannel, wifip2pinfo -> { 357 if (!mIsIgnoreInitConnectionInfoCallback) { 358 if (networkInfo.isConnected()) { 359 if (DBG) { 360 Log.d(TAG, "Connected"); 361 } 362 } else if (!mLastGroupFormed) { 363 // Find peers when p2p doesn't connected. 364 startSearch(); 365 } 366 mLastGroupFormed = wifip2pinfo.groupFormed; 367 } 368 }); 369 }); 370 } 371 } 372 373 @Override onPause()374 public void onPause() { 375 super.onPause(); 376 if (mWifiP2pManager != null && mChannel != null) { 377 mWifiP2pManager.stopPeerDiscovery(mChannel, null); 378 if (!mLastGroupFormed) { 379 // Close the channel when p2p doesn't connected. 380 mChannel.close(); 381 mChannel = null; 382 } 383 } 384 getActivity().unregisterReceiver(mReceiver); 385 } 386 387 @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)388 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 389 int textId = mWifiP2pSearching ? R.string.wifi_p2p_menu_searching : 390 R.string.wifi_p2p_menu_search; 391 menu.add(Menu.NONE, MENU_ID_SEARCH, 0, textId) 392 .setEnabled(mWifiP2pEnabled); 393 menu.add(Menu.NONE, MENU_ID_RENAME, 0, R.string.wifi_p2p_menu_rename) 394 .setEnabled(mWifiP2pEnabled); 395 super.onCreateOptionsMenu(menu, inflater); 396 } 397 398 @Override onPrepareOptionsMenu(Menu menu)399 public void onPrepareOptionsMenu(Menu menu) { 400 MenuItem searchMenu = menu.findItem(MENU_ID_SEARCH); 401 MenuItem renameMenu = menu.findItem(MENU_ID_RENAME); 402 if (mWifiP2pEnabled) { 403 searchMenu.setEnabled(true); 404 renameMenu.setEnabled(true); 405 } else { 406 searchMenu.setEnabled(false); 407 renameMenu.setEnabled(false); 408 } 409 410 if (mWifiP2pSearching) { 411 searchMenu.setTitle(R.string.wifi_p2p_menu_searching); 412 } else { 413 searchMenu.setTitle(R.string.wifi_p2p_menu_search); 414 } 415 } 416 417 @Override onOptionsItemSelected(MenuItem item)418 public boolean onOptionsItemSelected(MenuItem item) { 419 switch (item.getItemId()) { 420 case MENU_ID_SEARCH: 421 startSearch(); 422 return true; 423 case MENU_ID_RENAME: 424 showDialog(DIALOG_RENAME); 425 return true; 426 } 427 return super.onOptionsItemSelected(item); 428 } 429 430 @Override onPreferenceTreeClick(Preference preference)431 public boolean onPreferenceTreeClick(Preference preference) { 432 if (preference instanceof WifiP2pPeer) { 433 mSelectedWifiPeer = (WifiP2pPeer) preference; 434 if (mSelectedWifiPeer.device.status == WifiP2pDevice.CONNECTED) { 435 showDialog(DIALOG_DISCONNECT); 436 } else if (mSelectedWifiPeer.device.status == WifiP2pDevice.INVITED) { 437 showDialog(DIALOG_CANCEL_CONNECT); 438 } else { 439 WifiP2pConfig config = new WifiP2pConfig(); 440 config.deviceAddress = mSelectedWifiPeer.device.deviceAddress; 441 442 int forceWps = TelephonyProperties.wps_info().orElse(-1); 443 444 if (forceWps != -1) { 445 config.wps.setup = forceWps; 446 } else { 447 if (mSelectedWifiPeer.device.wpsPbcSupported()) { 448 config.wps.setup = WpsInfo.PBC; 449 } else if (mSelectedWifiPeer.device.wpsKeypadSupported()) { 450 config.wps.setup = WpsInfo.KEYPAD; 451 } else { 452 config.wps.setup = WpsInfo.DISPLAY; 453 } 454 } 455 if (mWifiP2pManager != null && mChannel != null) { 456 mWifiP2pManager.connect(mChannel, config, 457 new WifiP2pManager.ActionListener() { 458 public void onSuccess() { 459 if (DBG) Log.d(TAG, " connect success"); 460 } 461 public void onFailure(int reason) { 462 Log.e(TAG, " connect fail " + reason); 463 Toast.makeText(getActivity(), 464 R.string.wifi_p2p_failed_connect_message, 465 Toast.LENGTH_SHORT).show(); 466 } 467 }); 468 } 469 } 470 } else if (preference instanceof WifiP2pPersistentGroup) { 471 mSelectedGroup = (WifiP2pPersistentGroup) preference; 472 showDialog(DIALOG_DELETE_GROUP); 473 } 474 return super.onPreferenceTreeClick(preference); 475 } 476 477 @Override onCreateDialog(int id)478 public Dialog onCreateDialog(int id) { 479 if (id == DIALOG_DISCONNECT) { 480 String deviceName = TextUtils.isEmpty(mSelectedWifiPeer.device.deviceName) ? 481 mSelectedWifiPeer.device.deviceAddress : 482 mSelectedWifiPeer.device.deviceName; 483 String msg; 484 if (mConnectedDevices > 1) { 485 msg = getActivity().getString(R.string.wifi_p2p_disconnect_multiple_message, 486 deviceName, mConnectedDevices - 1); 487 } else { 488 msg = getActivity().getString(R.string.wifi_p2p_disconnect_message, deviceName); 489 } 490 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 491 .setTitle(R.string.wifi_p2p_disconnect_title) 492 .setMessage(msg) 493 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mDisconnectListener) 494 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null) 495 .create(); 496 return dialog; 497 } else if (id == DIALOG_CANCEL_CONNECT) { 498 int stringId = R.string.wifi_p2p_cancel_connect_message; 499 String deviceName = TextUtils.isEmpty(mSelectedWifiPeer.device.deviceName) ? 500 mSelectedWifiPeer.device.deviceAddress : 501 mSelectedWifiPeer.device.deviceName; 502 503 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 504 .setTitle(R.string.wifi_p2p_cancel_connect_title) 505 .setMessage(getActivity().getString(stringId, deviceName)) 506 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mCancelConnectListener) 507 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null) 508 .create(); 509 return dialog; 510 } else if (id == DIALOG_RENAME) { 511 final LayoutInflater layoutInflater = LayoutInflater.from(getPrefContext()); 512 final View root = layoutInflater.inflate(R.layout.dialog_edittext, null /* root */); 513 mDeviceNameText = root.findViewById(R.id.edittext); 514 mDeviceNameText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(30)}); 515 if (mSavedDeviceName != null) { 516 mDeviceNameText.setText(mSavedDeviceName); 517 mDeviceNameText.setSelection(mSavedDeviceName.length()); 518 } else if (mThisDevice != null && !TextUtils.isEmpty(mThisDevice.deviceName)) { 519 mDeviceNameText.setText(mThisDevice.deviceName); 520 mDeviceNameText.setSelection(0, mThisDevice.deviceName.length()); 521 } 522 mSavedDeviceName = null; 523 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 524 .setTitle(R.string.wifi_p2p_menu_rename) 525 .setView(root) 526 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mRenameListener) 527 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null) 528 .create(); 529 return dialog; 530 } else if (id == DIALOG_DELETE_GROUP) { 531 int stringId = R.string.wifi_p2p_delete_group_message; 532 533 AlertDialog dialog = new AlertDialog.Builder(getActivity()) 534 .setMessage(getActivity().getString(stringId)) 535 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mDeleteGroupListener) 536 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), 537 mDeleteGroupListener).create(); 538 return dialog; 539 } 540 return null; 541 } 542 543 @Override getDialogMetricsCategory(int dialogId)544 public int getDialogMetricsCategory(int dialogId) { 545 switch (dialogId) { 546 case DIALOG_DISCONNECT: 547 return SettingsEnums.DIALOG_WIFI_P2P_DISCONNECT; 548 case DIALOG_CANCEL_CONNECT: 549 return SettingsEnums.DIALOG_WIFI_P2P_CANCEL_CONNECT; 550 case DIALOG_RENAME: 551 return SettingsEnums.DIALOG_WIFI_P2P_RENAME; 552 case DIALOG_DELETE_GROUP: 553 return SettingsEnums.DIALOG_WIFI_P2P_DELETE_GROUP; 554 } 555 return 0; 556 } 557 558 @Override onSaveInstanceState(Bundle outState)559 public void onSaveInstanceState(Bundle outState) { 560 if (mSelectedWifiPeer != null) { 561 outState.putParcelable(SAVE_DIALOG_PEER, mSelectedWifiPeer.device); 562 } 563 if (mDeviceNameText != null) { 564 outState.putString(SAVE_DEVICE_NAME, mDeviceNameText.getText().toString()); 565 } 566 if (mSelectedGroup != null) { 567 outState.putString(SAVE_SELECTED_GROUP, mSelectedGroup.getGroupName()); 568 } 569 } 570 handlePeersChanged()571 private void handlePeersChanged() { 572 mPeerCategoryController.removeAllChildren(); 573 574 mConnectedDevices = 0; 575 if (DBG) Log.d(TAG, "List of available peers"); 576 for (WifiP2pDevice peer: mPeers.getDeviceList()) { 577 if (DBG) Log.d(TAG, "-> " + peer); 578 mPeerCategoryController.addChild(new WifiP2pPeer(getPrefContext(), peer)); 579 if (peer.status == WifiP2pDevice.CONNECTED) mConnectedDevices++; 580 } 581 if (DBG) Log.d(TAG, " mConnectedDevices " + mConnectedDevices); 582 } 583 584 @Override onPersistentGroupInfoAvailable(WifiP2pGroupList groups)585 public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) { 586 mPersistentCategoryController.removeAllChildren(); 587 588 for (WifiP2pGroup group: groups.getGroupList()) { 589 if (DBG) Log.d(TAG, " group " + group); 590 WifiP2pPersistentGroup wppg = new WifiP2pPersistentGroup(getPrefContext(), group); 591 mPersistentCategoryController.addChild(wppg); 592 if (wppg.getGroupName().equals(mSelectedGroupName)) { 593 if (DBG) Log.d(TAG, "Selecting group " + wppg.getGroupName()); 594 mSelectedGroup = wppg; 595 mSelectedGroupName = null; 596 } 597 } 598 if (mSelectedGroupName != null) { 599 // Looks like there's a dialog pending getting user confirmation to delete the 600 // selected group. When user hits OK on that dialog, we won't do anything; but we 601 // shouldn't be in this situation in first place, because these groups are persistent 602 // groups and they shouldn't just get deleted! 603 Log.w(TAG, " Selected group " + mSelectedGroupName + " disappered on next query "); 604 } 605 } 606 607 @Override onPeersAvailable(WifiP2pDeviceList peers)608 public void onPeersAvailable(WifiP2pDeviceList peers) { 609 if (DBG) Log.d(TAG, "Requested peers are available"); 610 mPeers = peers; 611 handlePeersChanged(); 612 } 613 614 @Override onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice)615 public void onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice) { 616 mThisDevice = wifiP2pDevice; 617 if (DBG) Log.d(TAG, "Update device info: " + mThisDevice); 618 mThisDevicePreferenceController.updateDeviceName(mThisDevice); 619 } 620 handleP2pStateChanged()621 private void handleP2pStateChanged() { 622 updateSearchMenu(false); 623 mThisDevicePreferenceController.setEnabled(mWifiP2pEnabled); 624 mPersistentCategoryController.setEnabled(mWifiP2pEnabled); 625 mPeerCategoryController.setEnabled(mWifiP2pEnabled); 626 } 627 updateSearchMenu(boolean searching)628 private void updateSearchMenu(boolean searching) { 629 mWifiP2pSearching = searching; 630 Activity activity = getActivity(); 631 if (activity != null) activity.invalidateOptionsMenu(); 632 } 633 startSearch()634 private void startSearch() { 635 if (mWifiP2pManager != null && mChannel != null && !mWifiP2pSearching) { 636 mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { 637 public void onSuccess() { 638 } 639 public void onFailure(int reason) { 640 if (DBG) Log.d(TAG, " discover fail " + reason); 641 } 642 }); 643 } 644 } 645 initChannel()646 private boolean initChannel() { 647 if (mChannel != null) { 648 return true; 649 } 650 if (mWifiP2pManager != null) { 651 mChannel = mWifiP2pManager.initialize(getActivity().getApplicationContext(), 652 getActivity().getMainLooper(), null); 653 } 654 if (mChannel == null) { 655 Log.e(TAG, "Failed to set up connection with wifi p2p service"); 656 return false; 657 } 658 return true; 659 } 660 } 661