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