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