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.AlertDialog;
21 import android.app.Dialog;
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.p2p.WifiP2pConfig;
30 import android.net.wifi.p2p.WifiP2pInfo;
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.WifiP2pManager;
36 import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
37 import android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener;
38 import android.net.wifi.WpsInfo;
39 import android.os.Bundle;
40 import android.os.SystemProperties;
41 import android.preference.Preference;
42 import android.preference.PreferenceCategory;
43 import android.preference.PreferenceGroup;
44 import android.preference.PreferenceScreen;
45 import android.text.InputFilter;
46 import android.text.TextUtils;
47 import android.util.Log;
48 import android.view.Menu;
49 import android.view.MenuInflater;
50 import android.view.MenuItem;
51 import android.widget.EditText;
52 import android.widget.Toast;
53 
54 import com.android.settings.R;
55 import com.android.settings.SettingsPreferenceFragment;
56 
57 /*
58  * Displays Wi-fi p2p settings UI
59  */
60 public class WifiP2pSettings extends SettingsPreferenceFragment
61         implements PersistentGroupInfoListener, PeerListListener {
62 
63     private static final String TAG = "WifiP2pSettings";
64     private static final boolean DBG = false;
65     private static final int MENU_ID_SEARCH = Menu.FIRST;
66     private static final int MENU_ID_RENAME = Menu.FIRST + 1;
67 
68     private final IntentFilter mIntentFilter = new IntentFilter();
69     private WifiP2pManager mWifiP2pManager;
70     private WifiP2pManager.Channel mChannel;
71     private OnClickListener mRenameListener;
72     private OnClickListener mDisconnectListener;
73     private OnClickListener mCancelConnectListener;
74     private OnClickListener mDeleteGroupListener;
75     private WifiP2pPeer mSelectedWifiPeer;
76     private WifiP2pPersistentGroup mSelectedGroup;
77     private String mSelectedGroupName;
78     private EditText mDeviceNameText;
79 
80     private boolean mWifiP2pEnabled;
81     private boolean mWifiP2pSearching;
82     private int mConnectedDevices;
83     private boolean mLastGroupFormed = false;
84 
85     private PreferenceGroup mPeersGroup;
86     private PreferenceGroup mPersistentGroup;
87     private Preference mThisDevicePref;
88 
89     private static final int DIALOG_DISCONNECT  = 1;
90     private static final int DIALOG_CANCEL_CONNECT = 2;
91     private static final int DIALOG_RENAME = 3;
92     private static final int DIALOG_DELETE_GROUP = 4;
93 
94     private static final String SAVE_DIALOG_PEER = "PEER_STATE";
95     private static final String SAVE_DEVICE_NAME = "DEV_NAME";
96     private static final String SAVE_SELECTED_GROUP = "GROUP_NAME";
97 
98     private WifiP2pDevice mThisDevice;
99     private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
100 
101     private String mSavedDeviceName;
102 
103     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
104         @Override
105         public void onReceive(Context context, Intent intent) {
106             String action = intent.getAction();
107 
108             if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
109                 mWifiP2pEnabled = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,
110                     WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED;
111                 handleP2pStateChanged();
112             } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
113                 mPeers = (WifiP2pDeviceList) intent.getParcelableExtra(
114                         WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
115                 handlePeersChanged();
116             } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
117                 if (mWifiP2pManager == null) return;
118                 NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(
119                         WifiP2pManager.EXTRA_NETWORK_INFO);
120                 WifiP2pInfo wifip2pinfo = (WifiP2pInfo) intent.getParcelableExtra(
121                         WifiP2pManager.EXTRA_WIFI_P2P_INFO);
122                 if (networkInfo.isConnected()) {
123                     if (DBG) Log.d(TAG, "Connected");
124                 } else if (mLastGroupFormed != true) {
125                     //start a search when we are disconnected
126                     //but not on group removed broadcast event
127                     startSearch();
128                 }
129                 mLastGroupFormed = wifip2pinfo.groupFormed;
130             } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
131                 mThisDevice = (WifiP2pDevice) intent.getParcelableExtra(
132                         WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
133                 if (DBG) Log.d(TAG, "Update device info: " + mThisDevice);
134                 updateDevicePref();
135             } else if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) {
136                 int discoveryState = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE,
137                     WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
138                 if (DBG) Log.d(TAG, "Discovery state changed: " + discoveryState);
139                 if (discoveryState == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) {
140                     updateSearchMenu(true);
141                 } else {
142                     updateSearchMenu(false);
143                 }
144             } else if (WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION.equals(action)) {
145                 if (mWifiP2pManager != null) {
146                     mWifiP2pManager.requestPersistentGroupInfo(mChannel, WifiP2pSettings.this);
147                 }
148             }
149         }
150     };
151 
WifiP2pSettings()152     public WifiP2pSettings() {
153         if (DBG) Log.d(TAG, "Creating WifiP2pSettings ...");
154     }
155 
156     @Override
onActivityCreated(Bundle savedInstanceState)157     public void onActivityCreated(Bundle savedInstanceState) {
158         addPreferencesFromResource(R.xml.wifi_p2p_settings);
159 
160         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
161         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
162         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
163         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
164         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
165         mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
166 
167         final Activity activity = getActivity();
168         mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
169         if (mWifiP2pManager != null) {
170             mChannel = mWifiP2pManager.initialize(activity, getActivity().getMainLooper(), null);
171             if (mChannel == null) {
172                 //Failure to set up connection
173                 Log.e(TAG, "Failed to set up connection with wifi p2p service");
174                 mWifiP2pManager = null;
175             }
176         } else {
177             Log.e(TAG, "mWifiP2pManager is null !");
178         }
179 
180         if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DIALOG_PEER)) {
181             WifiP2pDevice device = savedInstanceState.getParcelable(SAVE_DIALOG_PEER);
182             mSelectedWifiPeer = new WifiP2pPeer(getActivity(), device);
183         }
184         if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DEVICE_NAME)) {
185             mSavedDeviceName = savedInstanceState.getString(SAVE_DEVICE_NAME);
186         }
187         if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_SELECTED_GROUP)) {
188             mSelectedGroupName = savedInstanceState.getString(SAVE_SELECTED_GROUP);
189         }
190 
191         mRenameListener = new OnClickListener() {
192             @Override
193             public void onClick(DialogInterface dialog, int which) {
194                 if (which == DialogInterface.BUTTON_POSITIVE) {
195                     if (mWifiP2pManager != null) {
196                         mWifiP2pManager.setDeviceName(mChannel,
197                                 mDeviceNameText.getText().toString(),
198                                 new WifiP2pManager.ActionListener() {
199                             public void onSuccess() {
200                                 if (DBG) Log.d(TAG, " device rename success");
201                             }
202                             public void onFailure(int reason) {
203                                 Toast.makeText(getActivity(),
204                                         R.string.wifi_p2p_failed_rename_message,
205                                         Toast.LENGTH_LONG).show();
206                             }
207                         });
208                     }
209                 }
210             }
211         };
212 
213         //disconnect dialog listener
214         mDisconnectListener = new OnClickListener() {
215             @Override
216             public void onClick(DialogInterface dialog, int which) {
217                 if (which == DialogInterface.BUTTON_POSITIVE) {
218                     if (mWifiP2pManager != null) {
219                         mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() {
220                             public void onSuccess() {
221                                 if (DBG) Log.d(TAG, " remove group success");
222                             }
223                             public void onFailure(int reason) {
224                                 if (DBG) Log.d(TAG, " remove group fail " + reason);
225                             }
226                         });
227                     }
228                 }
229             }
230         };
231 
232         //cancel connect dialog listener
233         mCancelConnectListener = new OnClickListener() {
234             @Override
235             public void onClick(DialogInterface dialog, int which) {
236                 if (which == DialogInterface.BUTTON_POSITIVE) {
237                     if (mWifiP2pManager != null) {
238                         mWifiP2pManager.cancelConnect(mChannel,
239                                 new WifiP2pManager.ActionListener() {
240                             public void onSuccess() {
241                                 if (DBG) Log.d(TAG, " cancel connect success");
242                             }
243                             public void onFailure(int reason) {
244                                 if (DBG) Log.d(TAG, " cancel connect fail " + reason);
245                             }
246                         });
247                     }
248                 }
249             }
250         };
251 
252         //delete persistent group dialog listener
253         mDeleteGroupListener = new OnClickListener() {
254             @Override
255             public void onClick(DialogInterface dialog, int which) {
256                 if (which == DialogInterface.BUTTON_POSITIVE) {
257                     if (mWifiP2pManager != null) {
258                         if (mSelectedGroup != null) {
259                             if (DBG) Log.d(TAG, " deleting group " + mSelectedGroup.getGroupName());
260                             mWifiP2pManager.deletePersistentGroup(mChannel,
261                                     mSelectedGroup.getNetworkId(),
262                                     new WifiP2pManager.ActionListener() {
263                                 public void onSuccess() {
264                                     if (DBG) Log.d(TAG, " delete group success");
265                                 }
266                                 public void onFailure(int reason) {
267                                     if (DBG) Log.d(TAG, " delete group fail " + reason);
268                                 }
269                             });
270                             mSelectedGroup = null;
271                         } else {
272                             if (DBG) Log.w(TAG, " No selected group to delete!" );
273                         }
274                     }
275                 } else if (which == DialogInterface.BUTTON_NEGATIVE) {
276                     if (DBG) {
277                         Log.d(TAG, " forgetting selected group " + mSelectedGroup.getGroupName());
278                     }
279                     mSelectedGroup = null;
280                 }
281             }
282         };
283 
284         setHasOptionsMenu(true);
285 
286         final PreferenceScreen preferenceScreen = getPreferenceScreen();
287         preferenceScreen.removeAll();
288         preferenceScreen.setOrderingAsAdded(true);
289 
290         mThisDevicePref = new Preference(getActivity());
291         mThisDevicePref.setPersistent(false);
292         mThisDevicePref.setSelectable(false);
293         preferenceScreen.addPreference(mThisDevicePref);
294 
295         mPeersGroup = new PreferenceCategory(getActivity());
296         mPeersGroup.setTitle(R.string.wifi_p2p_peer_devices);
297         preferenceScreen.addPreference(mPeersGroup);
298 
299         mPersistentGroup = new PreferenceCategory(getActivity());
300         mPersistentGroup.setTitle(R.string.wifi_p2p_remembered_groups);
301         preferenceScreen.addPreference(mPersistentGroup);
302 
303         super.onActivityCreated(savedInstanceState);
304     }
305 
306     @Override
onResume()307     public void onResume() {
308         super.onResume();
309         getActivity().registerReceiver(mReceiver, mIntentFilter);
310         if (mWifiP2pManager != null) {
311             mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this);
312         }
313     }
314 
315     @Override
onPause()316     public void onPause() {
317         super.onPause();
318         if (mWifiP2pManager != null) {
319             mWifiP2pManager.stopPeerDiscovery(mChannel, null);
320         }
321         getActivity().unregisterReceiver(mReceiver);
322     }
323 
324     @Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)325     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
326         int textId = mWifiP2pSearching ? R.string.wifi_p2p_menu_searching :
327                 R.string.wifi_p2p_menu_search;
328         menu.add(Menu.NONE, MENU_ID_SEARCH, 0, textId)
329             .setEnabled(mWifiP2pEnabled)
330             .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
331         menu.add(Menu.NONE, MENU_ID_RENAME, 0, R.string.wifi_p2p_menu_rename)
332             .setEnabled(mWifiP2pEnabled)
333             .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
334         super.onCreateOptionsMenu(menu, inflater);
335     }
336 
337     @Override
onPrepareOptionsMenu(Menu menu)338     public void onPrepareOptionsMenu(Menu menu) {
339         MenuItem searchMenu = menu.findItem(MENU_ID_SEARCH);
340         MenuItem renameMenu = menu.findItem(MENU_ID_RENAME);
341         if (mWifiP2pEnabled) {
342             searchMenu.setEnabled(true);
343             renameMenu.setEnabled(true);
344         } else {
345             searchMenu.setEnabled(false);
346             renameMenu.setEnabled(false);
347         }
348 
349         if (mWifiP2pSearching) {
350             searchMenu.setTitle(R.string.wifi_p2p_menu_searching);
351         } else {
352             searchMenu.setTitle(R.string.wifi_p2p_menu_search);
353         }
354     }
355 
356     @Override
onOptionsItemSelected(MenuItem item)357     public boolean onOptionsItemSelected(MenuItem item) {
358         switch (item.getItemId()) {
359             case MENU_ID_SEARCH:
360                 startSearch();
361                 return true;
362             case MENU_ID_RENAME:
363                 showDialog(DIALOG_RENAME);
364                 return true;
365         }
366         return super.onOptionsItemSelected(item);
367     }
368 
369     @Override
onPreferenceTreeClick(PreferenceScreen screen, Preference preference)370     public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
371         if (preference instanceof WifiP2pPeer) {
372             mSelectedWifiPeer = (WifiP2pPeer) preference;
373             if (mSelectedWifiPeer.device.status == WifiP2pDevice.CONNECTED) {
374                 showDialog(DIALOG_DISCONNECT);
375             } else if (mSelectedWifiPeer.device.status == WifiP2pDevice.INVITED) {
376                 showDialog(DIALOG_CANCEL_CONNECT);
377             } else {
378                 WifiP2pConfig config = new WifiP2pConfig();
379                 config.deviceAddress = mSelectedWifiPeer.device.deviceAddress;
380 
381                 int forceWps = SystemProperties.getInt("wifidirect.wps", -1);
382 
383                 if (forceWps != -1) {
384                     config.wps.setup = forceWps;
385                 } else {
386                     if (mSelectedWifiPeer.device.wpsPbcSupported()) {
387                         config.wps.setup = WpsInfo.PBC;
388                     } else if (mSelectedWifiPeer.device.wpsKeypadSupported()) {
389                         config.wps.setup = WpsInfo.KEYPAD;
390                     } else {
391                         config.wps.setup = WpsInfo.DISPLAY;
392                     }
393                 }
394 
395                 mWifiP2pManager.connect(mChannel, config,
396                         new WifiP2pManager.ActionListener() {
397                             public void onSuccess() {
398                                 if (DBG) Log.d(TAG, " connect success");
399                             }
400                             public void onFailure(int reason) {
401                                 Log.e(TAG, " connect fail " + reason);
402                                 Toast.makeText(getActivity(),
403                                         R.string.wifi_p2p_failed_connect_message,
404                                         Toast.LENGTH_SHORT).show();
405                             }
406                     });
407             }
408         } else if (preference instanceof WifiP2pPersistentGroup) {
409             mSelectedGroup = (WifiP2pPersistentGroup) preference;
410             showDialog(DIALOG_DELETE_GROUP);
411         }
412         return super.onPreferenceTreeClick(screen, preference);
413     }
414 
415     @Override
onCreateDialog(int id)416     public Dialog onCreateDialog(int id) {
417         if (id == DIALOG_DISCONNECT) {
418             String deviceName = TextUtils.isEmpty(mSelectedWifiPeer.device.deviceName) ?
419                     mSelectedWifiPeer.device.deviceAddress :
420                     mSelectedWifiPeer.device.deviceName;
421             String msg;
422             if (mConnectedDevices > 1) {
423                 msg = getActivity().getString(R.string.wifi_p2p_disconnect_multiple_message,
424                         deviceName, mConnectedDevices - 1);
425             } else {
426                 msg = getActivity().getString(R.string.wifi_p2p_disconnect_message, deviceName);
427             }
428             AlertDialog dialog = new AlertDialog.Builder(getActivity())
429                 .setTitle(R.string.wifi_p2p_disconnect_title)
430                 .setMessage(msg)
431                 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mDisconnectListener)
432                 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null)
433                 .create();
434             return dialog;
435         } else if (id == DIALOG_CANCEL_CONNECT) {
436             int stringId = R.string.wifi_p2p_cancel_connect_message;
437             String deviceName = TextUtils.isEmpty(mSelectedWifiPeer.device.deviceName) ?
438                     mSelectedWifiPeer.device.deviceAddress :
439                     mSelectedWifiPeer.device.deviceName;
440 
441             AlertDialog dialog = new AlertDialog.Builder(getActivity())
442                 .setTitle(R.string.wifi_p2p_cancel_connect_title)
443                 .setMessage(getActivity().getString(stringId, deviceName))
444                 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mCancelConnectListener)
445                 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null)
446                 .create();
447             return dialog;
448         } else if (id == DIALOG_RENAME) {
449             mDeviceNameText = new EditText(getActivity());
450             mDeviceNameText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(30)});
451             if (mSavedDeviceName != null) {
452                 mDeviceNameText.setText(mSavedDeviceName);
453                 mDeviceNameText.setSelection(mSavedDeviceName.length());
454             } else if (mThisDevice != null && !TextUtils.isEmpty(mThisDevice.deviceName)) {
455                 mDeviceNameText.setText(mThisDevice.deviceName);
456                 mDeviceNameText.setSelection(0, mThisDevice.deviceName.length());
457             }
458             mSavedDeviceName = null;
459             AlertDialog dialog = new AlertDialog.Builder(getActivity())
460                 .setTitle(R.string.wifi_p2p_menu_rename)
461                 .setView(mDeviceNameText)
462                 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mRenameListener)
463                 .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null)
464                 .create();
465             return dialog;
466         } else if (id == DIALOG_DELETE_GROUP) {
467             int stringId = R.string.wifi_p2p_delete_group_message;
468 
469             AlertDialog dialog = new AlertDialog.Builder(getActivity())
470                 .setMessage(getActivity().getString(stringId))
471                 .setPositiveButton(getActivity().getString(R.string.dlg_ok), mDeleteGroupListener)
472                 .setNegativeButton(getActivity().getString(R.string.dlg_cancel),
473                         mDeleteGroupListener).create();
474             return dialog;
475         }
476         return null;
477     }
478 
479     @Override
onSaveInstanceState(Bundle outState)480     public void onSaveInstanceState(Bundle outState) {
481         if (mSelectedWifiPeer != null) {
482             outState.putParcelable(SAVE_DIALOG_PEER, mSelectedWifiPeer.device);
483         }
484         if (mDeviceNameText != null) {
485             outState.putString(SAVE_DEVICE_NAME, mDeviceNameText.getText().toString());
486         }
487         if (mSelectedGroup != null) {
488             outState.putString(SAVE_SELECTED_GROUP, mSelectedGroup.getGroupName());
489         }
490     }
491 
handlePeersChanged()492     private void handlePeersChanged() {
493         mPeersGroup.removeAll();
494 
495         mConnectedDevices = 0;
496         if (DBG) Log.d(TAG, "List of available peers");
497         for (WifiP2pDevice peer: mPeers.getDeviceList()) {
498             if (DBG) Log.d(TAG, "-> " + peer);
499             mPeersGroup.addPreference(new WifiP2pPeer(getActivity(), peer));
500             if (peer.status == WifiP2pDevice.CONNECTED) mConnectedDevices++;
501         }
502         if (DBG) Log.d(TAG, " mConnectedDevices " + mConnectedDevices);
503     }
504 
505     @Override
onPersistentGroupInfoAvailable(WifiP2pGroupList groups)506     public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) {
507         mPersistentGroup.removeAll();
508 
509         for (WifiP2pGroup group: groups.getGroupList()) {
510             if (DBG) Log.d(TAG, " group " + group);
511             WifiP2pPersistentGroup wppg = new WifiP2pPersistentGroup(getActivity(), group);
512             mPersistentGroup.addPreference(wppg);
513             if (wppg.getGroupName().equals(mSelectedGroupName)) {
514                 if (DBG) Log.d(TAG, "Selecting group " + wppg.getGroupName());
515                 mSelectedGroup = wppg;
516                 mSelectedGroupName = null;
517             }
518         }
519         if (mSelectedGroupName != null) {
520             // Looks like there's a dialog pending getting user confirmation to delete the
521             // selected group. When user hits OK on that dialog, we won't do anything; but we
522             // shouldn't be in this situation in first place, because these groups are persistent
523             // groups and they shouldn't just get deleted!
524             Log.w(TAG, " Selected group " + mSelectedGroupName + " disappered on next query ");
525         }
526     }
527 
528     @Override
onPeersAvailable(WifiP2pDeviceList peers)529     public void onPeersAvailable(WifiP2pDeviceList peers) {
530         if (DBG) Log.d(TAG, "Requested peers are available");
531         mPeers = peers;
532         handlePeersChanged();
533     }
534 
handleP2pStateChanged()535     private void handleP2pStateChanged() {
536         updateSearchMenu(false);
537         mThisDevicePref.setEnabled(mWifiP2pEnabled);
538         mPeersGroup.setEnabled(mWifiP2pEnabled);
539         mPersistentGroup.setEnabled(mWifiP2pEnabled);
540     }
541 
updateSearchMenu(boolean searching)542     private void updateSearchMenu(boolean searching) {
543        mWifiP2pSearching = searching;
544        Activity activity = getActivity();
545        if (activity != null) activity.invalidateOptionsMenu();
546     }
547 
startSearch()548     private void startSearch() {
549         if (mWifiP2pManager != null && !mWifiP2pSearching) {
550             mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
551                 public void onSuccess() {
552                 }
553                 public void onFailure(int reason) {
554                     if (DBG) Log.d(TAG, " discover fail " + reason);
555                 }
556             });
557         }
558     }
559 
updateDevicePref()560     private void updateDevicePref() {
561         if (mThisDevice != null) {
562             if (TextUtils.isEmpty(mThisDevice.deviceName)) {
563                 mThisDevicePref.setTitle(mThisDevice.deviceAddress);
564             } else {
565                 mThisDevicePref.setTitle(mThisDevice.deviceName);
566             }
567         }
568     }
569 }
570