Loading android/app/src/com/android/bluetooth/gatt/ScanManager.java +40 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.DisplayManager; import android.location.LocationManager; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading Loading @@ -102,6 +103,7 @@ public class ScanManager { private DisplayManager mDm; private ActivityManager mActivityManager; private LocationManager mLocationManager; private static final int FOREGROUND_IMPORTANCE_CUTOFF = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; Loading @@ -115,8 +117,6 @@ public class ScanManager { } } ; ScanManager(GattService service) { mRegularScanClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>()); Loading @@ -128,6 +128,7 @@ public class ScanManager { mCurUsedTrackableAdvertisements = 0; mDm = (DisplayManager) mService.getSystemService(Context.DISPLAY_SERVICE); mActivityManager = (ActivityManager) mService.getSystemService(Context.ACTIVITY_SERVICE); mLocationManager = (LocationManager) mService.getSystemService(Context.LOCATION_SERVICE); } void start() { Loading @@ -141,6 +142,8 @@ public class ScanManager { mActivityManager.addOnUidImportanceListener(mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF); } IntentFilter locationIntentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); mService.registerReceiver(mLocationReceiver, locationIntentFilter); } void cleanup() { Loading Loading @@ -170,6 +173,12 @@ public class ScanManager { } mHandler = null; } try { mService.unregisterReceiver(mLocationReceiver); } catch (IllegalArgumentException e) { Log.w(TAG, "exception when invoking unregisterReceiver(mLocationReceiver)", e); } } void registerScanner(UUID uuid) { Loading Loading @@ -313,6 +322,17 @@ public class ScanManager { return; } final boolean locationEnabled = mLocationManager.isLocationEnabled(); if (!locationEnabled && !isFiltered && !client.legacyForegroundApp) { Log.i(TAG, "Cannot start unfiltered scan in location-off. This scan will be" + " resumed when location is on: " + client.scannerId); mSuspendedScanClients.add(client); if (client.stats != null) { client.stats.recordScanSuspend(client.scannerId); } return; } // Begin scan operations. if (isBatchClient(client)) { mBatchClients.add(client); Loading Loading @@ -396,7 +416,7 @@ public class ScanManager { void handleSuspendScans() { for (ScanClient client : mRegularScanClients) { if (!mScanNative.isOpportunisticScanClient(client) && (client.filters == null || client.filters.isEmpty())) { || client.filters.isEmpty()) && !client.legacyForegroundApp) { /*Suspend unfiltered scans*/ if (client.stats != null) { client.stats.recordScanSuspend(client.scannerId); Loading Loading @@ -1303,7 +1323,7 @@ public class ScanManager { @Override public void onDisplayChanged(int displayId) { if (isScreenOn()) { if (isScreenOn() && mLocationManager.isLocationEnabled()) { sendMessage(MSG_RESUME_SCANS, null); } else { sendMessage(MSG_SUSPEND_SCANS, null); Loading @@ -1324,6 +1344,22 @@ public class ScanManager { } }; private BroadcastReceiver mLocationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { final boolean locationEnabled = mLocationManager.isLocationEnabled(); if (locationEnabled && isScreenOn()) { sendMessage(MSG_RESUME_SCANS, null); } else { sendMessage(MSG_SUSPEND_SCANS, null); } } } }; private void handleImportanceChange(UidImportance imp) { if (imp == null) { return; Loading android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +20 −0 Original line number Diff line number Diff line package com.android.bluetooth.gatt; import static org.mockito.Mockito.*; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; Loading @@ -26,6 +28,7 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidJUnit4.class) public class GattServiceTest { private static final int TIMES_UP_AND_DOWN = 3; private Context mTargetContext; private GattService mService; Loading Loading @@ -61,6 +64,23 @@ public class GattServiceTest { Assert.assertNotNull(GattService.getGattService()); } @Test public void testServiceUpAndDown() throws Exception { for (int i = 0; i < TIMES_UP_AND_DOWN; i++) { GattService gattService = GattService.getGattService(); TestUtils.stopService(mServiceRule, GattService.class); mService = GattService.getGattService(); Assert.assertNull(mService); gattService.cleanup(); TestUtils.clearAdapterService(mAdapterService); reset(mAdapterService); TestUtils.setAdapterService(mAdapterService); TestUtils.startService(mServiceRule, GattService.class); mService = GattService.getGattService(); Assert.assertNotNull(mService); } } @Test public void testParseBatchTimestamp() { long timestampNanos = mService.parseTimestampNanos(new byte[]{ Loading Loading
android/app/src/com/android/bluetooth/gatt/ScanManager.java +40 −4 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.DisplayManager; import android.location.LocationManager; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading Loading @@ -102,6 +103,7 @@ public class ScanManager { private DisplayManager mDm; private ActivityManager mActivityManager; private LocationManager mLocationManager; private static final int FOREGROUND_IMPORTANCE_CUTOFF = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; Loading @@ -115,8 +117,6 @@ public class ScanManager { } } ; ScanManager(GattService service) { mRegularScanClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>()); Loading @@ -128,6 +128,7 @@ public class ScanManager { mCurUsedTrackableAdvertisements = 0; mDm = (DisplayManager) mService.getSystemService(Context.DISPLAY_SERVICE); mActivityManager = (ActivityManager) mService.getSystemService(Context.ACTIVITY_SERVICE); mLocationManager = (LocationManager) mService.getSystemService(Context.LOCATION_SERVICE); } void start() { Loading @@ -141,6 +142,8 @@ public class ScanManager { mActivityManager.addOnUidImportanceListener(mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF); } IntentFilter locationIntentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); mService.registerReceiver(mLocationReceiver, locationIntentFilter); } void cleanup() { Loading Loading @@ -170,6 +173,12 @@ public class ScanManager { } mHandler = null; } try { mService.unregisterReceiver(mLocationReceiver); } catch (IllegalArgumentException e) { Log.w(TAG, "exception when invoking unregisterReceiver(mLocationReceiver)", e); } } void registerScanner(UUID uuid) { Loading Loading @@ -313,6 +322,17 @@ public class ScanManager { return; } final boolean locationEnabled = mLocationManager.isLocationEnabled(); if (!locationEnabled && !isFiltered && !client.legacyForegroundApp) { Log.i(TAG, "Cannot start unfiltered scan in location-off. This scan will be" + " resumed when location is on: " + client.scannerId); mSuspendedScanClients.add(client); if (client.stats != null) { client.stats.recordScanSuspend(client.scannerId); } return; } // Begin scan operations. if (isBatchClient(client)) { mBatchClients.add(client); Loading Loading @@ -396,7 +416,7 @@ public class ScanManager { void handleSuspendScans() { for (ScanClient client : mRegularScanClients) { if (!mScanNative.isOpportunisticScanClient(client) && (client.filters == null || client.filters.isEmpty())) { || client.filters.isEmpty()) && !client.legacyForegroundApp) { /*Suspend unfiltered scans*/ if (client.stats != null) { client.stats.recordScanSuspend(client.scannerId); Loading Loading @@ -1303,7 +1323,7 @@ public class ScanManager { @Override public void onDisplayChanged(int displayId) { if (isScreenOn()) { if (isScreenOn() && mLocationManager.isLocationEnabled()) { sendMessage(MSG_RESUME_SCANS, null); } else { sendMessage(MSG_SUSPEND_SCANS, null); Loading @@ -1324,6 +1344,22 @@ public class ScanManager { } }; private BroadcastReceiver mLocationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { final boolean locationEnabled = mLocationManager.isLocationEnabled(); if (locationEnabled && isScreenOn()) { sendMessage(MSG_RESUME_SCANS, null); } else { sendMessage(MSG_SUSPEND_SCANS, null); } } } }; private void handleImportanceChange(UidImportance imp) { if (imp == null) { return; Loading
android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +20 −0 Original line number Diff line number Diff line package com.android.bluetooth.gatt; import static org.mockito.Mockito.*; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; Loading @@ -26,6 +28,7 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidJUnit4.class) public class GattServiceTest { private static final int TIMES_UP_AND_DOWN = 3; private Context mTargetContext; private GattService mService; Loading Loading @@ -61,6 +64,23 @@ public class GattServiceTest { Assert.assertNotNull(GattService.getGattService()); } @Test public void testServiceUpAndDown() throws Exception { for (int i = 0; i < TIMES_UP_AND_DOWN; i++) { GattService gattService = GattService.getGattService(); TestUtils.stopService(mServiceRule, GattService.class); mService = GattService.getGattService(); Assert.assertNull(mService); gattService.cleanup(); TestUtils.clearAdapterService(mAdapterService); reset(mAdapterService); TestUtils.setAdapterService(mAdapterService); TestUtils.startService(mServiceRule, GattService.class); mService = GattService.getGattService(); Assert.assertNotNull(mService); } } @Test public void testParseBatchTimestamp() { long timestampNanos = mService.parseTimestampNanos(new byte[]{ Loading