| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.googlecode.android_scripting.facade.bluetooth; |
| |
| import android.app.Service; |
| import android.bluetooth.BluetoothAdapter; |
| import android.bluetooth.BluetoothAdapter.LeScanCallback; |
| import android.bluetooth.BluetoothDevice; |
| import android.bluetooth.le.BluetoothLeScanner; |
| import android.bluetooth.le.ScanCallback; |
| import android.bluetooth.le.ScanFilter; |
| import android.bluetooth.le.ScanFilter.Builder; |
| import android.bluetooth.le.ScanResult; |
| import android.bluetooth.le.ScanSettings; |
| import android.os.Bundle; |
| import android.os.ParcelUuid; |
| |
| import com.googlecode.android_scripting.Log; |
| import com.googlecode.android_scripting.MainThread; |
| import com.googlecode.android_scripting.facade.EventFacade; |
| import com.googlecode.android_scripting.facade.FacadeManager; |
| import com.googlecode.android_scripting.jsonrpc.RpcReceiver; |
| import com.googlecode.android_scripting.rpc.Rpc; |
| import com.googlecode.android_scripting.rpc.RpcOptional; |
| import com.googlecode.android_scripting.rpc.RpcParameter; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.UUID; |
| import java.util.concurrent.Callable; |
| |
| /** |
| * BluetoothLe Scan functions. |
| */ |
| |
| public class BluetoothLeScanFacade extends RpcReceiver { |
| |
| private final EventFacade mEventFacade; |
| |
| private BluetoothAdapter mBluetoothAdapter; |
| private static int ScanCallbackCount; |
| private static int FilterListCount; |
| private static int LeScanCallbackCount; |
| private static int ScanSettingsCount; |
| private final Service mService; |
| private final BluetoothLeScanner mScanner; |
| private android.bluetooth.le.ScanSettings.Builder mScanSettingsBuilder; |
| private Builder mScanFilterBuilder; |
| private final HashMap<Integer, myScanCallback> mScanCallbackList; |
| private final HashMap<Integer, myLeScanCallback> mLeScanCallbackList; |
| private final HashMap<Integer, ArrayList<ScanFilter>> mScanFilterList; |
| private final HashMap<Integer, ScanSettings> mScanSettingsList; |
| |
| public BluetoothLeScanFacade(FacadeManager manager) { |
| super(manager); |
| mService = manager.getService(); |
| mBluetoothAdapter = MainThread.run(mService, |
| new Callable<BluetoothAdapter>() { |
| @Override |
| public BluetoothAdapter call() throws Exception { |
| return BluetoothAdapter.getDefaultAdapter(); |
| } |
| }); |
| mScanner = mBluetoothAdapter.getBluetoothLeScanner(); |
| mEventFacade = manager.getReceiver(EventFacade.class); |
| mScanFilterList = new HashMap<Integer, ArrayList<ScanFilter>>(); |
| mLeScanCallbackList = new HashMap<Integer, myLeScanCallback>(); |
| mScanSettingsList = new HashMap<Integer, ScanSettings>(); |
| mScanCallbackList = new HashMap<Integer, myScanCallback>(); |
| mScanFilterBuilder = new Builder(); |
| mScanSettingsBuilder = new android.bluetooth.le.ScanSettings.Builder(); |
| } |
| |
| /** |
| * Constructs a myScanCallback obj and returns its index |
| * |
| * @return Integer myScanCallback.index |
| */ |
| @Rpc(description = "Generate a new myScanCallback Object") |
| public Integer bleGenScanCallback() { |
| ScanCallbackCount += 1; |
| int index = ScanCallbackCount; |
| myScanCallback mScan = new myScanCallback(index); |
| mScanCallbackList.put(mScan.index, mScan); |
| return mScan.index; |
| } |
| |
| /** |
| * Constructs a myLeScanCallback obj and returns its index |
| * |
| * @return Integer myScanCallback.index |
| */ |
| @Rpc(description = "Generate a new myScanCallback Object") |
| public Integer bleGenLeScanCallback() { |
| LeScanCallbackCount += 1; |
| int index = LeScanCallbackCount; |
| myLeScanCallback mScan = new myLeScanCallback(index); |
| mLeScanCallbackList.put(mScan.index, mScan); |
| return mScan.index; |
| } |
| |
| /** |
| * Constructs a new filter list array and returns its index |
| * |
| * @return Integer index |
| */ |
| @Rpc(description = "Generate a new Filter list") |
| public Integer bleGenFilterList() { |
| FilterListCount += 1; |
| int index = FilterListCount; |
| mScanFilterList.put(index, new ArrayList<ScanFilter>()); |
| return index; |
| } |
| |
| /** |
| * Constructs a new filter list array and returns its index |
| * |
| * @return Integer index |
| */ |
| @Rpc(description = "Generate a new Filter list") |
| public Integer bleBuildScanFilter( |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex |
| ) { |
| mScanFilterList.get(filterIndex).add(mScanFilterBuilder.build()); |
| mScanFilterBuilder = new Builder(); |
| return mScanFilterList.get(filterIndex).size()-1; |
| } |
| |
| /** |
| * Constructs a new scan setting and returns its index |
| * |
| * @return Integer index |
| */ |
| @Rpc(description = "Generate a new scan settings Object") |
| public Integer bleBuildScanSetting() { |
| ScanSettingsCount += 1; |
| int index = ScanSettingsCount; |
| mScanSettingsList.put(index, mScanSettingsBuilder.build()); |
| mScanSettingsBuilder = new android.bluetooth.le.ScanSettings.Builder(); |
| return index; |
| } |
| |
| /** |
| * Stops a ble scan |
| * |
| * @param index the id of the myScan whose ScanCallback to stop |
| * @throws Exception |
| */ |
| @Rpc(description = "Stops an ongoing ble advertisement scan") |
| public void bleStopBleScan( |
| @RpcParameter(name = "index") |
| Integer index) throws Exception { |
| Log.d("bluetooth_le_scan mScanCallback " + index); |
| if (mScanCallbackList.get(index) != null) { |
| myScanCallback mScanCallback = mScanCallbackList.get(index); |
| mScanner.stopScan(mScanCallback); |
| } else { |
| throw new Exception("Invalid index input:" + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Stops a classic ble scan |
| * |
| * @param index the id of the myScan whose LeScanCallback to stop |
| * @throws Exception |
| */ |
| @Rpc(description = "Stops an ongoing classic ble scan") |
| public void bleStopClassicBleScan( |
| @RpcParameter(name = "index") |
| Integer index) throws Exception { |
| Log.d("bluetooth_le_scan mLeScanCallback " + index); |
| if (mLeScanCallbackList.get(index) != null) { |
| myLeScanCallback mLeScanCallback = mLeScanCallbackList.get(index); |
| mBluetoothAdapter.stopLeScan(mLeScanCallback); |
| } else { |
| throw new Exception("Invalid index input:" + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Starts a ble scan |
| * |
| * @param index the id of the myScan whose ScanCallback to start |
| * @throws Exception |
| */ |
| @Rpc(description = "Starts a ble advertisement scan") |
| public void bleStartBleScan( |
| @RpcParameter(name = "filterListIndex") |
| Integer filterListIndex, |
| @RpcParameter(name = "scanSettingsIndex") |
| Integer scanSettingsIndex, |
| @RpcParameter(name = "callbackIndex") |
| Integer callbackIndex |
| ) throws Exception { |
| Log.d("bluetooth_le_scan starting a background scan"); |
| ArrayList<ScanFilter> mScanFilters = new ArrayList<ScanFilter>(); |
| mScanFilters.add(new ScanFilter.Builder().build()); |
| ScanSettings mScanSettings = new ScanSettings.Builder().build(); |
| if (mScanFilterList.get(filterListIndex) != null) { |
| mScanFilters = mScanFilterList.get(filterListIndex); |
| } else { |
| throw new Exception("Invalid filterListIndex input:" |
| + Integer.toString(filterListIndex)); |
| } |
| if (mScanSettingsList.get(scanSettingsIndex) != null) { |
| mScanSettings = mScanSettingsList.get(scanSettingsIndex); |
| } else if (!mScanSettingsList.isEmpty()) { |
| throw new Exception("Invalid scanSettingsIndex input:" |
| + Integer.toString(scanSettingsIndex)); |
| } |
| if (mScanCallbackList.get(callbackIndex) != null) { |
| mScanner.startScan(mScanFilters, mScanSettings, |
| mScanCallbackList.get(callbackIndex)); |
| } else { |
| throw new Exception("Invalid filterListIndex input:" |
| + Integer.toString(filterListIndex)); |
| } |
| } |
| |
| /** |
| * Starts a classic ble scan |
| * |
| * @param index the id of the myScan whose ScanCallback to start |
| * @throws Exception |
| */ |
| @Rpc(description = "Starts a classic ble advertisement scan") |
| public boolean bleStartClassicBleScan( |
| @RpcParameter(name = "leCallbackIndex") |
| Integer leCallbackIndex |
| ) throws Exception { |
| Log.d("bluetooth_le_scan starting a background scan"); |
| boolean result = false; |
| if (mLeScanCallbackList.get(leCallbackIndex) != null) { |
| result = mBluetoothAdapter.startLeScan( |
| mLeScanCallbackList.get(leCallbackIndex)); |
| } else { |
| throw new Exception("Invalid leCallbackIndex input:" |
| + Integer.toString(leCallbackIndex)); |
| } |
| return result; |
| } |
| |
| /** |
| * Starts a classic ble scan with service Uuids |
| * |
| * @param index the id of the myScan whose ScanCallback to start |
| * @throws Exception |
| */ |
| @Rpc(description = "Starts a classic ble advertisement scan with service Uuids") |
| public boolean bleStartClassicBleScanWithServiceUuids( |
| @RpcParameter(name = "leCallbackIndex") |
| Integer leCallbackIndex, |
| @RpcParameter(name = "serviceUuids") |
| String[] serviceUuidList |
| ) throws Exception { |
| Log.d("bluetooth_le_scan starting a background scan"); |
| UUID[] serviceUuids = new UUID[serviceUuidList.length]; |
| for (int i = 0; i < serviceUuidList.length; i++) { |
| serviceUuids[i] = UUID.fromString(serviceUuidList[i]); |
| } |
| boolean result = false; |
| if (mLeScanCallbackList.get(leCallbackIndex) != null) { |
| result = mBluetoothAdapter.startLeScan(serviceUuids, |
| mLeScanCallbackList.get(leCallbackIndex)); |
| } else { |
| throw new Exception("Invalid leCallbackIndex input:" |
| + Integer.toString(leCallbackIndex)); |
| } |
| return result; |
| } |
| |
| /** |
| * Trigger onBatchScanResults |
| * |
| * @throws Exception |
| */ |
| @Rpc(description = "Gets the results of the ble ScanCallback") |
| public void bleFlushPendingScanResults( |
| @RpcParameter(name = "callbackIndex") |
| Integer callbackIndex |
| ) throws Exception { |
| if (mScanCallbackList.get(callbackIndex) != null) { |
| mBluetoothAdapter |
| .getBluetoothLeScanner().flushPendingScanResults( |
| mScanCallbackList.get(callbackIndex)); |
| } else { |
| throw new Exception("Invalid callbackIndex input:" |
| + Integer.toString(callbackIndex)); |
| } |
| } |
| |
| /** |
| * Set scanSettings for ble scan. Note: You have to set all variables at once. |
| * |
| * @param callbackType Bluetooth LE scan callback type |
| * @param reportDelaySeconds Time of delay for reporting the scan result |
| * @param scanMode Bluetooth LE scan mode. |
| * @param scanResultType Bluetooth LE scan result type |
| * @throws Exception |
| */ |
| |
| /** |
| * Set the scan setting's callback type |
| * @param callbackType Bluetooth LE scan callback type |
| */ |
| @Rpc(description = "Set the scan setting's callback type") |
| public void bleSetScanSettingsCallbackType( |
| @RpcParameter(name = "callbackType") |
| Integer callbackType) { |
| mScanSettingsBuilder.setCallbackType(callbackType); |
| } |
| |
| /** |
| * Set the scan setting's report delay millis |
| * @param reportDelayMillis Time of delay for reporting the scan result |
| */ |
| @Rpc(description = "Set the scan setting's report delay millis") |
| public void bleSetScanSettingsReportDelayMillis( |
| @RpcParameter(name = "reportDelayMillis") |
| Long reportDelayMillis) { |
| mScanSettingsBuilder.setReportDelay(reportDelayMillis); |
| } |
| |
| /** |
| * Set the scan setting's scan mode |
| * @param scanMode Bluetooth LE scan mode. |
| */ |
| @Rpc(description = "Set the scan setting's scan mode") |
| public void bleSetScanSettingsScanMode( |
| @RpcParameter(name = "scanMode") |
| Integer scanMode) { |
| mScanSettingsBuilder.setScanMode(scanMode); |
| } |
| |
| /** |
| * Set the scan setting's legacy mode |
| * @param legacy Wether scan is legacy. |
| */ |
| @Rpc(description = "Set the scan setting's legacy mode") |
| public void bleSetScanSettingsLegacy( |
| @RpcParameter(name = "legacy") |
| Boolean legacy) { |
| mScanSettingsBuilder.setLegacy(legacy); |
| } |
| |
| /** |
| * Set the scan setting's phy mode |
| * @param phy |
| */ |
| @Rpc(description = "Set the scan setting's phy mode") |
| public void bleSetScanSettingsPhy( |
| @RpcParameter(name = "phy") |
| Integer phy) { |
| mScanSettingsBuilder.setPhy(phy); |
| } |
| |
| /** |
| * Set the scan setting's scan result type |
| * @param scanResultType Bluetooth LE scan result type |
| */ |
| @Rpc(description = "Set the scan setting's scan result type") |
| public void bleSetScanSettingsResultType( |
| @RpcParameter(name = "scanResultType") |
| Integer scanResultType) { |
| mScanSettingsBuilder.setScanResultType(scanResultType); |
| } |
| /** |
| * Get ScanSetting's callback type |
| * |
| * @param index the ScanSetting object to use |
| * @return the ScanSetting's callback type |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanSetting's callback type") |
| public Integer bleGetScanSettingsCallbackType( |
| @RpcParameter(name = "index") |
| Integer index |
| ) throws Exception { |
| if (mScanSettingsList.get(index) != null) { |
| ScanSettings mScanSettings = mScanSettingsList.get(index); |
| return mScanSettings.getCallbackType(); |
| } else { |
| throw new Exception("Invalid index input:" + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanSetting's report delay in milli seconds |
| * |
| * @param index the ScanSetting object to useSystemClock |
| * @return the ScanSetting's report delay in milliseconds |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanSetting's report delay milliseconds") |
| public Long bleGetScanSettingsReportDelayMillis( |
| @RpcParameter(name = "index") |
| Integer index) throws Exception { |
| if (mScanSettingsList.get(index) != null) { |
| ScanSettings mScanSettings = mScanSettingsList.get(index); |
| return mScanSettings.getReportDelayMillis(); |
| } else { |
| throw new Exception("Invalid index input:" + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanSetting's scan mode |
| * |
| * @param index the ScanSetting object to use |
| * @return the ScanSetting's scan mode |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanSetting's scan mode") |
| public Integer bleGetScanSettingsScanMode( |
| @RpcParameter(name = "index") |
| Integer index) throws Exception { |
| if (mScanSettingsList.get(index) != null) { |
| ScanSettings mScanSettings = mScanSettingsList.get(index); |
| return mScanSettings.getScanMode(); |
| } else { |
| throw new Exception("Invalid index input:" + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanSetting's scan result type |
| * |
| * @param index the ScanSetting object to use |
| * @return the ScanSetting's scan result type |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanSetting's scan result type") |
| public Integer bleGetScanSettingsScanResultType( |
| @RpcParameter(name = "index") |
| Integer index) throws Exception { |
| if (mScanSettingsList.get(index) != null) { |
| ScanSettings mScanSettings = mScanSettingsList.get(index); |
| return mScanSettings.getScanResultType(); |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's Manufacturer Id |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's manufacturer id |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's Manufacturer Id") |
| public Integer bleGetScanFilterManufacturerId( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index) |
| .get(filterIndex).getManufacturerId(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's device address |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's device address |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's device address") |
| public String bleGetScanFilterDeviceAddress( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getDeviceAddress(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's device name |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's device name |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's device name") |
| public String bleGetScanFilterDeviceName( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getDeviceName(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's manufacturer data |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's manufacturer data |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's manufacturer data") |
| public byte[] bleGetScanFilterManufacturerData( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getManufacturerData(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's manufacturer data mask |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's manufacturer data mask |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's manufacturer data mask") |
| public byte[] bleGetScanFilterManufacturerDataMask( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getManufacturerDataMask(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's service data |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's service data |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's service data") |
| public byte[] bleGetScanFilterServiceData( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getServiceData(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's service data mask |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's service data mask |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's service data mask") |
| public byte[] bleGetScanFilterServiceDataMask( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getServiceDataMask(); |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's service uuid |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's service uuid |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's service uuid") |
| public String bleGetScanFilterServiceUuid( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| if (mScanFilterList.get(index).get( |
| filterIndex).getServiceUuid() != null) { |
| return mScanFilterList.get(index).get( |
| filterIndex).getServiceUuid().toString(); |
| } else { |
| throw new Exception("No Service Uuid set for filter:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Get ScanFilter's service uuid mask |
| * |
| * @param index the ScanFilter object to use |
| * @return the ScanFilter's service uuid mask |
| * @throws Exception |
| */ |
| @Rpc(description = "Get ScanFilter's service uuid mask") |
| public String bleGetScanFilterServiceUuidMask( |
| @RpcParameter(name = "index") |
| Integer index, |
| @RpcParameter(name = "filterIndex") |
| Integer filterIndex) |
| throws Exception { |
| if (mScanFilterList.get(index) != null) { |
| if (mScanFilterList.get(index).get(filterIndex) != null) { |
| if (mScanFilterList.get(index).get( |
| filterIndex).getServiceUuidMask() != null) { |
| return mScanFilterList.get( |
| index).get(filterIndex).getServiceUuidMask() |
| .toString(); |
| } else { |
| throw new Exception("No Service Uuid Mask set for filter:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid filterIndex input:" |
| + Integer.toString(filterIndex)); |
| } |
| } else { |
| throw new Exception("Invalid index input:" |
| + Integer.toString(index)); |
| } |
| } |
| |
| /** |
| * Add filter "macAddress" to existing ScanFilter |
| * |
| * @param macAddress the macAddress to filter against |
| * @throws Exception |
| */ |
| @Rpc(description = "Add filter \"macAddress\" to existing ScanFilter") |
| public void bleSetScanFilterDeviceAddress( |
| @RpcParameter(name = "macAddress") |
| String macAddress |
| ) { |
| mScanFilterBuilder.setDeviceAddress(macAddress); |
| } |
| |
| /** |
| * Add filter "manufacturereDataId and/or manufacturerData" to existing |
| * ScanFilter |
| * @param manufacturerDataId the manufacturer data id to filter against |
| * @param manufacturerDataMask the manufacturere data mask to filter against |
| * @throws Exception |
| */ |
| @Rpc(description = "Add filter \"manufacturereDataId and/or manufacturerData\" to existing ScanFilter") |
| public void bleSetScanFilterManufacturerData( |
| @RpcParameter(name = "manufacturerDataId") |
| Integer manufacturerDataId, |
| @RpcParameter(name = "manufacturerData") |
| byte[] manufacturerData, |
| @RpcParameter(name = "manufacturerDataMask") |
| @RpcOptional |
| byte[] manufacturerDataMask |
| ){ |
| if (manufacturerDataMask != null) { |
| mScanFilterBuilder.setManufacturerData(manufacturerDataId, |
| manufacturerData, manufacturerDataMask); |
| } else { |
| mScanFilterBuilder.setManufacturerData(manufacturerDataId, |
| manufacturerData); |
| } |
| } |
| |
| /** |
| * Add filter "serviceData and serviceDataMask" to existing ScanFilter |
| * |
| * @param serviceData the service data to filter against |
| * @param serviceDataMask the servie data mask to filter against |
| * @throws Exception |
| */ |
| @Rpc(description = "Add filter \"serviceData and serviceDataMask\" to existing ScanFilter ") |
| public void bleSetScanFilterServiceData( |
| @RpcParameter(name = "serviceUuid") String serviceUuid, |
| @RpcParameter(name = "serviceData") byte[] serviceData, |
| @RpcParameter(name = "serviceDataMask") |
| @RpcOptional byte[] serviceDataMask |
| ) { |
| if (serviceDataMask != null) { |
| mScanFilterBuilder |
| .setServiceData( |
| ParcelUuid.fromString(serviceUuid), |
| serviceData, serviceDataMask); |
| } else { |
| mScanFilterBuilder.setServiceData(ParcelUuid.fromString(serviceUuid), |
| serviceData); |
| } |
| } |
| |
| /** |
| * Add filter "serviceUuid and/or serviceMask" to existing ScanFilter |
| * |
| * @param serviceUuid the service uuid to filter against |
| * @param serviceMask the service mask to filter against |
| * @throws Exception |
| */ |
| @Rpc(description = "Add filter \"serviceUuid and/or serviceMask\" to existing ScanFilter") |
| public void bleSetScanFilterServiceUuid( |
| @RpcParameter(name = "serviceUuid") |
| String serviceUuid, |
| @RpcParameter(name = "serviceMask") |
| @RpcOptional |
| String serviceMask |
| ) { |
| if (serviceMask != null) { |
| mScanFilterBuilder |
| .setServiceUuid(ParcelUuid.fromString(serviceUuid), |
| ParcelUuid.fromString(serviceMask)); |
| } else { |
| mScanFilterBuilder.setServiceUuid(ParcelUuid.fromString(serviceUuid)); |
| } |
| } |
| |
| /** |
| * Add filter "device name" to existing ScanFilter |
| * |
| * @param name the device name to filter against |
| * @throws Exception |
| */ |
| @Rpc(description = "Sets the scan filter's device name") |
| public void bleSetScanFilterDeviceName( |
| @RpcParameter(name = "name") |
| String name |
| ) { |
| mScanFilterBuilder.setDeviceName(name); |
| } |
| |
| @Rpc(description = "Set the scan setting's match mode") |
| public void bleSetScanSettingsMatchMode( |
| @RpcParameter(name = "mode") Integer mode) { |
| mScanSettingsBuilder.setMatchMode(mode); |
| } |
| |
| @Rpc(description = "Get the scan setting's match mode") |
| public int bleGetScanSettingsMatchMode( |
| @RpcParameter(name = "scanSettingsIndex") Integer scanSettingsIndex |
| ) { |
| return mScanSettingsList.get(scanSettingsIndex).getMatchMode(); |
| } |
| |
| @Rpc(description = "Set the scan setting's number of matches") |
| public void bleSetScanSettingsNumOfMatches( |
| @RpcParameter(name = "matches") Integer matches) { |
| mScanSettingsBuilder.setNumOfMatches(matches); |
| } |
| |
| @Rpc(description = "Get the scan setting's number of matches") |
| public int bleGetScanSettingsNumberOfMatches( |
| @RpcParameter(name = "scanSettingsIndex") |
| Integer scanSettingsIndex) { |
| return mScanSettingsList.get(scanSettingsIndex).getNumOfMatches(); |
| } |
| |
| private class myScanCallback extends ScanCallback { |
| public Integer index; |
| String mEventType; |
| private final Bundle mResults; |
| |
| public myScanCallback(Integer idx) { |
| index = idx; |
| mEventType = "BleScan"; |
| mResults = new Bundle(); |
| } |
| |
| @Override |
| public void onScanFailed(int errorCode) { |
| String errorString = "UNKNOWN_ERROR_CODE"; |
| if (errorCode == ScanCallback.SCAN_FAILED_ALREADY_STARTED) { |
| errorString = "SCAN_FAILED_ALREADY_STARTED"; |
| } else if (errorCode |
| == ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED) { |
| errorString = "SCAN_FAILED_APPLICATION_REGISTRATION_FAILED"; |
| } else if (errorCode |
| == ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED) { |
| errorString = "SCAN_FAILED_FEATURE_UNSUPPORTED"; |
| } else if (errorCode == ScanCallback.SCAN_FAILED_INTERNAL_ERROR) { |
| errorString = "SCAN_FAILED_INTERNAL_ERROR"; |
| } |
| Log.d("bluetooth_le_scan change onScanFailed " |
| + mEventType + " " + index + " error " |
| + errorString); |
| mResults.putInt("ID", index); |
| mResults.putString("Type", "onScanFailed"); |
| mResults.putInt("ErrorCode", errorCode); |
| mResults.putString("Error", errorString); |
| mEventFacade.postEvent(mEventType + index + "onScanFailed", |
| mResults.clone()); |
| mResults.clear(); |
| } |
| |
| @Override |
| public void onScanResult(int callbackType, ScanResult result) { |
| Log.d("bluetooth_le_scan change onUpdate " |
| + mEventType + " " + index); |
| mResults.putInt("ID", index); |
| mResults.putInt("CallbackType", callbackType); |
| mResults.putString("Type", "onScanResult"); |
| mResults.putParcelable("Result", result); |
| mEventFacade.postEvent( |
| mEventType + index + "onScanResults", mResults.clone()); |
| mResults.clear(); |
| } |
| |
| @Override |
| public void onBatchScanResults(List<ScanResult> results) { |
| Log.d("reportResult " + mEventType + " " + index); |
| mResults.putLong("Timestamp", System.currentTimeMillis() / 1000); |
| mResults.putInt("ID", index); |
| mResults.putString("Type", "onBatchScanResults"); |
| mResults.putParcelableList("Results", results); |
| mEventFacade.postEvent(mEventType |
| + index + "onBatchScanResult", mResults.clone()); |
| mResults.clear(); |
| } |
| } |
| |
| private class myLeScanCallback implements LeScanCallback { |
| public Integer index; |
| String mEventType; |
| private final Bundle mResults; |
| |
| public myLeScanCallback(Integer idx) { |
| index = idx; |
| mEventType = "ClassicBleScan"; |
| mResults = new Bundle(); |
| } |
| |
| @Override |
| public void onLeScan( |
| BluetoothDevice device, int rssi, byte[] scanRecord) { |
| Log.d("bluetooth_classic_le_scan " + mEventType + " " + index); |
| mResults.putParcelable("Device", device); |
| mResults.putInt("Rssi", rssi); |
| mResults.putByteArray("ScanRecord", scanRecord); |
| mResults.putString("Type", "onLeScan"); |
| mEventFacade.postEvent(mEventType |
| + index + "onLeScan", mResults.clone()); |
| mResults.clear(); |
| } |
| } |
| |
| @Override |
| public void shutdown() { |
| if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { |
| for (myScanCallback mScanCallback : mScanCallbackList.values()) { |
| if (mScanCallback != null) { |
| try { |
| mBluetoothAdapter.getBluetoothLeScanner() |
| .stopScan(mScanCallback); |
| } catch (NullPointerException e) { |
| Log.e("Failed to stop ble scan callback.", e); |
| } |
| } |
| } |
| for (myLeScanCallback mLeScanCallback : mLeScanCallbackList.values()) { |
| if (mLeScanCallback != null) { |
| try { |
| mBluetoothAdapter.stopLeScan(mLeScanCallback); |
| } catch (NullPointerException e) { |
| Log.e("Failed to stop classic ble scan callback.", e); |
| } |
| } |
| } |
| } |
| mScanCallbackList.clear(); |
| mScanFilterList.clear(); |
| mScanSettingsList.clear(); |
| mLeScanCallbackList.clear(); |
| } |
| } |