• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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