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