Home | History | Annotate | Download | only in wifidirect
      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.example.android.wifidirect;
     18 
     19 import android.app.Activity;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.net.wifi.p2p.WifiP2pConfig;
     25 import android.net.wifi.p2p.WifiP2pDevice;
     26 import android.net.wifi.p2p.WifiP2pManager;
     27 import android.net.wifi.p2p.WifiP2pManager.ActionListener;
     28 import android.net.wifi.p2p.WifiP2pManager.Channel;
     29 import android.net.wifi.p2p.WifiP2pManager.ChannelListener;
     30 import android.os.Bundle;
     31 import android.provider.Settings;
     32 import android.util.Log;
     33 import android.view.Menu;
     34 import android.view.MenuInflater;
     35 import android.view.MenuItem;
     36 import android.view.View;
     37 import android.widget.Toast;
     38 
     39 import com.example.android.wifidirect.DeviceListFragment.DeviceActionListener;
     40 
     41 /**
     42  * An activity that uses WiFi Direct APIs to discover and connect with available
     43  * devices. WiFi Direct APIs are asynchronous and rely on callback mechanism
     44  * using interfaces to notify the application of operation success or failure.
     45  * The application should also register a BroadcastReceiver for notification of
     46  * WiFi state related events.
     47  */
     48 public class WiFiDirectActivity extends Activity implements ChannelListener, DeviceActionListener {
     49 
     50     public static final String TAG = "wifidirectdemo";
     51     private WifiP2pManager manager;
     52     private boolean isWifiP2pEnabled = false;
     53     private boolean retryChannel = false;
     54 
     55     private final IntentFilter intentFilter = new IntentFilter();
     56     private Channel channel;
     57     private BroadcastReceiver receiver = null;
     58 
     59     /**
     60      * @param isWifiP2pEnabled the isWifiP2pEnabled to set
     61      */
     62     public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
     63         this.isWifiP2pEnabled = isWifiP2pEnabled;
     64     }
     65 
     66     @Override
     67     public void onCreate(Bundle savedInstanceState) {
     68         super.onCreate(savedInstanceState);
     69         setContentView(R.layout.main);
     70 
     71         // add necessary intent values to be matched.
     72 
     73         intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
     74         intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
     75         intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
     76         intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
     77 
     78         manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
     79         channel = manager.initialize(this, getMainLooper(), null);
     80     }
     81 
     82     /** register the BroadcastReceiver with the intent values to be matched */
     83     @Override
     84     public void onResume() {
     85         super.onResume();
     86         receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
     87         registerReceiver(receiver, intentFilter);
     88     }
     89 
     90     @Override
     91     public void onPause() {
     92         super.onPause();
     93         unregisterReceiver(receiver);
     94     }
     95 
     96     /**
     97      * Remove all peers and clear all fields. This is called on
     98      * BroadcastReceiver receiving a state change event.
     99      */
    100     public void resetData() {
    101         DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
    102                 .findFragmentById(R.id.frag_list);
    103         DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
    104                 .findFragmentById(R.id.frag_detail);
    105         if (fragmentList != null) {
    106             fragmentList.clearPeers();
    107         }
    108         if (fragmentDetails != null) {
    109             fragmentDetails.resetViews();
    110         }
    111     }
    112 
    113     @Override
    114     public boolean onCreateOptionsMenu(Menu menu) {
    115         MenuInflater inflater = getMenuInflater();
    116         inflater.inflate(R.menu.action_items, menu);
    117         return true;
    118     }
    119 
    120     /*
    121      * (non-Javadoc)
    122      * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
    123      */
    124     @Override
    125     public boolean onOptionsItemSelected(MenuItem item) {
    126         switch (item.getItemId()) {
    127             case R.id.atn_direct_enable:
    128                 if (manager != null && channel != null) {
    129 
    130                     // Since this is the system wireless settings activity, it's
    131                     // not going to send us a result. We will be notified by
    132                     // WiFiDeviceBroadcastReceiver instead.
    133 
    134                     startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
    135                 } else {
    136                     Log.e(TAG, "channel or manager is null");
    137                 }
    138                 return true;
    139 
    140             case R.id.atn_direct_discover:
    141                 if (!isWifiP2pEnabled) {
    142                     Toast.makeText(WiFiDirectActivity.this, R.string.p2p_off_warning,
    143                             Toast.LENGTH_SHORT).show();
    144                     return true;
    145                 }
    146                 final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
    147                         .findFragmentById(R.id.frag_list);
    148                 fragment.onInitiateDiscovery();
    149                 manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
    150 
    151                     @Override
    152                     public void onSuccess() {
    153                         Toast.makeText(WiFiDirectActivity.this, "Discovery Initiated",
    154                                 Toast.LENGTH_SHORT).show();
    155                     }
    156 
    157                     @Override
    158                     public void onFailure(int reasonCode) {
    159                         Toast.makeText(WiFiDirectActivity.this, "Discovery Failed : " + reasonCode,
    160                                 Toast.LENGTH_SHORT).show();
    161                     }
    162                 });
    163                 return true;
    164             default:
    165                 return super.onOptionsItemSelected(item);
    166         }
    167     }
    168 
    169     @Override
    170     public void showDetails(WifiP2pDevice device) {
    171         DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
    172                 .findFragmentById(R.id.frag_detail);
    173         fragment.showDetails(device);
    174 
    175     }
    176 
    177     @Override
    178     public void connect(WifiP2pConfig config) {
    179         manager.connect(channel, config, new ActionListener() {
    180 
    181             @Override
    182             public void onSuccess() {
    183                 // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
    184             }
    185 
    186             @Override
    187             public void onFailure(int reason) {
    188                 Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
    189                         Toast.LENGTH_SHORT).show();
    190             }
    191         });
    192     }
    193 
    194     @Override
    195     public void disconnect() {
    196         final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
    197                 .findFragmentById(R.id.frag_detail);
    198         fragment.resetViews();
    199         manager.removeGroup(channel, new ActionListener() {
    200 
    201             @Override
    202             public void onFailure(int reasonCode) {
    203                 Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
    204 
    205             }
    206 
    207             @Override
    208             public void onSuccess() {
    209                 fragment.getView().setVisibility(View.GONE);
    210             }
    211 
    212         });
    213     }
    214 
    215     @Override
    216     public void onChannelDisconnected() {
    217         // we will try once more
    218         if (manager != null && !retryChannel) {
    219             Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
    220             resetData();
    221             retryChannel = true;
    222             manager.initialize(this, getMainLooper(), this);
    223         } else {
    224             Toast.makeText(this,
    225                     "Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
    226                     Toast.LENGTH_LONG).show();
    227         }
    228     }
    229 
    230     @Override
    231     public void cancelDisconnect() {
    232 
    233         /*
    234          * A cancel abort request by user. Disconnect i.e. removeGroup if
    235          * already connected. Else, request WifiP2pManager to abort the ongoing
    236          * request
    237          */
    238         if (manager != null) {
    239             final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
    240                     .findFragmentById(R.id.frag_list);
    241             if (fragment.getDevice() == null
    242                     || fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
    243                 disconnect();
    244             } else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
    245                     || fragment.getDevice().status == WifiP2pDevice.INVITED) {
    246 
    247                 manager.cancelConnect(channel, new ActionListener() {
    248 
    249                     @Override
    250                     public void onSuccess() {
    251                         Toast.makeText(WiFiDirectActivity.this, "Aborting connection",
    252                                 Toast.LENGTH_SHORT).show();
    253                     }
    254 
    255                     @Override
    256                     public void onFailure(int reasonCode) {
    257                         Toast.makeText(WiFiDirectActivity.this,
    258                                 "Connect abort request failed. Reason Code: " + reasonCode,
    259                                 Toast.LENGTH_SHORT).show();
    260                     }
    261                 });
    262             }
    263         }
    264 
    265     }
    266 }
    267