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.cts.verifier.bluetooth;
18 
19 import static android.content.Context.RECEIVER_EXPORTED;
20 
21 import android.app.Activity;
22 import android.app.AlertDialog;
23 import android.bluetooth.BluetoothAdapter;
24 import android.bluetooth.BluetoothDevice;
25 import android.content.BroadcastReceiver;
26 import android.content.Context;
27 import android.content.DialogInterface;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.os.Bundle;
31 import android.view.View;
32 import android.view.View.OnClickListener;
33 import android.widget.AdapterView;
34 import android.widget.AdapterView.OnItemClickListener;
35 import android.widget.ArrayAdapter;
36 import android.widget.Button;
37 import android.widget.ListView;
38 import android.widget.ProgressBar;
39 import android.widget.TextView;
40 
41 import com.android.cts.verifier.R;
42 
43 import java.util.Set;
44 
45 /**
46  * {@link Activity} that shows a list of paired and new devices and returns the device selected
47  * by the user. When the user selects a paired device, it forwards them to the Bluetooth settings
48  * page, so that they can unpair it for the test.
49  */
50 public class DevicePickerActivity extends Activity {
51 
52     public static final String EXTRA_DEVICE_ADDRESS = "deviceAddress";
53 
54     private static final int ENABLE_BLUETOOTH_REQUEST = 1;
55 
56     private BluetoothAdapter mBluetoothAdapter;
57 
58     private DiscoveryReceiver mReceiver;
59 
60     private ArrayAdapter<Device> mNewDevicesAdapter;
61 
62     private ArrayAdapter<Device> mPairedDevicesAdapter;
63 
64     private TextView mEmptyNewView;
65 
66     private ProgressBar mProgressBar;
67 
68     @Override
onCreate(Bundle savedInstanceState)69     protected void onCreate(Bundle savedInstanceState) {
70         super.onCreate(savedInstanceState);
71         setContentView(R.layout.bt_device_picker);
72 
73         mProgressBar = (ProgressBar) findViewById(R.id.bt_progress_bar);
74 
75         mPairedDevicesAdapter = new ArrayAdapter<Device>(this, R.layout.bt_device_name);
76         ListView pairedDevicesListView = (ListView) findViewById(R.id.bt_paired_devices);
77         pairedDevicesListView.setAdapter(mPairedDevicesAdapter);
78         pairedDevicesListView.setOnItemClickListener(new PairedDeviceClickListener());
79 
80         View emptyPairedView = findViewById(R.id.bt_empty_paired_devices);
81         pairedDevicesListView.setEmptyView(emptyPairedView);
82 
83         mNewDevicesAdapter = new ArrayAdapter<Device>(this, R.layout.bt_device_name);
84         ListView newDevicesListView = (ListView) findViewById(R.id.bt_new_devices);
85         newDevicesListView.setAdapter(mNewDevicesAdapter);
86         newDevicesListView.setOnItemClickListener(new NewDeviceClickListener());
87 
88         mEmptyNewView = (TextView) findViewById(R.id.bt_empty_new_devices);
89         newDevicesListView.setEmptyView(mEmptyNewView);
90 
91         mReceiver = new DiscoveryReceiver();
92         IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
93         filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
94         filter.addAction(BluetoothDevice.ACTION_FOUND);
95         registerReceiver(mReceiver, filter, RECEIVER_EXPORTED);
96 
97         Button scanButton = (Button) findViewById(R.id.bt_scan_button);
98         scanButton.setOnClickListener(new OnClickListener() {
99             @Override
100             public void onClick(View v) {
101                 scan();
102             }
103         });
104 
105         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
106         if (mBluetoothAdapter.isEnabled()) {
107             scan();
108         } else {
109             Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
110             startActivityForResult(intent, ENABLE_BLUETOOTH_REQUEST);
111         }
112     }
113 
114     @Override
onActivityResult(int requestCode, int resultCode, Intent data)115     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
116         super.onActivityResult(requestCode, resultCode, data);
117         if (requestCode == ENABLE_BLUETOOTH_REQUEST) {
118             if (resultCode == RESULT_OK) {
119                 scan();
120             } else {
121                 setResult(RESULT_CANCELED);
122                 finish();
123             }
124         }
125     }
126 
scan()127     private void scan() {
128         populatePairedDevices();
129         mNewDevicesAdapter.clear();
130         if (mBluetoothAdapter.isDiscovering()) {
131             mBluetoothAdapter.cancelDiscovery();
132         }
133         mBluetoothAdapter.startDiscovery();
134     }
135 
populatePairedDevices()136     private void populatePairedDevices() {
137         mPairedDevicesAdapter.clear();
138         Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
139         for (BluetoothDevice device : pairedDevices) {
140             mPairedDevicesAdapter.add(Device.fromBluetoothDevice(device));
141         }
142     }
143 
144     @Override
onDestroy()145     protected void onDestroy() {
146         super.onDestroy();
147         if (mBluetoothAdapter != null) {
148             mBluetoothAdapter.cancelDiscovery();
149         }
150         unregisterReceiver(mReceiver);
151     }
152 
153     class NewDeviceClickListener implements OnItemClickListener {
154         @Override
onItemClick(AdapterView<?> parent, View view, int position, long id)155         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
156             Intent data = new Intent();
157             Device device = (Device) parent.getItemAtPosition(position);
158             data.putExtra(EXTRA_DEVICE_ADDRESS, device.mAddress);
159             setResult(RESULT_OK, data);
160             finish();
161         }
162     }
163 
164     class PairedDeviceClickListener implements OnItemClickListener {
165         @Override
onItemClick(AdapterView<?> parent, View view, int position, long id)166         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
167             new AlertDialog.Builder(DevicePickerActivity.this)
168                 .setIcon(android.R.drawable.ic_dialog_alert)
169                 .setMessage(R.string.bt_unpair)
170                 .setPositiveButton(R.string.bt_settings, new DialogInterface.OnClickListener() {
171                     @Override
172                     public void onClick(DialogInterface dialog, int which) {
173                         if (mBluetoothAdapter != null) {
174                             mBluetoothAdapter.cancelDiscovery();
175                         }
176                         Intent intent = new Intent();
177                         intent.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
178                         startActivity(intent);
179                     }
180                 })
181                 .show();
182         }
183     }
184 
185     class DiscoveryReceiver extends BroadcastReceiver {
186         @Override
onReceive(Context context, Intent intent)187         public void onReceive(Context context, Intent intent) {
188             if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
189                 mEmptyNewView.setText(R.string.bt_scanning);
190                 mProgressBar.setVisibility(View.VISIBLE);
191             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
192                 mEmptyNewView.setText(R.string.bt_no_devices);
193                 mProgressBar.setVisibility(View.INVISIBLE);
194             } else if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
195                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
196                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
197                     mNewDevicesAdapter.add(Device.fromBluetoothDevice(device));
198                 }
199             }
200         }
201     }
202 
203     static class Device {
204 
205         String mName;
206 
207         String mAddress;
208 
Device(String name, String address)209         Device(String name, String address) {
210             mName = name;
211             mAddress = address;
212         }
213 
214         @Override
toString()215         public String toString() {
216             return mName + "\n" + mAddress;
217         }
218 
fromBluetoothDevice(BluetoothDevice device)219         static Device fromBluetoothDevice(BluetoothDevice device) {
220             return new Device(device.getName() != null ? device.getName() : "",
221                     device.getAddress());
222         }
223     }
224 }
225