blob: a5f0f24363a5cbd9b27e4d06c0280134522c7c54 [file] [log] [blame]
Eugene Susla6ed45d82017-01-22 13:52:51 -08001/*
2 * Copyright (C) 2013 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
17package com.android.companiondevicemanager;
18
Eugene Susla36e866b2017-02-23 18:24:39 -080019import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
20import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
21
22import static com.android.internal.util.ArrayUtils.isEmpty;
Eugene Susla0c4a9262017-06-09 18:03:14 -070023import static com.android.internal.util.CollectionUtils.emptyIfNull;
24import static com.android.internal.util.CollectionUtils.size;
Eugene Susla158d5e72018-02-27 14:32:21 -080025import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
Eugene Susla6ed45d82017-01-22 13:52:51 -080026
27import android.annotation.NonNull;
28import android.annotation.Nullable;
29import android.app.PendingIntent;
30import android.app.Service;
31import android.bluetooth.BluetoothAdapter;
32import android.bluetooth.BluetoothDevice;
33import android.bluetooth.BluetoothManager;
34import android.bluetooth.le.BluetoothLeScanner;
35import android.bluetooth.le.ScanCallback;
36import android.bluetooth.le.ScanFilter;
37import android.bluetooth.le.ScanResult;
38import android.bluetooth.le.ScanSettings;
39import android.companion.AssociationRequest;
Eugene Susla36e866b2017-02-23 18:24:39 -080040import android.companion.BluetoothDeviceFilter;
Eugene Susla722463f2017-04-19 15:22:39 -070041import android.companion.BluetoothLeDeviceFilter;
Eugene Susla36e866b2017-02-23 18:24:39 -080042import android.companion.DeviceFilter;
Svet Ganovda0acdf2017-02-15 10:28:51 -080043import android.companion.ICompanionDeviceDiscoveryService;
44import android.companion.ICompanionDeviceDiscoveryServiceCallback;
45import android.companion.IFindDeviceCallback;
Eugene Susla36e866b2017-02-23 18:24:39 -080046import android.companion.WifiDeviceFilter;
Eugene Susla6ed45d82017-01-22 13:52:51 -080047import android.content.BroadcastReceiver;
48import android.content.Context;
49import android.content.Intent;
50import android.content.IntentFilter;
51import android.graphics.Color;
Eugene Susla6ed45d82017-01-22 13:52:51 -080052import android.graphics.drawable.Drawable;
Eugene Susla36e866b2017-02-23 18:24:39 -080053import android.net.wifi.WifiManager;
Eugene Susla158d5e72018-02-27 14:32:21 -080054import android.os.Handler;
Eugene Susla6ed45d82017-01-22 13:52:51 -080055import android.os.IBinder;
Eugene Susla36e866b2017-02-23 18:24:39 -080056import android.os.Parcelable;
Eugene Susla6ed45d82017-01-22 13:52:51 -080057import android.os.RemoteException;
Eugene Susla36e866b2017-02-23 18:24:39 -080058import android.text.TextUtils;
Eugene Susla6ed45d82017-01-22 13:52:51 -080059import android.util.Log;
60import android.view.View;
61import android.view.ViewGroup;
62import android.widget.ArrayAdapter;
63import android.widget.TextView;
64
Eugene Suslaa38fbf62017-03-14 10:26:10 -070065import com.android.internal.util.ArrayUtils;
Eugene Susla6a7006a2017-03-13 12:57:58 -070066import com.android.internal.util.CollectionUtils;
Eugene Susla36e866b2017-02-23 18:24:39 -080067import com.android.internal.util.Preconditions;
Eugene Susla158d5e72018-02-27 14:32:21 -080068import com.android.internal.util.function.pooled.PooledLambda;
Eugene Susla36e866b2017-02-23 18:24:39 -080069
Eugene Susla158d5e72018-02-27 14:32:21 -080070import java.lang.ref.WeakReference;
Eugene Susla6ed45d82017-01-22 13:52:51 -080071import java.util.ArrayList;
Eugene Susla6ed45d82017-01-22 13:52:51 -080072import java.util.List;
Eugene Susla36e866b2017-02-23 18:24:39 -080073import java.util.Objects;
Eugene Susla6ed45d82017-01-22 13:52:51 -080074
75public class DeviceDiscoveryService extends Service {
76
77 private static final boolean DEBUG = false;
78 private static final String LOG_TAG = "DeviceDiscoveryService";
79
Eugene Susla158d5e72018-02-27 14:32:21 -080080 private static final long SCAN_TIMEOUT = 20000;
81
Eugene Susla6ed45d82017-01-22 13:52:51 -080082 static DeviceDiscoveryService sInstance;
83
84 private BluetoothAdapter mBluetoothAdapter;
Eugene Susla36e866b2017-02-23 18:24:39 -080085 private WifiManager mWifiManager;
Eugene Susla7a090a12017-06-28 10:58:46 -070086 @Nullable private BluetoothLeScanner mBLEScanner;
Eugene Susla6ed45d82017-01-22 13:52:51 -080087 private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
Eugene Suslaa7717e32017-04-17 19:13:31 -070088
Eugene Susla36e866b2017-02-23 18:24:39 -080089 private List<DeviceFilter<?>> mFilters;
Eugene Susla722463f2017-04-19 15:22:39 -070090 private List<BluetoothLeDeviceFilter> mBLEFilters;
Eugene Susla36e866b2017-02-23 18:24:39 -080091 private List<BluetoothDeviceFilter> mBluetoothFilters;
92 private List<WifiDeviceFilter> mWifiFilters;
93 private List<ScanFilter> mBLEScanFilters;
Eugene Suslaa7717e32017-04-17 19:13:31 -070094
Eugene Susla36e866b2017-02-23 18:24:39 -080095 AssociationRequest mRequest;
96 List<DeviceFilterPair> mDevicesFound;
97 DeviceFilterPair mSelectedDevice;
Eugene Susla6ed45d82017-01-22 13:52:51 -080098 DevicesAdapter mDevicesAdapter;
Svet Ganovda0acdf2017-02-15 10:28:51 -080099 IFindDeviceCallback mFindCallback;
Eugene Suslaa7717e32017-04-17 19:13:31 -0700100
Svet Ganovda0acdf2017-02-15 10:28:51 -0800101 ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
Eugene Susla158d5e72018-02-27 14:32:21 -0800102 boolean mIsScanning = false;
103 @Nullable DeviceChooserActivity mActivity = null;
Eugene Susla6ed45d82017-01-22 13:52:51 -0800104
Svet Ganovda0acdf2017-02-15 10:28:51 -0800105 private final ICompanionDeviceDiscoveryService mBinder =
106 new ICompanionDeviceDiscoveryService.Stub() {
Eugene Susla6ed45d82017-01-22 13:52:51 -0800107 @Override
108 public void startDiscovery(AssociationRequest request,
Svet Ganovda0acdf2017-02-15 10:28:51 -0800109 String callingPackage,
110 IFindDeviceCallback findCallback,
111 ICompanionDeviceDiscoveryServiceCallback serviceCallback) {
Eugene Susla6ed45d82017-01-22 13:52:51 -0800112 if (DEBUG) {
113 Log.i(LOG_TAG,
Svet Ganovda0acdf2017-02-15 10:28:51 -0800114 "startDiscovery() called with: filter = [" + request
115 + "], findCallback = [" + findCallback + "]"
116 + "], serviceCallback = [" + serviceCallback + "]");
Eugene Susla6ed45d82017-01-22 13:52:51 -0800117 }
Svet Ganovda0acdf2017-02-15 10:28:51 -0800118 mFindCallback = findCallback;
119 mServiceCallback = serviceCallback;
Eugene Susla6ed45d82017-01-22 13:52:51 -0800120 DeviceDiscoveryService.this.startDiscovery(request);
121 }
122 };
123
Eugene Suslaa7717e32017-04-17 19:13:31 -0700124 private ScanCallback mBLEScanCallback;
125 private BluetoothBroadcastReceiver mBluetoothBroadcastReceiver;
126 private WifiBroadcastReceiver mWifiBroadcastReceiver;
Eugene Susla36e866b2017-02-23 18:24:39 -0800127
Eugene Susla6ed45d82017-01-22 13:52:51 -0800128 @Override
129 public IBinder onBind(Intent intent) {
130 if (DEBUG) Log.i(LOG_TAG, "onBind(" + intent + ")");
131 return mBinder.asBinder();
132 }
133
134 @Override
135 public void onCreate() {
136 super.onCreate();
137
138 if (DEBUG) Log.i(LOG_TAG, "onCreate()");
139
140 mBluetoothAdapter = getSystemService(BluetoothManager.class).getAdapter();
141 mBLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
Eugene Susla36e866b2017-02-23 18:24:39 -0800142 mWifiManager = getSystemService(WifiManager.class);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800143
144 mDevicesFound = new ArrayList<>();
145 mDevicesAdapter = new DevicesAdapter();
146
147 sInstance = this;
148 }
149
Eugene Susla36e866b2017-02-23 18:24:39 -0800150 private void startDiscovery(AssociationRequest request) {
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700151 if (!request.equals(mRequest)) {
152 mRequest = request;
Eugene Susla36e866b2017-02-23 18:24:39 -0800153
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700154 mFilters = request.getDeviceFilters();
155 mWifiFilters = CollectionUtils.filter(mFilters, WifiDeviceFilter.class);
156 mBluetoothFilters = CollectionUtils.filter(mFilters, BluetoothDeviceFilter.class);
Eugene Susla722463f2017-04-19 15:22:39 -0700157 mBLEFilters = CollectionUtils.filter(mFilters, BluetoothLeDeviceFilter.class);
158 mBLEScanFilters = CollectionUtils.map(mBLEFilters, BluetoothLeDeviceFilter::getScanFilter);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800159
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700160 reset();
Eugene Susla3c9aa172017-03-28 15:04:12 -0700161 } else if (DEBUG) Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request);
162
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700163 if (!ArrayUtils.isEmpty(mDevicesFound)) {
164 onReadyToShowUI();
165 }
Eugene Susla6ed45d82017-01-22 13:52:51 -0800166
Eugene Susla0c4a9262017-06-09 18:03:14 -0700167 // If filtering to get single device by mac address, also search in the set of already
168 // bonded devices to allow linking those directly
169 String singleMacAddressFilter = null;
170 if (mRequest.isSingleDevice()) {
171 int numFilters = size(mBluetoothFilters);
172 for (int i = 0; i < numFilters; i++) {
173 BluetoothDeviceFilter filter = mBluetoothFilters.get(i);
174 if (!TextUtils.isEmpty(filter.getAddress())) {
175 singleMacAddressFilter = filter.getAddress();
176 break;
177 }
178 }
179 }
180 if (singleMacAddressFilter != null) {
181 for (BluetoothDevice dev : emptyIfNull(mBluetoothAdapter.getBondedDevices())) {
182 onDeviceFound(DeviceFilterPair.findMatch(dev, mBluetoothFilters));
183 }
184 }
185
Eugene Susla36e866b2017-02-23 18:24:39 -0800186 if (shouldScan(mBluetoothFilters)) {
187 final IntentFilter intentFilter = new IntentFilter();
188 intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
189 intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800190
Eugene Suslaa7717e32017-04-17 19:13:31 -0700191 mBluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
192 registerReceiver(mBluetoothBroadcastReceiver, intentFilter);
Eugene Susla36e866b2017-02-23 18:24:39 -0800193 mBluetoothAdapter.startDiscovery();
194 }
Eugene Susla6ed45d82017-01-22 13:52:51 -0800195
Eugene Susla7a090a12017-06-28 10:58:46 -0700196 if (shouldScan(mBLEFilters) && mBLEScanner != null) {
Eugene Suslaa7717e32017-04-17 19:13:31 -0700197 mBLEScanCallback = new BLEScanCallback();
Eugene Susla36e866b2017-02-23 18:24:39 -0800198 mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
199 }
200
201 if (shouldScan(mWifiFilters)) {
Eugene Suslaa7717e32017-04-17 19:13:31 -0700202 mWifiBroadcastReceiver = new WifiBroadcastReceiver();
203 registerReceiver(mWifiBroadcastReceiver,
Eugene Susla36e866b2017-02-23 18:24:39 -0800204 new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
205 mWifiManager.startScan();
206 }
Eugene Susla158d5e72018-02-27 14:32:21 -0800207 mIsScanning = true;
208 Handler.getMain().sendMessageDelayed(
209 obtainMessage(DeviceDiscoveryService::stopScan, this),
210 SCAN_TIMEOUT);
Eugene Susla36e866b2017-02-23 18:24:39 -0800211 }
212
213 private boolean shouldScan(List<? extends DeviceFilter> mediumSpecificFilters) {
214 return !isEmpty(mediumSpecificFilters) || isEmpty(mFilters);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800215 }
216
217 private void reset() {
Eugene Susla3c9aa172017-03-28 15:04:12 -0700218 if (DEBUG) Log.i(LOG_TAG, "reset()");
Eugene Suslaa7717e32017-04-17 19:13:31 -0700219 stopScan();
Eugene Susla6ed45d82017-01-22 13:52:51 -0800220 mDevicesFound.clear();
221 mSelectedDevice = null;
222 mDevicesAdapter.notifyDataSetChanged();
223 }
224
225 @Override
226 public boolean onUnbind(Intent intent) {
227 stopScan();
228 return super.onUnbind(intent);
229 }
230
231 private void stopScan() {
Eugene Suslaa7717e32017-04-17 19:13:31 -0700232 if (DEBUG) Log.i(LOG_TAG, "stopScan()");
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700233
Eugene Susla158d5e72018-02-27 14:32:21 -0800234 if (!mIsScanning) return;
235 mIsScanning = false;
236
237 DeviceChooserActivity activity = mActivity;
238 if (activity != null) {
239 activity.mDeviceListView.removeFooterView(activity.mLoadingIndicator);
240 mActivity = null;
241 }
242
Eugene Suslaa7717e32017-04-17 19:13:31 -0700243 mBluetoothAdapter.cancelDiscovery();
244 if (mBluetoothBroadcastReceiver != null) {
245 unregisterReceiver(mBluetoothBroadcastReceiver);
246 mBluetoothBroadcastReceiver = null;
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700247 }
Eugene Susla7a090a12017-06-28 10:58:46 -0700248 if (mBLEScanner != null) mBLEScanner.stopScan(mBLEScanCallback);
Eugene Suslaa7717e32017-04-17 19:13:31 -0700249 if (mWifiBroadcastReceiver != null) {
250 unregisterReceiver(mWifiBroadcastReceiver);
251 mWifiBroadcastReceiver = null;
Eugene Suslaa38fbf62017-03-14 10:26:10 -0700252 }
Eugene Susla6ed45d82017-01-22 13:52:51 -0800253 }
254
Eugene Susla36e866b2017-02-23 18:24:39 -0800255 private void onDeviceFound(@Nullable DeviceFilterPair device) {
Eugene Susla0c4a9262017-06-09 18:03:14 -0700256 if (device == null) return;
257
Eugene Susla6ed45d82017-01-22 13:52:51 -0800258 if (mDevicesFound.contains(device)) {
259 return;
260 }
261
Eugene Suslaa7717e32017-04-17 19:13:31 -0700262 if (DEBUG) Log.i(LOG_TAG, "Found device " + device);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800263
Eugene Susla6ed45d82017-01-22 13:52:51 -0800264 if (mDevicesFound.isEmpty()) {
265 onReadyToShowUI();
266 }
267 mDevicesFound.add(device);
268 mDevicesAdapter.notifyDataSetChanged();
269 }
270
271 //TODO also, on timeout -> call onFailure
272 private void onReadyToShowUI() {
273 try {
Svet Ganovda0acdf2017-02-15 10:28:51 -0800274 mFindCallback.onSuccess(PendingIntent.getActivity(
Eugene Susla6ed45d82017-01-22 13:52:51 -0800275 this, 0,
276 new Intent(this, DeviceChooserActivity.class),
277 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
278 | PendingIntent.FLAG_IMMUTABLE));
279 } catch (RemoteException e) {
280 throw new RuntimeException(e);
281 }
282 }
283
Eugene Susla36e866b2017-02-23 18:24:39 -0800284 private void onDeviceLost(@Nullable DeviceFilterPair device) {
Eugene Susla6ed45d82017-01-22 13:52:51 -0800285 mDevicesFound.remove(device);
286 mDevicesAdapter.notifyDataSetChanged();
Eugene Susla36e866b2017-02-23 18:24:39 -0800287 if (DEBUG) Log.i(LOG_TAG, "Lost device " + device.getDisplayName());
Eugene Susla6ed45d82017-01-22 13:52:51 -0800288 }
289
Eugene Susla47aafbe2017-02-13 12:46:46 -0800290 void onDeviceSelected(String callingPackage, String deviceAddress) {
291 try {
292 mServiceCallback.onDeviceSelected(
293 //TODO is this the right userId?
294 callingPackage, getUserId(), deviceAddress);
295 } catch (RemoteException e) {
296 Log.e(LOG_TAG, "Failed to record association: "
297 + callingPackage + " <-> " + deviceAddress);
298 }
299 }
300
Eugene Susla200c37f2017-03-28 15:40:44 -0700301 void onCancel() {
Eugene Suslaa7717e32017-04-17 19:13:31 -0700302 if (DEBUG) Log.i(LOG_TAG, "onCancel()");
Eugene Susla200c37f2017-03-28 15:40:44 -0700303 try {
304 mServiceCallback.onDeviceSelectionCancel();
305 } catch (RemoteException e) {
306 throw new RuntimeException(e);
307 }
308 }
309
Eugene Susla36e866b2017-02-23 18:24:39 -0800310 class DevicesAdapter extends ArrayAdapter<DeviceFilterPair> {
Eugene Susla6ed45d82017-01-22 13:52:51 -0800311 private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
Eugene Susla254b3732017-04-18 13:45:17 -0700312 private Drawable WIFI_ICON = icon(com.android.internal.R.drawable.ic_wifi_signal_3);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800313
314 private Drawable icon(int drawableRes) {
315 Drawable icon = getResources().getDrawable(drawableRes, null);
316 icon.setTint(Color.DKGRAY);
317 return icon;
318 }
319
320 public DevicesAdapter() {
321 super(DeviceDiscoveryService.this, 0, mDevicesFound);
322 }
323
324 @Override
325 public View getView(
326 int position,
327 @Nullable View convertView,
328 @NonNull ViewGroup parent) {
329 TextView view = convertView instanceof TextView
330 ? (TextView) convertView
331 : newView();
332 bind(view, getItem(position));
333 return view;
334 }
335
Eugene Susla36e866b2017-02-23 18:24:39 -0800336 private void bind(TextView textView, DeviceFilterPair device) {
337 textView.setText(device.getDisplayName());
Eugene Susla6ed45d82017-01-22 13:52:51 -0800338 textView.setBackgroundColor(
339 device.equals(mSelectedDevice)
340 ? Color.GRAY
341 : Color.TRANSPARENT);
Eugene Susla254b3732017-04-18 13:45:17 -0700342 textView.setCompoundDrawablesWithIntrinsicBounds(
343 device.device instanceof android.net.wifi.ScanResult
344 ? WIFI_ICON
345 : BLUETOOTH_ICON,
346 null, null, null);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800347 textView.setOnClickListener((view) -> {
348 mSelectedDevice = device;
349 notifyDataSetChanged();
350 });
351 }
352
353 //TODO move to a layout file
354 private TextView newView() {
355 final TextView textView = new TextView(DeviceDiscoveryService.this);
356 textView.setTextColor(Color.BLACK);
357 final int padding = DeviceChooserActivity.getPadding(getResources());
358 textView.setPadding(padding, padding, padding, padding);
Eugene Susla6ed45d82017-01-22 13:52:51 -0800359 textView.setCompoundDrawablePadding(padding);
360 return textView;
361 }
362 }
Eugene Susla36e866b2017-02-23 18:24:39 -0800363
364 /**
365 * A pair of device and a filter that matched this device if any.
366 *
367 * @param <T> device type
368 */
369 static class DeviceFilterPair<T extends Parcelable> {
370 public final T device;
371 @Nullable
372 public final DeviceFilter<T> filter;
373
374 private DeviceFilterPair(T device, @Nullable DeviceFilter<T> filter) {
375 this.device = device;
376 this.filter = filter;
377 }
378
379 /**
380 * {@code (device, null)} if the filters list is empty or null
381 * {@code null} if none of the provided filters match the device
382 * {@code (device, filter)} where filter is among the list of filters and matches the device
383 */
384 @Nullable
385 public static <T extends Parcelable> DeviceFilterPair<T> findMatch(
386 T dev, @Nullable List<? extends DeviceFilter<T>> filters) {
387 if (isEmpty(filters)) return new DeviceFilterPair<>(dev, null);
Eugene Susla3c9aa172017-03-28 15:04:12 -0700388 final DeviceFilter<T> matchingFilter
389 = CollectionUtils.find(filters, f -> f.matches(dev));
390
391 DeviceFilterPair<T> result = matchingFilter != null
392 ? new DeviceFilterPair<>(dev, matchingFilter)
393 : null;
394 if (DEBUG) Log.i(LOG_TAG, "findMatch(dev = " + dev + ", filters = " + filters +
395 ") -> " + result);
396 return result;
Eugene Susla36e866b2017-02-23 18:24:39 -0800397 }
398
399 public String getDisplayName() {
400 if (filter == null) {
401 Preconditions.checkNotNull(device);
402 if (device instanceof BluetoothDevice) {
403 return getDeviceDisplayNameInternal((BluetoothDevice) device);
404 } else if (device instanceof android.net.wifi.ScanResult) {
405 return getDeviceDisplayNameInternal((android.net.wifi.ScanResult) device);
406 } else if (device instanceof ScanResult) {
407 return getDeviceDisplayNameInternal(((ScanResult) device).getDevice());
408 } else {
409 throw new IllegalArgumentException("Unknown device type: " + device.getClass());
410 }
411 }
412 return filter.getDeviceDisplayName(device);
413 }
414
415 @Override
416 public boolean equals(Object o) {
417 if (this == o) return true;
418 if (o == null || getClass() != o.getClass()) return false;
419 DeviceFilterPair<?> that = (DeviceFilterPair<?>) o;
420 return Objects.equals(getDeviceMacAddress(device), getDeviceMacAddress(that.device));
421 }
422
423 @Override
424 public int hashCode() {
425 return Objects.hash(getDeviceMacAddress(device));
426 }
Eugene Suslaa7717e32017-04-17 19:13:31 -0700427
428 @Override
429 public String toString() {
430 return "DeviceFilterPair{" +
431 "device=" + device +
432 ", filter=" + filter +
433 '}';
434 }
435 }
436
437 private class BLEScanCallback extends ScanCallback {
438
439 public BLEScanCallback() {
440 if (DEBUG) Log.i(LOG_TAG, "new BLEScanCallback() -> " + this);
441 }
442
443 @Override
444 public void onScanResult(int callbackType, ScanResult result) {
445 if (DEBUG) {
446 Log.i(LOG_TAG,
447 "BLE.onScanResult(callbackType = " + callbackType + ", result = " + result
448 + ")");
449 }
450 final DeviceFilterPair<ScanResult> deviceFilterPair
451 = DeviceFilterPair.findMatch(result, mBLEFilters);
452 if (deviceFilterPair == null) return;
453 if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
454 onDeviceLost(deviceFilterPair);
455 } else {
456 onDeviceFound(deviceFilterPair);
457 }
458 }
459 }
460
461 private class BluetoothBroadcastReceiver extends BroadcastReceiver {
462 @Override
463 public void onReceive(Context context, Intent intent) {
464 if (DEBUG) {
465 Log.i(LOG_TAG,
466 "BL.onReceive(context = " + context + ", intent = " + intent + ")");
467 }
468 final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
469 final DeviceFilterPair<BluetoothDevice> deviceFilterPair
470 = DeviceFilterPair.findMatch(device, mBluetoothFilters);
471 if (deviceFilterPair == null) return;
472 if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
473 onDeviceFound(deviceFilterPair);
474 } else {
475 onDeviceLost(deviceFilterPair);
476 }
477 }
478 }
479
480 private class WifiBroadcastReceiver extends BroadcastReceiver {
481 @Override
482 public void onReceive(Context context, Intent intent) {
483 if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
484 List<android.net.wifi.ScanResult> scanResults = mWifiManager.getScanResults();
485
486 if (DEBUG) {
487 Log.i(LOG_TAG, "Wifi scan results: " + TextUtils.join("\n", scanResults));
488 }
489
490 for (int i = 0; i < scanResults.size(); i++) {
Eugene Susla0c4a9262017-06-09 18:03:14 -0700491 onDeviceFound(DeviceFilterPair.findMatch(scanResults.get(i), mWifiFilters));
Eugene Suslaa7717e32017-04-17 19:13:31 -0700492 }
493 }
Eugene Suslaa7717e32017-04-17 19:13:31 -0700494 }
Eugene Susla36e866b2017-02-23 18:24:39 -0800495 }
Eugene Susla6ed45d82017-01-22 13:52:51 -0800496}