Loading android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +8 −0 Original line number Diff line number Diff line Loading @@ -260,6 +260,14 @@ class AdapterProperties { boolean isActivityAndEnergyReportingSupported() { return mIsActivityAndEnergyReporting; } /** * @return total number of trackable advertisements */ int getTotalNumOfTrackableAdvertisements() { return mTotNumOfTrackableAdv; } /** * @return the mBondedDevices */ Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +5 −8 Original line number Diff line number Diff line Loading @@ -1267,14 +1267,6 @@ public class AdapterService extends Service { return service.reportActivityInfo(); } public int numOfHwTrackFiltersAvailable() { AdapterService service = getService(); if (service == null) return 0; //ToDo: Accounting of how many filters hw can do, capability, //vs how many have been used by current filters by ScanManager return 5; } public String dump() { AdapterService service = getService(); if (service == null) { Loading Loading @@ -1896,6 +1888,11 @@ public class AdapterService extends Service { return info; } public int getTotalNumOfTrackableAdvertisements() { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); } private String dump() { StringBuilder sb = new StringBuilder(); synchronized (mProfiles) { Loading android/app/src/com/android/bluetooth/gatt/GattService.java +21 −0 Original line number Diff line number Diff line Loading @@ -560,6 +560,13 @@ public class GattService extends ProfileService { if (service == null) return; service.unregAll(); } @Override public int numHwTrackFiltersAvailable() { GattService service = getService(); if (service == null) return 0; return service.numHwTrackFiltersAvailable(); } }; /************************************************************************** Loading Loading @@ -1194,6 +1201,16 @@ public class GattService extends ProfileService { app.callback.onMultiAdvertiseCallback(status, isStart, settings); } // callback from ScanManager for dispatch of errors apps. void onScanManagerErrorCallback(int clientIf, int errorCode) throws RemoteException { ClientMap.App app = mClientMap.getById(clientIf); if (app == null || app.callback == null) { Log.e(TAG, "App or callback is null"); return; } app.callback.onScanManagerErrorCallback(errorCode); } void onConfigureMTU(int connId, int status, int mtu) throws RemoteException { String address = mClientMap.addressByConnId(connId); Loading Loading @@ -1413,6 +1430,10 @@ public class GattService extends ProfileService { mAdvertiseManager.stopAdvertising(client); } int numHwTrackFiltersAvailable() { return (AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements() - mScanManager.getCurrentUsedTrackingAdvertisement()); } synchronized List<ParcelUuid> getRegisteredServiceUuids() { Utils.enforceAdminPermission(this); Loading android/app/src/com/android/bluetooth/gatt/ScanManager.java +65 −6 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.gatt; import android.app.AlarmManager; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanSettings; import android.content.BroadcastReceiver; Loading @@ -29,6 +30,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; Loading Loading @@ -73,6 +75,7 @@ public class ScanManager { // Scan parameters for batch scan. private BatchScanParams mBatchScanParms; private Integer curUsedTrackableAdvertisements; private GattService mService; private BroadcastReceiver mBatchAlarmReceiver; private boolean mBatchAlarmReceiverRegistered; Loading Loading @@ -292,6 +295,10 @@ public class ScanManager { } } public int getCurrentUsedTrackingAdvertisement() { return curUsedTrackableAdvertisements; } private class ScanNative { // Delivery mode defined in bt stack. Loading Loading @@ -591,6 +598,22 @@ public class ScanManager { void stopRegularScan(ScanClient client) { // Remove scan filters and recycle filter indices. removeScanFilters(client.clientIf); int deliveryMode = getDeliveryMode(client); if (deliveryMode == DELIVERY_MODE_ON_FOUND_LOST) { for (ScanFilter filter : client.filters) { int entriesToFree = getNumOfTrackingAdvertisements(client.settings); if (!manageAllocationOfTrackingAdvertisement(entriesToFree, false)) { Log.e(TAG, "Error freeing for onfound/onlost filter resources " + entriesToFree); try { mService.onScanManagerErrorCallback(client.clientIf, ScanCallback.SCAN_FAILED_INTERNAL_ERROR); } catch (RemoteException e) { Log.e(TAG, "failed on onScanManagerCallback at freeing", e); } } } } mRegularScanClients.remove(client); if (numRegularScanClients() == 0) { logd("stop scan"); Loading Loading @@ -681,9 +704,15 @@ public class ScanManager { resetCountDownLatch(); if (deliveryMode == DELIVERY_MODE_ON_FOUND_LOST) { trackEntries = getNumOfTrackingAdvertisements(client.settings); if (trackEntries == 0) { Log.e(TAG, "No hardware resources for onfound/onlost filter"); return; if (!manageAllocationOfTrackingAdvertisement(trackEntries, true)) { Log.e(TAG, "No hardware resources for onfound/onlost filter " + trackEntries); try { mService.onScanManagerErrorCallback(clientIf, ScanCallback.SCAN_FAILED_INTERNAL_ERROR); } catch (RemoteException e) { Log.e(TAG, "failed on onScanManagerCallback", e); } } } configureFilterParamter(clientIf, client, featureSelection, filterIndex, Loading Loading @@ -934,6 +963,12 @@ public class ScanManager { if (settings == null) return 0; int val=0; int maxTotalTrackableAdvertisements = AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements(); // controller based onfound onlost resources are scarce commodity; the // assignment of filters to num of beacons to track is configurable based // on hw capabilities. Apps give an intent and allocation of onfound // resources or failure there of is done based on availibility - FCFS model switch (settings.getNumOfMatches()) { case ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT: val = 1; Loading @@ -942,16 +977,40 @@ public class ScanManager { val = 2; break; case ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT: val = 4; val = maxTotalTrackableAdvertisements/2; break; default: val = 1; logd("Invalid setting for getNumOfMatches() " + settings.getNumOfMatches()); } // ToDo: Reserve few tracking advertisements in hw and report // or scale down the request based on ask and availibility. return val; } private boolean manageAllocationOfTrackingAdvertisement(int numOfTrackableAdvertisement, boolean allocate) { int maxTotalTrackableAdvertisements = AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements(); synchronized(curUsedTrackableAdvertisements) { int availableEntries = maxTotalTrackableAdvertisements - curUsedTrackableAdvertisements; if (allocate) { if (availableEntries >= numOfTrackableAdvertisement) { curUsedTrackableAdvertisements += numOfTrackableAdvertisement; return true; } else { return false; } } else { if (numOfTrackableAdvertisement > curUsedTrackableAdvertisements) { return false; } else { curUsedTrackableAdvertisements -= numOfTrackableAdvertisement; return true; } } } } /************************** Regular scan related native methods **************************/ private native void gattClientScanNative(boolean start); Loading Loading
android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +8 −0 Original line number Diff line number Diff line Loading @@ -260,6 +260,14 @@ class AdapterProperties { boolean isActivityAndEnergyReportingSupported() { return mIsActivityAndEnergyReporting; } /** * @return total number of trackable advertisements */ int getTotalNumOfTrackableAdvertisements() { return mTotNumOfTrackableAdv; } /** * @return the mBondedDevices */ Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +5 −8 Original line number Diff line number Diff line Loading @@ -1267,14 +1267,6 @@ public class AdapterService extends Service { return service.reportActivityInfo(); } public int numOfHwTrackFiltersAvailable() { AdapterService service = getService(); if (service == null) return 0; //ToDo: Accounting of how many filters hw can do, capability, //vs how many have been used by current filters by ScanManager return 5; } public String dump() { AdapterService service = getService(); if (service == null) { Loading Loading @@ -1896,6 +1888,11 @@ public class AdapterService extends Service { return info; } public int getTotalNumOfTrackableAdvertisements() { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); } private String dump() { StringBuilder sb = new StringBuilder(); synchronized (mProfiles) { Loading
android/app/src/com/android/bluetooth/gatt/GattService.java +21 −0 Original line number Diff line number Diff line Loading @@ -560,6 +560,13 @@ public class GattService extends ProfileService { if (service == null) return; service.unregAll(); } @Override public int numHwTrackFiltersAvailable() { GattService service = getService(); if (service == null) return 0; return service.numHwTrackFiltersAvailable(); } }; /************************************************************************** Loading Loading @@ -1194,6 +1201,16 @@ public class GattService extends ProfileService { app.callback.onMultiAdvertiseCallback(status, isStart, settings); } // callback from ScanManager for dispatch of errors apps. void onScanManagerErrorCallback(int clientIf, int errorCode) throws RemoteException { ClientMap.App app = mClientMap.getById(clientIf); if (app == null || app.callback == null) { Log.e(TAG, "App or callback is null"); return; } app.callback.onScanManagerErrorCallback(errorCode); } void onConfigureMTU(int connId, int status, int mtu) throws RemoteException { String address = mClientMap.addressByConnId(connId); Loading Loading @@ -1413,6 +1430,10 @@ public class GattService extends ProfileService { mAdvertiseManager.stopAdvertising(client); } int numHwTrackFiltersAvailable() { return (AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements() - mScanManager.getCurrentUsedTrackingAdvertisement()); } synchronized List<ParcelUuid> getRegisteredServiceUuids() { Utils.enforceAdminPermission(this); Loading
android/app/src/com/android/bluetooth/gatt/ScanManager.java +65 −6 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.gatt; import android.app.AlarmManager; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanSettings; import android.content.BroadcastReceiver; Loading @@ -29,6 +30,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; Loading Loading @@ -73,6 +75,7 @@ public class ScanManager { // Scan parameters for batch scan. private BatchScanParams mBatchScanParms; private Integer curUsedTrackableAdvertisements; private GattService mService; private BroadcastReceiver mBatchAlarmReceiver; private boolean mBatchAlarmReceiverRegistered; Loading Loading @@ -292,6 +295,10 @@ public class ScanManager { } } public int getCurrentUsedTrackingAdvertisement() { return curUsedTrackableAdvertisements; } private class ScanNative { // Delivery mode defined in bt stack. Loading Loading @@ -591,6 +598,22 @@ public class ScanManager { void stopRegularScan(ScanClient client) { // Remove scan filters and recycle filter indices. removeScanFilters(client.clientIf); int deliveryMode = getDeliveryMode(client); if (deliveryMode == DELIVERY_MODE_ON_FOUND_LOST) { for (ScanFilter filter : client.filters) { int entriesToFree = getNumOfTrackingAdvertisements(client.settings); if (!manageAllocationOfTrackingAdvertisement(entriesToFree, false)) { Log.e(TAG, "Error freeing for onfound/onlost filter resources " + entriesToFree); try { mService.onScanManagerErrorCallback(client.clientIf, ScanCallback.SCAN_FAILED_INTERNAL_ERROR); } catch (RemoteException e) { Log.e(TAG, "failed on onScanManagerCallback at freeing", e); } } } } mRegularScanClients.remove(client); if (numRegularScanClients() == 0) { logd("stop scan"); Loading Loading @@ -681,9 +704,15 @@ public class ScanManager { resetCountDownLatch(); if (deliveryMode == DELIVERY_MODE_ON_FOUND_LOST) { trackEntries = getNumOfTrackingAdvertisements(client.settings); if (trackEntries == 0) { Log.e(TAG, "No hardware resources for onfound/onlost filter"); return; if (!manageAllocationOfTrackingAdvertisement(trackEntries, true)) { Log.e(TAG, "No hardware resources for onfound/onlost filter " + trackEntries); try { mService.onScanManagerErrorCallback(clientIf, ScanCallback.SCAN_FAILED_INTERNAL_ERROR); } catch (RemoteException e) { Log.e(TAG, "failed on onScanManagerCallback", e); } } } configureFilterParamter(clientIf, client, featureSelection, filterIndex, Loading Loading @@ -934,6 +963,12 @@ public class ScanManager { if (settings == null) return 0; int val=0; int maxTotalTrackableAdvertisements = AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements(); // controller based onfound onlost resources are scarce commodity; the // assignment of filters to num of beacons to track is configurable based // on hw capabilities. Apps give an intent and allocation of onfound // resources or failure there of is done based on availibility - FCFS model switch (settings.getNumOfMatches()) { case ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT: val = 1; Loading @@ -942,16 +977,40 @@ public class ScanManager { val = 2; break; case ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT: val = 4; val = maxTotalTrackableAdvertisements/2; break; default: val = 1; logd("Invalid setting for getNumOfMatches() " + settings.getNumOfMatches()); } // ToDo: Reserve few tracking advertisements in hw and report // or scale down the request based on ask and availibility. return val; } private boolean manageAllocationOfTrackingAdvertisement(int numOfTrackableAdvertisement, boolean allocate) { int maxTotalTrackableAdvertisements = AdapterService.getAdapterService().getTotalNumOfTrackableAdvertisements(); synchronized(curUsedTrackableAdvertisements) { int availableEntries = maxTotalTrackableAdvertisements - curUsedTrackableAdvertisements; if (allocate) { if (availableEntries >= numOfTrackableAdvertisement) { curUsedTrackableAdvertisements += numOfTrackableAdvertisement; return true; } else { return false; } } else { if (numOfTrackableAdvertisement > curUsedTrackableAdvertisements) { return false; } else { curUsedTrackableAdvertisements -= numOfTrackableAdvertisement; return true; } } } } /************************** Regular scan related native methods **************************/ private native void gattClientScanNative(boolean start); Loading