replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / android / examples / simplebase / src / main / java / org / iotivity / base / examples / BluetoothFragment.java
1 /*
2  * ******************************************************************
3  *
4  * Copyright 2016 Samsung Electronics All Rights Reserved.
5  *
6  * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22
23 package org.iotivity.base.examples;
24
25 import android.app.Activity;
26 import android.app.Fragment;
27 import android.bluetooth.BluetoothAdapter;
28 import android.bluetooth.BluetoothDevice;
29 import android.bluetooth.BluetoothGatt;
30 import android.bluetooth.BluetoothManager;
31 import android.bluetooth.le.BluetoothLeScanner;
32 import android.bluetooth.le.ScanCallback;
33 import android.bluetooth.le.ScanFilter;
34 import android.bluetooth.le.ScanResult;
35 import android.bluetooth.le.ScanSettings;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.pm.PackageManager;
39 import android.os.Build;
40 import android.os.Bundle;
41 import android.os.Handler;
42 import android.os.ParcelUuid;
43 import android.util.Log;
44 import android.view.LayoutInflater;
45 import android.view.View;
46 import android.view.ViewGroup;
47 import android.widget.AdapterView;
48 import android.widget.ArrayAdapter;
49 import android.widget.Button;
50 import android.widget.ListView;
51
52 import org.iotivity.base.ModeType;
53 import org.iotivity.base.OcConnectivityType;
54 import org.iotivity.base.OcException;
55 import org.iotivity.base.OcPlatform;
56 import org.iotivity.base.OcResource;
57 import org.iotivity.base.PlatformConfig;
58 import org.iotivity.base.QualityOfService;
59 import org.iotivity.base.ServiceType;
60 import org.iotivity.ca.CaBtPairingInterface;
61 import org.iotivity.ca.CaInterface;
62
63 import java.util.ArrayList;
64 import java.util.EnumSet;
65 import java.util.List;
66
67 /**
68  * This class is for testing of Bluetooth util.
69  */
70 public class BluetoothFragment extends Fragment implements
71         CaInterface.OnBtDeviceFoundListener,
72         CaInterface.OnConnectionManagerStateListener {
73
74     private static final String      TAG                  = "OCF_SIMPLE_BLUETOOTH";
75     private static final String      CA_GATT_SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
76
77     private Activity                   mActivity;
78     private Context                    mContext;
79     private BluetoothAdapter           mBluetoothAdapter;
80     private static final int           REQUEST_ENABLE_BT  = 1;
81     private static final long          SCAN_PERIOD        = 10000;
82     private BluetoothLeScanner         mLEScanner;
83     private ScanSettings               mScanSettings;
84     private List<ScanFilter>           mScanFilters;
85     private BluetoothGatt              mGatt;
86     private ArrayList<String>          mItems;
87     private ArrayList<BluetoothDevice> mBluetoothDevices;
88     private ArrayAdapter<String>       mAdapters;
89
90     private boolean                    mIsScanning;
91     private boolean                    mIsBTSelected;
92
93     private Button                     mBtButton;
94     private Button                     mLeButton;
95
96     @Override
97     public View onCreateView(LayoutInflater inflater, ViewGroup container,
98                              Bundle savedInstanceState) {
99         View rootView = inflater.inflate(R.layout.fragment_bluetooth, container, false);
100         mBtButton = (Button) rootView.findViewById(R.id.btn_bt);
101         mBtButton.setOnClickListener(scanButtonListener(true));
102
103         mLeButton = (Button) rootView.findViewById(R.id.btn_le);
104         mLeButton.setOnClickListener(scanButtonListener(false));
105
106         ListView listView = (ListView) rootView.findViewById(R.id.list_view);
107         mItems = new ArrayList<String>();
108         mAdapters = new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1, mItems);
109         listView.setAdapter(mAdapters);
110         listView.setOnItemClickListener(itemClickListener);
111         listView.setOnItemLongClickListener(itemLongClickListener);
112
113         return rootView;
114     }
115
116     @Override
117     public void onCreate(Bundle savedInstanceState) {
118         super.onCreate(savedInstanceState);
119         mActivity = getActivity();
120         mContext = mActivity.getBaseContext();
121
122         mBluetoothDevices = new ArrayList<BluetoothDevice>();
123
124         if (!mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
125             Common.showToast(mContext, "BLE Not Supported");
126         }
127         final BluetoothManager bluetoothManager = (BluetoothManager) mActivity
128                                                   .getSystemService(Context.BLUETOOTH_SERVICE);
129         mBluetoothAdapter = bluetoothManager.getAdapter();
130
131         PlatformConfig cfg = new PlatformConfig(mActivity, mContext,
132                                                 ServiceType.IN_PROC,
133                                                 ModeType.CLIENT,
134                                                 Common.IP_ADDRESS,
135                                                 Common.IP_PORT,
136                                                 QualityOfService.LOW);
137
138         OcPlatform.Configure(cfg);
139         CaInterface.startBtPairingService(mContext, this);
140         CaInterface.startManagerService(mContext, this);
141     }
142
143     @Override
144     public void onResume() {
145         super.onResume();
146         if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
147             Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
148             startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
149         } else {
150             if (Build.VERSION.SDK_INT >= 21) {
151                 mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
152                 if (mScanSettings == null) {
153                     mScanSettings = new ScanSettings.Builder()
154                                                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
155                                                .build();
156                 }
157
158                 if (mScanFilters == null) {
159                     mScanFilters = new ArrayList<ScanFilter>();
160                     ScanFilter scanFilter = new ScanFilter.Builder()
161                             .setServiceUuid(ParcelUuid.fromString(CA_GATT_SERVICE_UUID)).build();
162                     mScanFilters.add(scanFilter);
163                 }
164             }
165         }
166     }
167
168     @Override
169     public void onPause() {
170         super.onPause();
171         if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
172             scanLeDevice(false);
173         }
174     }
175
176     @Override
177     public void onDestroy() {
178         super.onDestroy();
179         CaInterface.stopBtPairingService();
180         CaInterface.stopManagerService();
181         if (mGatt != null) {
182             mGatt.close();
183             mGatt = null;
184         }
185     }
186
187     @Override
188     public void onActivityResult(int requestCode, int resultCode, Intent data) {
189         if (requestCode == REQUEST_ENABLE_BT) {
190             if (resultCode == Activity.RESULT_CANCELED) {
191                 mActivity.finish();
192                 return;
193             }
194         }
195         super.onActivityResult(requestCode, resultCode, data);
196     }
197
198     View.OnClickListener scanButtonListener(final boolean isBT) {
199         return new View.OnClickListener() {
200             @Override
201             public void onClick(View view) {
202                 if (!mIsScanning) {
203                     mItems.clear();
204                     mBluetoothDevices.clear();
205                     mAdapters.notifyDataSetChanged();
206                     mIsBTSelected = isBT;
207                 }
208
209                 if (isBT) {
210                     if (mIsScanning) {
211                         // BT Stop
212                         try {
213                             CaInterface.stopScan();
214                         } catch (OcException e) {
215                             e.printStackTrace();
216                         }
217                         mBtButton.setText(R.string.bt_scan);
218                         mLeButton.setVisibility(View.VISIBLE);
219                     } else {
220                         // BT Scan
221                         try {
222                             CaInterface.startScan();
223                         } catch (OcException e) {
224                             e.printStackTrace();
225                         }
226                         mBtButton.setText(R.string.stop_scan);
227                         mLeButton.setVisibility(View.GONE);
228                     }
229                 } else {
230                     if (mIsScanning) {
231                         // LE Stop
232                         mLeButton.setText(R.string.le_scan);
233                         mBtButton.setVisibility(View.VISIBLE);
234                     } else {
235                         // LE Scan
236                         mLeButton.setText(R.string.stop_scan);
237                         mBtButton.setVisibility(View.GONE);
238                     }
239                     scanLeDevice(!mIsScanning);
240                 }
241                 mIsScanning = !mIsScanning;
242             }
243         };
244     }
245
246     @Override
247     public synchronized void onBtDeviceFound(BluetoothDevice device) throws OcException {
248         Log.i(TAG, "onBtDeviceFound address : " + device.getAddress());
249
250         addItemToList(device);
251     }
252
253     private AdapterView.OnItemClickListener itemClickListener = new AdapterView
254                                                                 .OnItemClickListener() {
255         public void onItemClick(AdapterView<?> adapterView, View clickedView, int pos, long id) {
256             StringBuilder sb = new StringBuilder();
257
258             if (mIsBTSelected) {
259                 sb.append("Pairing with : ");
260                 try {
261                     CaInterface.createBond(mBluetoothDevices.get(pos));
262                 } catch (OcException e) {
263                     e.printStackTrace();
264                 }
265             } else {
266                 sb.append("Set Connect with : ");
267                 try {
268                     final String address = mBluetoothDevices.get(pos).getAddress();
269                     Common.setLeAddress(address);
270                     CaInterface.setAutoConnectionDevice(address);
271                     OcPlatform.OnResourceFoundListener resourceFoundListener =
272                             new OcPlatform.OnResourceFoundListener() {
273                         @Override
274                         public void onResourceFound(OcResource ocResource) {
275                             Log.i(TAG, "onResourceFound : " + ocResource.getUri());
276                         }
277
278                         @Override
279                         public void onFindResourceFailed(Throwable throwable, String uri) {
280                            Log.i(TAG, "findResource request has failed");
281                            Log.e(TAG, throwable.toString());
282                         }
283                     };
284                     OcPlatform.findResource("", address + OcPlatform.WELL_KNOWN_QUERY,
285                                             EnumSet.of(OcConnectivityType.CT_ADAPTER_GATT_BTLE),
286                                             resourceFoundListener, QualityOfService.LOW);
287                 } catch (OcException e) {
288                     e.printStackTrace();
289                 }
290             }
291             Common.showToast(mContext, sb.append(mItems.get(pos)).toString());
292         }
293     };
294
295     private AdapterView.OnItemLongClickListener itemLongClickListener = new AdapterView
296                                                                         .OnItemLongClickListener() {
297         @Override
298         public boolean onItemLongClick(AdapterView<?> adapterView, View view, int pos, long id) {
299             StringBuilder sb = new StringBuilder();
300
301             if (!mIsBTSelected) {
302                 sb.append("Unset Connect with : ");
303                 try {
304                     CaInterface.unsetAutoConnectionDevice(mBluetoothDevices.get(pos).getAddress());
305                 } catch (OcException e) {
306                     e.printStackTrace();
307                 }
308             }
309             Common.showToast(mContext, sb.append(mItems.get(pos)).toString());
310
311             return true;
312         }
313     };
314
315     private void scanLeDevice(final boolean enable) {
316         if (enable) {
317             new Handler().postDelayed(new Runnable() {
318                 @Override
319                 public void run() {
320                     mLEScanner.stopScan(mScanCallback);
321                 }
322             }, SCAN_PERIOD);
323
324             mLEScanner.startScan(mScanFilters, mScanSettings, mScanCallback);
325         } else {
326             mLEScanner.stopScan(mScanCallback);
327         }
328     }
329
330     private ScanCallback mScanCallback = new ScanCallback() {
331         @Override
332         public void onScanResult(int callbackType, ScanResult result) {
333             Log.i(TAG, "onScanResult : " + result.toString());
334
335             addItemToList(result.getDevice());
336         }
337
338         @Override
339         public void onScanFailed(int errorCode) {
340             Log.e(TAG, "Scan Failed, Error Code : " + errorCode);
341         }
342     };
343
344     private void addItemToList(BluetoothDevice btDevice) {
345         StringBuilder sb = new StringBuilder(btDevice.toString());
346         sb.append(" (");
347         if (btDevice.getName() != null) {
348             sb.append(btDevice.getName().toString());
349         } else {
350             sb.append("NULL");
351         }
352         sb.append(")");
353
354         if (mItems.contains(sb.toString())) {
355             // Duplicate
356         } else {
357             // add item
358             mItems.add(sb.toString());
359             mBluetoothDevices.add(btDevice);
360             mAdapters.notifyDataSetChanged();
361         }
362     }
363
364     @Override
365     public void onAdapterStateChanged(OcConnectivityType type, boolean enabled) {
366         final String msg = getString(R.string.action_onadapterstatechanged) + enabled;
367         Log.i(TAG, msg);
368         mActivity.runOnUiThread(new Runnable() {
369             @Override
370             public void run() {
371                 Common.showToast(mContext, msg);
372             }
373         });
374     }
375
376     @Override
377     public void onConnectionStateChanged(OcConnectivityType type,
378                                          String address, boolean connected) {
379         Log.i(TAG, "onConnectionStateChanged address: " + address);
380         final String msg = getString(R.string.action_onconnectionstatechanged) + connected;
381         Log.i(TAG, msg);
382         mActivity.runOnUiThread(new Runnable() {
383             @Override
384             public void run() {
385                 Common.showToast(mContext, msg);
386             }
387         });
388     }
389 }