• 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.example.android.wifidirect;
18 
19 import android.app.Fragment;
20 import android.app.ProgressDialog;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.net.Uri;
25 import android.net.wifi.WpsInfo;
26 import android.net.wifi.p2p.WifiP2pConfig;
27 import android.net.wifi.p2p.WifiP2pDevice;
28 import android.net.wifi.p2p.WifiP2pInfo;
29 import android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener;
30 import android.os.AsyncTask;
31 import android.os.Bundle;
32 import android.os.Environment;
33 import android.util.Log;
34 import android.view.LayoutInflater;
35 import android.view.View;
36 import android.view.ViewGroup;
37 import android.widget.TextView;
38 
39 import com.example.android.wifidirect.DeviceListFragment.DeviceActionListener;
40 
41 import java.io.File;
42 import java.io.FileOutputStream;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.io.OutputStream;
46 import java.net.ServerSocket;
47 import java.net.Socket;
48 
49 /**
50  * A fragment that manages a particular peer and allows interaction with device
51  * i.e. setting up network connection and transferring data.
52  */
53 public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
54 
55     protected static final int CHOOSE_FILE_RESULT_CODE = 20;
56     private View mContentView = null;
57     private WifiP2pDevice device;
58     private WifiP2pInfo info;
59     ProgressDialog progressDialog = null;
60 
61     @Override
onActivityCreated(Bundle savedInstanceState)62     public void onActivityCreated(Bundle savedInstanceState) {
63         super.onActivityCreated(savedInstanceState);
64     }
65 
66     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)67     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
68 
69         mContentView = inflater.inflate(R.layout.device_detail, null);
70         mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
71 
72             @Override
73             public void onClick(View v) {
74                 WifiP2pConfig config = new WifiP2pConfig();
75                 config.deviceAddress = device.deviceAddress;
76                 config.wps.setup = WpsInfo.PBC;
77                 if (progressDialog != null && progressDialog.isShowing()) {
78                     progressDialog.dismiss();
79                 }
80                 progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
81                         "Connecting to :" + device.deviceAddress, true, true
82 //                        new DialogInterface.OnCancelListener() {
83 //
84 //                            @Override
85 //                            public void onCancel(DialogInterface dialog) {
86 //                                ((DeviceActionListener) getActivity()).cancelDisconnect();
87 //                            }
88 //                        }
89                         );
90                 ((DeviceActionListener) getActivity()).connect(config);
91 
92             }
93         });
94 
95         mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
96                 new View.OnClickListener() {
97 
98                     @Override
99                     public void onClick(View v) {
100                         ((DeviceActionListener) getActivity()).disconnect();
101                     }
102                 });
103 
104         mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
105                 new View.OnClickListener() {
106 
107                     @Override
108                     public void onClick(View v) {
109                         // Allow user to pick an image from Gallery or other
110                         // registered apps
111                         Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
112                         intent.setType("image/*");
113                         startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
114                     }
115                 });
116 
117         return mContentView;
118     }
119 
120     @Override
onActivityResult(int requestCode, int resultCode, Intent data)121     public void onActivityResult(int requestCode, int resultCode, Intent data) {
122 
123         // User has picked an image. Transfer it to group owner i.e peer using
124         // FileTransferService.
125         Uri uri = data.getData();
126         TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
127         statusText.setText("Sending: " + uri);
128         Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
129         Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
130         serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
131         serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
132         serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
133                 info.groupOwnerAddress.getHostAddress());
134         serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
135         getActivity().startService(serviceIntent);
136     }
137 
138     @Override
onConnectionInfoAvailable(final WifiP2pInfo info)139     public void onConnectionInfoAvailable(final WifiP2pInfo info) {
140         if (progressDialog != null && progressDialog.isShowing()) {
141             progressDialog.dismiss();
142         }
143         this.info = info;
144         this.getView().setVisibility(View.VISIBLE);
145 
146         // The owner IP is now known.
147         TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
148         view.setText(getResources().getString(R.string.group_owner_text)
149                 + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
150                         : getResources().getString(R.string.no)));
151 
152         // InetAddress from WifiP2pInfo struct.
153         view = (TextView) mContentView.findViewById(R.id.device_info);
154         view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
155 
156         // After the group negotiation, we assign the group owner as the file
157         // server. The file server is single threaded, single connection server
158         // socket.
159         if (info.groupFormed && info.isGroupOwner) {
160             new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
161                     .execute();
162         } else if (info.groupFormed) {
163             // The other device acts as the client. In this case, we enable the
164             // get file button.
165             mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
166             ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
167                     .getString(R.string.client_text));
168         }
169 
170         // hide the connect button
171         mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
172     }
173 
174     /**
175      * Updates the UI with device data
176      *
177      * @param device the device to be displayed
178      */
showDetails(WifiP2pDevice device)179     public void showDetails(WifiP2pDevice device) {
180         this.device = device;
181         this.getView().setVisibility(View.VISIBLE);
182         TextView view = (TextView) mContentView.findViewById(R.id.device_address);
183         view.setText(device.deviceAddress);
184         view = (TextView) mContentView.findViewById(R.id.device_info);
185         view.setText(device.toString());
186 
187     }
188 
189     /**
190      * Clears the UI fields after a disconnect or direct mode disable operation.
191      */
resetViews()192     public void resetViews() {
193         mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
194         TextView view = (TextView) mContentView.findViewById(R.id.device_address);
195         view.setText(R.string.empty);
196         view = (TextView) mContentView.findViewById(R.id.device_info);
197         view.setText(R.string.empty);
198         view = (TextView) mContentView.findViewById(R.id.group_owner);
199         view.setText(R.string.empty);
200         view = (TextView) mContentView.findViewById(R.id.status_text);
201         view.setText(R.string.empty);
202         mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
203         this.getView().setVisibility(View.GONE);
204     }
205 
206     /**
207      * A simple server socket that accepts connection and writes some data on
208      * the stream.
209      */
210     public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
211 
212         private Context context;
213         private TextView statusText;
214 
215         /**
216          * @param context
217          * @param statusText
218          */
FileServerAsyncTask(Context context, View statusText)219         public FileServerAsyncTask(Context context, View statusText) {
220             this.context = context;
221             this.statusText = (TextView) statusText;
222         }
223 
224         @Override
doInBackground(Void... params)225         protected String doInBackground(Void... params) {
226             try {
227                 ServerSocket serverSocket = new ServerSocket(8988);
228                 Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
229                 Socket client = serverSocket.accept();
230                 Log.d(WiFiDirectActivity.TAG, "Server: connection done");
231                 final File f = new File(Environment.getExternalStorageDirectory() + "/"
232                         + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
233                         + ".jpg");
234 
235                 File dirs = new File(f.getParent());
236                 if (!dirs.exists())
237                     dirs.mkdirs();
238                 f.createNewFile();
239 
240                 Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
241                 InputStream inputstream = client.getInputStream();
242                 copyFile(inputstream, new FileOutputStream(f));
243                 serverSocket.close();
244                 return f.getAbsolutePath();
245             } catch (IOException e) {
246                 Log.e(WiFiDirectActivity.TAG, e.getMessage());
247                 return null;
248             }
249         }
250 
251         /*
252          * (non-Javadoc)
253          * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
254          */
255         @Override
onPostExecute(String result)256         protected void onPostExecute(String result) {
257             if (result != null) {
258                 statusText.setText("File copied - " + result);
259                 Intent intent = new Intent();
260                 intent.setAction(android.content.Intent.ACTION_VIEW);
261                 intent.setDataAndType(Uri.parse("file://" + result), "image/*");
262                 context.startActivity(intent);
263             }
264 
265         }
266 
267         /*
268          * (non-Javadoc)
269          * @see android.os.AsyncTask#onPreExecute()
270          */
271         @Override
onPreExecute()272         protected void onPreExecute() {
273             statusText.setText("Opening a server socket");
274         }
275 
276     }
277 
copyFile(InputStream inputStream, OutputStream out)278     public static boolean copyFile(InputStream inputStream, OutputStream out) {
279         byte buf[] = new byte[1024];
280         int len;
281         try {
282             while ((len = inputStream.read(buf)) != -1) {
283                 out.write(buf, 0, len);
284 
285             }
286             out.close();
287             inputStream.close();
288         } catch (IOException e) {
289             Log.d(WiFiDirectActivity.TAG, e.toString());
290             return false;
291         }
292         return true;
293     }
294 
295 }
296