Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +44 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.bluetooth.btservice; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.bluetooth.Utils.addressToBytes; import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser; import static com.android.bluetooth.Utils.callerIsSystemOrActiveUser; Loading Loading @@ -3609,6 +3612,13 @@ public class AdapterService extends Service { @GuardedBy("mDeviceConfigLock") private Predicate<byte[]> mLocationDenylistAdvertisingData = (v) -> false; @GuardedBy("mDeviceConfigLock") private int mScanQuotaCount = DeviceConfigListener.DEFAULT_SCAN_QUOTA_COUNT; @GuardedBy("mDeviceConfigLock") private long mScanQuotaWindowMillis = DeviceConfigListener.DEFAULT_SCAN_QUOTA_WINDOW_MILLIS; @GuardedBy("mDeviceConfigLock") private long mScanTimeoutMillis = DeviceConfigListener.DEFAULT_SCAN_TIMEOUT_MILLIS; public @NonNull Predicate<String> getLocationDenylistName() { synchronized (mDeviceConfigLock) { return mLocationDenylistName; Loading @@ -3627,6 +3637,24 @@ public class AdapterService extends Service { } } public int getScanQuotaCount() { synchronized (mDeviceConfigLock) { return mScanQuotaCount; } } public long getScanQuotaWindowMillis() { synchronized (mDeviceConfigLock) { return mScanQuotaWindowMillis; } } public long getScanTimeoutMillis() { synchronized (mDeviceConfigLock) { return mScanTimeoutMillis; } } private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener(); private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener { Loading @@ -3636,6 +3664,12 @@ public class AdapterService extends Service { "location_denylist_mac"; private static final String LOCATION_DENYLIST_ADVERTISING_DATA = "location_denylist_advertising_data"; private static final String SCAN_QUOTA_COUNT = "scan_quota_count"; private static final String SCAN_QUOTA_WINDOW_MILLIS = "scan_quota_window_millis"; private static final String SCAN_TIMEOUT_MILLIS = "scan_timeout_millis"; /** * Default denylist which matches Eddystone and iBeacon payloads. Loading @@ -3643,6 +3677,10 @@ public class AdapterService extends Service { private static final String DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA = "⊆0016AAFE/00FFFFFF,⊆00FF4C0002/00FFFFFFFF"; private static final int DEFAULT_SCAN_QUOTA_COUNT = 5; private static final long DEFAULT_SCAN_QUOTA_WINDOW_MILLIS = 30 * SECOND_IN_MILLIS; private static final long DEFAULT_SCAN_TIMEOUT_MILLIS = 30 * MINUTE_IN_MILLIS; public void start() { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BLUETOOTH, BackgroundThread.getExecutor(), this); Loading @@ -3661,6 +3699,12 @@ public class AdapterService extends Service { mLocationDenylistAdvertisingData = BytesMatcher .decode(properties.getString(LOCATION_DENYLIST_ADVERTISING_DATA, DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA)); mScanQuotaCount = properties.getInt(SCAN_QUOTA_COUNT, DEFAULT_SCAN_QUOTA_COUNT); mScanQuotaWindowMillis = properties.getLong(SCAN_QUOTA_WINDOW_MILLIS, DEFAULT_SCAN_QUOTA_WINDOW_MILLIS); mScanTimeoutMillis = properties.getLong(SCAN_TIMEOUT_MILLIS, DEFAULT_SCAN_TIMEOUT_MILLIS); } } } Loading android/app/src/com/android/bluetooth/gatt/AppScanStats.java +15 −8 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.WorkSource; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.AdapterService; import com.android.internal.app.IBatteryStats; import java.text.DateFormat; Loading Loading @@ -101,16 +102,22 @@ import java.util.Objects; } } static final int NUM_SCAN_DURATIONS_KEPT = 5; static int getNumScanDurationsKept() { return AdapterService.getAdapterService().getScanQuotaCount(); } // This constant defines the time window an app can scan multiple times. // Any single app can scan up to |NUM_SCAN_DURATIONS_KEPT| times during // this window. Once they reach this limit, they must wait until their // earliest recorded scan exits this window. static final long EXCESSIVE_SCANNING_PERIOD_MS = 30 * 1000; static long getExcessiveScanningPeriodMillis() { return AdapterService.getAdapterService().getScanQuotaWindowMillis(); } // Maximum msec before scan gets downgraded to opportunistic static final int SCAN_TIMEOUT_MS = 30 * 60 * 1000; static long getScanTimeoutMillis() { return AdapterService.getAdapterService().getScanTimeoutMillis(); } public String appName; public WorkSource mWorkSource; // Used for BatteryStats and BluetoothStatsLog Loading @@ -131,7 +138,7 @@ import java.util.Objects; private int mBalancedScan = 0; private int mLowLantencyScan = 0; private int mAmbientDiscoveryScan = 0; private List<LastScan> mLastScans = new ArrayList<LastScan>(NUM_SCAN_DURATIONS_KEPT); private List<LastScan> mLastScans = new ArrayList<LastScan>(); private HashMap<Integer, LastScan> mOngoingScans = new HashMap<Integer, LastScan>(); public long startTime = 0; public long stopTime = 0; Loading Loading @@ -263,7 +270,7 @@ import java.util.Objects; mTotalSuspendTime += suspendDuration; } mOngoingScans.remove(scannerId); if (mLastScans.size() >= NUM_SCAN_DURATIONS_KEPT) { if (mLastScans.size() >= getNumScanDurationsKept()) { mLastScans.remove(0); } mLastScans.add(scan); Loading Loading @@ -349,19 +356,19 @@ import java.util.Objects; } synchronized boolean isScanningTooFrequently() { if (mLastScans.size() < NUM_SCAN_DURATIONS_KEPT) { if (mLastScans.size() < getNumScanDurationsKept()) { return false; } return (SystemClock.elapsedRealtime() - mLastScans.get(0).timestamp) < EXCESSIVE_SCANNING_PERIOD_MS; < getExcessiveScanningPeriodMillis(); } synchronized boolean isScanningTooLong() { if (!isScanning()) { return false; } return (SystemClock.elapsedRealtime() - mScanStartTime) > SCAN_TIMEOUT_MS; return (SystemClock.elapsedRealtime() - mScanStartTime) > getScanTimeoutMillis(); } // This function truncates the app name for privacy reasons. Apps with Loading android/app/src/com/android/bluetooth/gatt/ScanManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -357,7 +357,7 @@ public class ScanManager { Message msg = obtainMessage(MSG_SCAN_TIMEOUT); msg.obj = client; // Only one timeout message should exist at any time sendMessageDelayed(msg, AppScanStats.SCAN_TIMEOUT_MS); sendMessageDelayed(msg, AppScanStats.getScanTimeoutMillis()); } } } Loading android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +2 −2 Original line number Diff line number Diff line Loading @@ -314,8 +314,6 @@ public class BluetoothInCallService extends InCallService { public BluetoothInCallService() { Log.i(TAG, "BluetoothInCallService is created"); BluetoothAdapter.getDefaultAdapter() .getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); sInstance = this; } Loading Loading @@ -535,6 +533,8 @@ public class BluetoothInCallService extends InCallService { public void onCreate() { Log.d(TAG, "onCreate"); super.onCreate(); BluetoothAdapter.getDefaultAdapter() .getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); mBluetoothAdapterReceiver = new BluetoothAdapterReceiver(); IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(mBluetoothAdapterReceiver, intentFilter); Loading Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +44 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.bluetooth.btservice; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.bluetooth.Utils.addressToBytes; import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser; import static com.android.bluetooth.Utils.callerIsSystemOrActiveUser; Loading Loading @@ -3609,6 +3612,13 @@ public class AdapterService extends Service { @GuardedBy("mDeviceConfigLock") private Predicate<byte[]> mLocationDenylistAdvertisingData = (v) -> false; @GuardedBy("mDeviceConfigLock") private int mScanQuotaCount = DeviceConfigListener.DEFAULT_SCAN_QUOTA_COUNT; @GuardedBy("mDeviceConfigLock") private long mScanQuotaWindowMillis = DeviceConfigListener.DEFAULT_SCAN_QUOTA_WINDOW_MILLIS; @GuardedBy("mDeviceConfigLock") private long mScanTimeoutMillis = DeviceConfigListener.DEFAULT_SCAN_TIMEOUT_MILLIS; public @NonNull Predicate<String> getLocationDenylistName() { synchronized (mDeviceConfigLock) { return mLocationDenylistName; Loading @@ -3627,6 +3637,24 @@ public class AdapterService extends Service { } } public int getScanQuotaCount() { synchronized (mDeviceConfigLock) { return mScanQuotaCount; } } public long getScanQuotaWindowMillis() { synchronized (mDeviceConfigLock) { return mScanQuotaWindowMillis; } } public long getScanTimeoutMillis() { synchronized (mDeviceConfigLock) { return mScanTimeoutMillis; } } private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener(); private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener { Loading @@ -3636,6 +3664,12 @@ public class AdapterService extends Service { "location_denylist_mac"; private static final String LOCATION_DENYLIST_ADVERTISING_DATA = "location_denylist_advertising_data"; private static final String SCAN_QUOTA_COUNT = "scan_quota_count"; private static final String SCAN_QUOTA_WINDOW_MILLIS = "scan_quota_window_millis"; private static final String SCAN_TIMEOUT_MILLIS = "scan_timeout_millis"; /** * Default denylist which matches Eddystone and iBeacon payloads. Loading @@ -3643,6 +3677,10 @@ public class AdapterService extends Service { private static final String DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA = "⊆0016AAFE/00FFFFFF,⊆00FF4C0002/00FFFFFFFF"; private static final int DEFAULT_SCAN_QUOTA_COUNT = 5; private static final long DEFAULT_SCAN_QUOTA_WINDOW_MILLIS = 30 * SECOND_IN_MILLIS; private static final long DEFAULT_SCAN_TIMEOUT_MILLIS = 30 * MINUTE_IN_MILLIS; public void start() { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BLUETOOTH, BackgroundThread.getExecutor(), this); Loading @@ -3661,6 +3699,12 @@ public class AdapterService extends Service { mLocationDenylistAdvertisingData = BytesMatcher .decode(properties.getString(LOCATION_DENYLIST_ADVERTISING_DATA, DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA)); mScanQuotaCount = properties.getInt(SCAN_QUOTA_COUNT, DEFAULT_SCAN_QUOTA_COUNT); mScanQuotaWindowMillis = properties.getLong(SCAN_QUOTA_WINDOW_MILLIS, DEFAULT_SCAN_QUOTA_WINDOW_MILLIS); mScanTimeoutMillis = properties.getLong(SCAN_TIMEOUT_MILLIS, DEFAULT_SCAN_TIMEOUT_MILLIS); } } } Loading
android/app/src/com/android/bluetooth/gatt/AppScanStats.java +15 −8 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.WorkSource; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.AdapterService; import com.android.internal.app.IBatteryStats; import java.text.DateFormat; Loading Loading @@ -101,16 +102,22 @@ import java.util.Objects; } } static final int NUM_SCAN_DURATIONS_KEPT = 5; static int getNumScanDurationsKept() { return AdapterService.getAdapterService().getScanQuotaCount(); } // This constant defines the time window an app can scan multiple times. // Any single app can scan up to |NUM_SCAN_DURATIONS_KEPT| times during // this window. Once they reach this limit, they must wait until their // earliest recorded scan exits this window. static final long EXCESSIVE_SCANNING_PERIOD_MS = 30 * 1000; static long getExcessiveScanningPeriodMillis() { return AdapterService.getAdapterService().getScanQuotaWindowMillis(); } // Maximum msec before scan gets downgraded to opportunistic static final int SCAN_TIMEOUT_MS = 30 * 60 * 1000; static long getScanTimeoutMillis() { return AdapterService.getAdapterService().getScanTimeoutMillis(); } public String appName; public WorkSource mWorkSource; // Used for BatteryStats and BluetoothStatsLog Loading @@ -131,7 +138,7 @@ import java.util.Objects; private int mBalancedScan = 0; private int mLowLantencyScan = 0; private int mAmbientDiscoveryScan = 0; private List<LastScan> mLastScans = new ArrayList<LastScan>(NUM_SCAN_DURATIONS_KEPT); private List<LastScan> mLastScans = new ArrayList<LastScan>(); private HashMap<Integer, LastScan> mOngoingScans = new HashMap<Integer, LastScan>(); public long startTime = 0; public long stopTime = 0; Loading Loading @@ -263,7 +270,7 @@ import java.util.Objects; mTotalSuspendTime += suspendDuration; } mOngoingScans.remove(scannerId); if (mLastScans.size() >= NUM_SCAN_DURATIONS_KEPT) { if (mLastScans.size() >= getNumScanDurationsKept()) { mLastScans.remove(0); } mLastScans.add(scan); Loading Loading @@ -349,19 +356,19 @@ import java.util.Objects; } synchronized boolean isScanningTooFrequently() { if (mLastScans.size() < NUM_SCAN_DURATIONS_KEPT) { if (mLastScans.size() < getNumScanDurationsKept()) { return false; } return (SystemClock.elapsedRealtime() - mLastScans.get(0).timestamp) < EXCESSIVE_SCANNING_PERIOD_MS; < getExcessiveScanningPeriodMillis(); } synchronized boolean isScanningTooLong() { if (!isScanning()) { return false; } return (SystemClock.elapsedRealtime() - mScanStartTime) > SCAN_TIMEOUT_MS; return (SystemClock.elapsedRealtime() - mScanStartTime) > getScanTimeoutMillis(); } // This function truncates the app name for privacy reasons. Apps with Loading
android/app/src/com/android/bluetooth/gatt/ScanManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -357,7 +357,7 @@ public class ScanManager { Message msg = obtainMessage(MSG_SCAN_TIMEOUT); msg.obj = client; // Only one timeout message should exist at any time sendMessageDelayed(msg, AppScanStats.SCAN_TIMEOUT_MS); sendMessageDelayed(msg, AppScanStats.getScanTimeoutMillis()); } } } Loading
android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +2 −2 Original line number Diff line number Diff line Loading @@ -314,8 +314,6 @@ public class BluetoothInCallService extends InCallService { public BluetoothInCallService() { Log.i(TAG, "BluetoothInCallService is created"); BluetoothAdapter.getDefaultAdapter() .getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); sInstance = this; } Loading Loading @@ -535,6 +533,8 @@ public class BluetoothInCallService extends InCallService { public void onCreate() { Log.d(TAG, "onCreate"); super.onCreate(); BluetoothAdapter.getDefaultAdapter() .getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); mBluetoothAdapterReceiver = new BluetoothAdapterReceiver(); IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(mBluetoothAdapterReceiver, intentFilter); Loading