diff --git a/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManager.java b/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManager.java index 0c4142657c..5797d3d25b 100644 --- a/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManager.java +++ b/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManager.java @@ -21,6 +21,7 @@ import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_PRESENCE; import static com.android.server.nearby.NearbyService.TAG; import android.annotation.Nullable; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.nearby.DataElement; import android.nearby.IScanListener; @@ -141,6 +142,8 @@ public class DiscoveryProviderManager extends /** Called after boot completed. */ public void init() { + // Register BLE only scan when Bluetooth is turned off + setBleScanEnabled(); if (mInjector.getContextHubManager() != null) { mChreDiscoveryProvider.init(); } @@ -313,4 +316,29 @@ public class DiscoveryProviderManager extends public void onMergedRegistrationsUpdated() { invalidateProviderScanMode(); } + + /** + * Registers Nearby service to Ble scan if Bluetooth is off. (Even when Bluetooth is off) + * @return {@code true} when Nearby currently can scan through Bluetooth or Ble or successfully + * registers Nearby service to Ble scan when Blutooth is off. + */ + public boolean setBleScanEnabled() { + BluetoothAdapter adapter = mInjector.getBluetoothAdapter(); + if (adapter == null) { + Log.e(TAG, "BluetoothAdapter is null."); + return false; + } + if (adapter.isEnabled() || adapter.isLeEnabled()) { + return true; + } + if (!adapter.isBleScanAlwaysAvailable()) { + Log.v(TAG, "Ble always on scan is disabled."); + return false; + } + if (!adapter.enableBLE()) { + Log.e(TAG, "Failed to register Ble scan."); + return false; + } + return true; + } } diff --git a/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManagerLegacy.java b/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManagerLegacy.java index 4b76eba888..df33773278 100644 --- a/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManagerLegacy.java +++ b/nearby/service/java/com/android/server/nearby/managers/DiscoveryProviderManagerLegacy.java @@ -22,6 +22,7 @@ import static com.android.server.nearby.NearbyService.TAG; import android.annotation.Nullable; import android.app.AppOpsManager; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.nearby.DataElement; import android.nearby.IScanListener; @@ -220,6 +221,8 @@ public class DiscoveryProviderManagerLegacy implements AbstractDiscoveryProvider /** Called after boot completed. */ public void init() { + // Register BLE only scan when Bluetooth is turned off + setBleScanEnabled(); if (mInjector.getContextHubManager() != null) { mChreDiscoveryProvider.init(); } @@ -503,4 +506,29 @@ public class DiscoveryProviderManagerLegacy implements AbstractDiscoveryProvider unregisterScanListener(listener); } } + + /** + * Registers Nearby service to Ble scan if Bluetooth is off. (Even when Bluetooth is off) + * @return {@code true} when Nearby currently can scan through Bluetooth or Ble or successfully + * registers Nearby service to Ble scan when Blutooth is off. + */ + public boolean setBleScanEnabled() { + BluetoothAdapter adapter = mInjector.getBluetoothAdapter(); + if (adapter == null) { + Log.e(TAG, "BluetoothAdapter is null."); + return false; + } + if (adapter.isEnabled() || adapter.isLeEnabled()) { + return true; + } + if (!adapter.isBleScanAlwaysAvailable()) { + Log.v(TAG, "Ble always on scan is disabled."); + return false; + } + if (!adapter.enableBLE()) { + Log.e(TAG, "Failed to register Ble scan."); + return false; + } + return true; + } } diff --git a/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerLegacyTest.java b/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerLegacyTest.java index aa0dad328c..a8c30a86a9 100644 --- a/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerLegacyTest.java +++ b/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerLegacyTest.java @@ -23,10 +23,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.nearby.DataElement; import android.nearby.IScanListener; @@ -86,6 +88,8 @@ public class DiscoveryProviderManagerLegacyTest { DiscoveryProviderManagerLegacy.ScanListenerDeathRecipient mScanListenerDeathRecipient; @Mock IBinder mIBinder; + @Mock + BluetoothAdapter mBluetoothAdapter; private DiscoveryProviderManagerLegacy mDiscoveryProviderManager; private Map mScanTypeScanListenerRecordMap; @@ -137,8 +141,11 @@ public class DiscoveryProviderManagerLegacyTest { public void setup() { MockitoAnnotations.initMocks(this); when(mInjector.getAppOpsManager()).thenReturn(mAppOpsManager); + when(mInjector.getBluetoothAdapter()).thenReturn(mBluetoothAdapter); when(mBleDiscoveryProvider.getController()).thenReturn(mBluetoothController); when(mChreDiscoveryProvider.getController()).thenReturn(mChreController); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.isEnabled()).thenReturn(true); mScanTypeScanListenerRecordMap = new HashMap<>(); mDiscoveryProviderManager = @@ -163,6 +170,13 @@ public class DiscoveryProviderManagerLegacyTest { mDiscoveryProviderManager.invalidateProviderScanMode(); } + @Test + public void test_enableBleWhenBleOff() throws Exception { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + mDiscoveryProviderManager.init(); + verify(mBluetoothAdapter, times(1)).enableBLE(); + } + @Test public void testStartProviders_chreOnlyChreAvailable_bleProviderNotStarted() { when(mChreDiscoveryProvider.available()).thenReturn(true); @@ -375,4 +389,62 @@ public class DiscoveryProviderManagerLegacyTest { .isTrue(); assertThat(manager.mChreDiscoveryProvider.getFiltersLocked()).isNotNull(); } + + @Test + public void isBluetoothEnabledTest_bluetoothEnabled() { + when(mBluetoothAdapter.isEnabled()).thenReturn(true); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(true); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void isBluetoothEnabledTest_bleEnabled() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(true); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(true); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void enabledTest_enabled() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(true); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void enabledTest_enableFailed() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(false); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isFalse(); + } + + @Test + public void enabledTest_scanIsOn() { + when(mBluetoothAdapter.isEnabled()).thenReturn(true); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(false); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void enabledTest_failed() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(false); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isFalse(); + } } diff --git a/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerTest.java index 7ecf631df3..b05893fa4d 100644 --- a/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerTest.java +++ b/nearby/tests/unit/src/com/android/server/nearby/managers/DiscoveryProviderManagerTest.java @@ -24,10 +24,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.nearby.DataElement; import android.nearby.IScanListener; @@ -80,6 +82,8 @@ public class DiscoveryProviderManagerTest { CallerIdentity mCallerIdentity; @Mock IBinder mIBinder; + @Mock + BluetoothAdapter mBluetoothAdapter; private Executor mExecutor; private DiscoveryProviderManager mDiscoveryProviderManager; @@ -134,6 +138,9 @@ public class DiscoveryProviderManagerTest { when(mBleDiscoveryProvider.getController()).thenReturn(mBluetoothController); when(mChreDiscoveryProvider.getController()).thenReturn(mChreController); when(mScanListener.asBinder()).thenReturn(mIBinder); + when(mInjector.getBluetoothAdapter()).thenReturn(mBluetoothAdapter); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.isEnabled()).thenReturn(true); mDiscoveryProviderManager = new DiscoveryProviderManager(mContext, mExecutor, mInjector, @@ -156,6 +163,13 @@ public class DiscoveryProviderManagerTest { mDiscoveryProviderManager.invalidateProviderScanMode(); } + @Test + public void test_enableBleWhenBleOff() throws Exception { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + mDiscoveryProviderManager.init(); + verify(mBluetoothAdapter, times(1)).enableBLE(); + } + @Test public void testStartProviders_chreOnlyChreAvailable_bleProviderNotStarted() { reset(mBluetoothController); @@ -336,4 +350,62 @@ public class DiscoveryProviderManagerTest { .isTrue(); assertThat(manager.mChreDiscoveryProvider.getFiltersLocked()).isNotNull(); } + + @Test + public void isBluetoothEnabledTest_bluetoothEnabled() { + when(mBluetoothAdapter.isEnabled()).thenReturn(true); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(true); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void isBluetoothEnabledTest_bleEnabled() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(true); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(true); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void enabledTest_enabled() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(true); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void enabledTest_enableFailed() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(true); + when(mBluetoothAdapter.enableBLE()).thenReturn(false); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isFalse(); + } + + @Test + public void enabledTest_scanIsOn() { + when(mBluetoothAdapter.isEnabled()).thenReturn(true); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(false); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isTrue(); + } + + @Test + public void enabledTest_failed() { + when(mBluetoothAdapter.isEnabled()).thenReturn(false); + when(mBluetoothAdapter.isLeEnabled()).thenReturn(false); + when(mBluetoothAdapter.isBleScanAlwaysAvailable()).thenReturn(false); + + assertThat(mDiscoveryProviderManager.setBleScanEnabled()).isFalse(); + } }