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