Loading services/core/java/com/android/server/LocationManagerService.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -86,6 +86,7 @@ import com.android.server.location.ActivityRecognitionProxy; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; import com.android.server.location.GeofenceProxy; import com.android.server.location.GnssBatchingProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssMeasurementsProvider; import com.android.server.location.GnssMeasurementsProvider; import com.android.server.location.GnssNavigationMessageProvider; import com.android.server.location.GnssNavigationMessageProvider; Loading Loading @@ -244,7 +245,7 @@ public class LocationManagerService extends ILocationManager.Stub { private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider; private GnssBatchingProvider mGnssBatchingProvider; private IBatchedLocationCallback mGnssBatchingCallback; private IBatchedLocationCallback mGnssBatchingCallback; private LinkedCallback mGnssBatchingDeathCallback; private LinkedCallback mGnssBatchingDeathCallback; private boolean mGnssBatchingInProgress = false; private boolean mGnssBatchingInProgress = false; Loading Loading @@ -1176,7 +1177,7 @@ public class LocationManagerService extends ILocationManager.Stub { "Location Hardware permission not granted to access hardware batching"); "Location Hardware permission not granted to access hardware batching"); if (hasGnssPermissions(packageName) && mGnssBatchingProvider != null) { if (hasGnssPermissions(packageName) && mGnssBatchingProvider != null) { return mGnssBatchingProvider.getSize(); return mGnssBatchingProvider.getBatchSize(); } else { } else { return 0; return 0; } } Loading services/core/java/com/android/server/location/GnssBatchingProvider.java 0 → 100644 +145 −0 Original line number Original line Diff line number Diff line package com.android.server.location; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; /** * Manages GNSS Batching operations. * * <p>This class is not thread safe (It's client's responsibility to make sure calls happen on * the same thread). */ public class GnssBatchingProvider { private static final String TAG = "GnssBatchingProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final GnssBatchingProviderNative mNative; private boolean mEnabled; private boolean mStarted; private long mPeriodNanos; private boolean mWakeOnFifoFull; GnssBatchingProvider() { this(new GnssBatchingProviderNative()); } @VisibleForTesting GnssBatchingProvider(GnssBatchingProviderNative gnssBatchingProviderNative) { mNative = gnssBatchingProviderNative; } /** * Returns the GNSS batching size */ public int getBatchSize() { return mNative.getBatchSize(); } /** Enable GNSS batching. */ public void enable() { mEnabled = mNative.initBatching(); if (!mEnabled) { Log.e(TAG, "Failed to initialize GNSS batching"); } } /** * Starts the hardware batching operation */ public boolean start(long periodNanos, boolean wakeOnFifoFull) { if (!mEnabled) { throw new IllegalStateException(); } if (periodNanos <= 0) { Log.e(TAG, "Invalid periodNanos " + periodNanos + " in batching request, not started"); return false; } mStarted = mNative.startBatch(periodNanos, wakeOnFifoFull); if (mStarted) { mPeriodNanos = periodNanos; mWakeOnFifoFull = wakeOnFifoFull; } return mStarted; } /** * Forces a flush of existing locations from the hardware batching */ public void flush() { if (!mStarted) { Log.w(TAG, "Cannot flush since GNSS batching has not started."); return; } mNative.flushBatch(); } /** * Stops the batching operation */ public boolean stop() { boolean stopped = mNative.stopBatch(); if (stopped) { mStarted = false; } return stopped; } /** Disable GNSS batching. */ public void disable() { stop(); mNative.cleanupBatching(); mEnabled = false; } // TODO(b/37460011): Use this with death recovery logic. void resumeIfStarted() { if (DEBUG) { Log.d(TAG, "resumeIfStarted"); } if (mStarted) { mNative.startBatch(mPeriodNanos, mWakeOnFifoFull); } } @VisibleForTesting static class GnssBatchingProviderNative { public int getBatchSize() { return native_get_batch_size(); } public boolean startBatch(long periodNanos, boolean wakeOnFifoFull) { return native_start_batch(periodNanos, wakeOnFifoFull); } public void flushBatch() { native_flush_batch(); } public boolean stopBatch() { return native_stop_batch(); } public boolean initBatching() { return native_init_batching(); } public void cleanupBatching() { native_cleanup_batching(); } } private static native int native_get_batch_size(); private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull); private static native void native_flush_batch(); private static native boolean native_stop_batch(); private static native boolean native_init_batching(); private static native void native_cleanup_batching(); } services/core/java/com/android/server/location/GnssLocationProvider.java +5 −81 Original line number Original line Diff line number Diff line Loading @@ -418,6 +418,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener(); private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener(); private final LocationChangeListener mFusedLocationListener = new FusedLocationListener(); private final LocationChangeListener mFusedLocationListener = new FusedLocationListener(); private final NtpTimeHelper mNtpTimeHelper; private final NtpTimeHelper mNtpTimeHelper; private final GnssBatchingProvider mGnssBatchingProvider; // Handler for processing events // Handler for processing events private Handler mHandler; private Handler mHandler; Loading Loading @@ -885,6 +886,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext, mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext, looper, this); looper, this); mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist); mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist); mGnssBatchingProvider = new GnssBatchingProvider(); } } /** /** Loading Loading @@ -1267,7 +1269,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mGnssMeasurementsProvider.onGpsEnabledChanged(); mGnssMeasurementsProvider.onGpsEnabledChanged(); mGnssNavigationMessageProvider.onGpsEnabledChanged(); mGnssNavigationMessageProvider.onGpsEnabledChanged(); enableBatching(); mGnssBatchingProvider.enable(); } else { } else { synchronized (mLock) { synchronized (mLock) { mEnabled = false; mEnabled = false; Loading Loading @@ -1299,7 +1301,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mAlarmManager.cancel(mWakeupIntent); mAlarmManager.cancel(mWakeupIntent); mAlarmManager.cancel(mTimeoutIntent); mAlarmManager.cancel(mTimeoutIntent); disableBatching(); mGnssBatchingProvider.disable(); // do this before releasing wakelock // do this before releasing wakelock native_cleanup(); native_cleanup(); Loading Loading @@ -2001,58 +2003,11 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt }; }; } } public interface GnssBatchingProvider { /** * Returns the GNSS batching size */ int getSize(); /** * Starts the hardware batching operation */ boolean start(long periodNanos, boolean wakeOnFifoFull); /** * Forces a flush of existing locations from the hardware batching */ void flush(); /** * Stops the batching operation */ boolean stop(); } /** /** * @hide * @hide */ */ public GnssBatchingProvider getGnssBatchingProvider() { public GnssBatchingProvider getGnssBatchingProvider() { return new GnssBatchingProvider() { return mGnssBatchingProvider; @Override public int getSize() { return native_get_batch_size(); } @Override public boolean start(long periodNanos, boolean wakeOnFifoFull) { if (periodNanos <= 0) { Log.e(TAG, "Invalid periodNanos " + periodNanos + "in batching request, not started"); return false; } return native_start_batch(periodNanos, wakeOnFifoFull); } @Override public void flush() { native_flush_batch(); } @Override public boolean stop() { return native_stop_batch(); } }; } } public interface GnssMetricsProvider { public interface GnssMetricsProvider { Loading @@ -2074,23 +2029,6 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt }; }; } } /** * Initialize Batching if enabled */ private void enableBatching() { if (!native_init_batching()) { Log.e(TAG, "Failed to initialize GNSS batching"); } } /** * Disable batching */ private void disableBatching() { native_stop_batch(); native_cleanup_batching(); } /** /** * called from native code - GNSS location batch callback * called from native code - GNSS location batch callback */ */ Loading Loading @@ -2912,19 +2850,5 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds); private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds); // GNSS Batching private static native int native_get_batch_size(); private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull); private static native void native_flush_batch(); private static native boolean native_stop_batch(); private static native boolean native_init_batching(); private static native void native_cleanup_batching(); } } services/core/jni/com_android_server_location_GnssLocationProvider.cpp +21 −15 Original line number Original line Diff line number Diff line Loading @@ -2050,7 +2050,7 @@ static jboolean android_location_GnssLocationProvider_set_satellite_blacklist( } } static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) { static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return 0; // batching not supported, size = 0 return 0; // batching not supported, size = 0 } } Loading @@ -2062,7 +2062,7 @@ static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass } } } } static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) { static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return JNI_FALSE; // batching not supported return JNI_FALSE; // batching not supported } } Loading @@ -2071,14 +2071,14 @@ static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jcl return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface)); return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface)); } } static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) { static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return; // batching not supported return; // batching not supported } } gnssBatchingIface->cleanup(); gnssBatchingIface->cleanup(); } } static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass, static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass, jlong periodNanos, jboolean wakeOnFifoFull) { jlong periodNanos, jboolean wakeOnFifoFull) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return JNI_FALSE; // batching not supported return JNI_FALSE; // batching not supported Loading @@ -2095,7 +2095,7 @@ static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclas return static_cast<jboolean>(gnssBatchingIface->start(options)); return static_cast<jboolean>(gnssBatchingIface->start(options)); } } static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) { static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return; // batching not supported return; // batching not supported } } Loading @@ -2103,7 +2103,7 @@ static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) { gnssBatchingIface->flush(); gnssBatchingIface->flush(); } } static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) { static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return JNI_FALSE; // batching not supported return JNI_FALSE; // batching not supported } } Loading Loading @@ -2241,30 +2241,36 @@ static const JNINativeMethod sMethods[] = { {"native_set_satellite_blacklist", {"native_set_satellite_blacklist", "([I[I)Z", "([I[I)Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)}, reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)}, }; static const JNINativeMethod sMethodsBatching[] = { /* name, signature, funcPtr */ {"native_get_batch_size", {"native_get_batch_size", "()I", "()I", reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)}, {"native_init_batching", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)}, {"native_start_batch", {"native_start_batch", "(JZ)Z", "(JZ)Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)}, {"native_flush_batch", {"native_flush_batch", "()V", "()V", reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)}, {"native_stop_batch", {"native_stop_batch", "()Z", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)}, {"native_init_batching", {"native_init_batching", "()Z", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)}, {"native_cleanup_batching", {"native_cleanup_batching", "()V", "()V", reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)}, }; }; int register_android_server_location_GnssLocationProvider(JNIEnv* env) { int register_android_server_location_GnssLocationProvider(JNIEnv* env) { jniRegisterNativeMethods( env, "com/android/server/location/GnssBatchingProvider", sMethodsBatching, NELEM(sMethodsBatching)); return jniRegisterNativeMethods( return jniRegisterNativeMethods( env, env, "com/android/server/location/GnssLocationProvider", "com/android/server/location/GnssLocationProvider", Loading services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java 0 → 100644 +91 −0 Original line number Original line Diff line number Diff line package com.android.server.location; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.platform.test.annotations.Presubmit; import com.android.server.location.GnssBatchingProvider.GnssBatchingProviderNative; import com.android.server.testing.FrameworkRobolectricTestRunner; import com.android.server.testing.SystemLoaderPackages; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; /** * Unit tests for {@link GnssBatchingProvider}. */ @RunWith(FrameworkRobolectricTestRunner.class) @Config( manifest = Config.NONE, shadows = { }, sdk = 27 ) @SystemLoaderPackages({"com.android.server.location"}) @Presubmit public class GnssBatchingProviderTest { private static final long PERIOD_NANOS = (long) 1e9; private static final boolean WAKE_ON_FIFO_FULL = true; private static final int BATCH_SIZE = 3; @Mock private GnssBatchingProviderNative mMockNative; private GnssBatchingProvider mTestProvider; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mMockNative.initBatching()).thenReturn(true); when(mMockNative.startBatch(anyLong(), anyBoolean())).thenReturn(true); when(mMockNative.stopBatch()).thenReturn(true); when(mMockNative.getBatchSize()).thenReturn(BATCH_SIZE); mTestProvider = new GnssBatchingProvider(mMockNative); mTestProvider.enable(); mTestProvider.start(PERIOD_NANOS, WAKE_ON_FIFO_FULL); } @Test public void start_nativeStarted() { verify(mMockNative).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL)); } @Test public void stop_nativeStopped() { mTestProvider.stop(); verify(mMockNative).stopBatch(); } @Test public void flush_nativeFlushed() { mTestProvider.flush(); verify(mMockNative).flushBatch(); } @Test public void getBatchSize_nativeGetBatchSize() { assertThat(mTestProvider.getBatchSize()).isEqualTo(BATCH_SIZE); } @Test public void started_resume_started() { mTestProvider.resumeIfStarted(); verify(mMockNative, times(2)).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL)); } @Test public void stopped_resume_notStarted() { mTestProvider.stop(); mTestProvider.resumeIfStarted(); verify(mMockNative, times(1)).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL)); } } Loading
services/core/java/com/android/server/LocationManagerService.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -86,6 +86,7 @@ import com.android.server.location.ActivityRecognitionProxy; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; import com.android.server.location.GeofenceProxy; import com.android.server.location.GnssBatchingProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssMeasurementsProvider; import com.android.server.location.GnssMeasurementsProvider; import com.android.server.location.GnssNavigationMessageProvider; import com.android.server.location.GnssNavigationMessageProvider; Loading Loading @@ -244,7 +245,7 @@ public class LocationManagerService extends ILocationManager.Stub { private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider; private GnssBatchingProvider mGnssBatchingProvider; private IBatchedLocationCallback mGnssBatchingCallback; private IBatchedLocationCallback mGnssBatchingCallback; private LinkedCallback mGnssBatchingDeathCallback; private LinkedCallback mGnssBatchingDeathCallback; private boolean mGnssBatchingInProgress = false; private boolean mGnssBatchingInProgress = false; Loading Loading @@ -1176,7 +1177,7 @@ public class LocationManagerService extends ILocationManager.Stub { "Location Hardware permission not granted to access hardware batching"); "Location Hardware permission not granted to access hardware batching"); if (hasGnssPermissions(packageName) && mGnssBatchingProvider != null) { if (hasGnssPermissions(packageName) && mGnssBatchingProvider != null) { return mGnssBatchingProvider.getSize(); return mGnssBatchingProvider.getBatchSize(); } else { } else { return 0; return 0; } } Loading
services/core/java/com/android/server/location/GnssBatchingProvider.java 0 → 100644 +145 −0 Original line number Original line Diff line number Diff line package com.android.server.location; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; /** * Manages GNSS Batching operations. * * <p>This class is not thread safe (It's client's responsibility to make sure calls happen on * the same thread). */ public class GnssBatchingProvider { private static final String TAG = "GnssBatchingProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final GnssBatchingProviderNative mNative; private boolean mEnabled; private boolean mStarted; private long mPeriodNanos; private boolean mWakeOnFifoFull; GnssBatchingProvider() { this(new GnssBatchingProviderNative()); } @VisibleForTesting GnssBatchingProvider(GnssBatchingProviderNative gnssBatchingProviderNative) { mNative = gnssBatchingProviderNative; } /** * Returns the GNSS batching size */ public int getBatchSize() { return mNative.getBatchSize(); } /** Enable GNSS batching. */ public void enable() { mEnabled = mNative.initBatching(); if (!mEnabled) { Log.e(TAG, "Failed to initialize GNSS batching"); } } /** * Starts the hardware batching operation */ public boolean start(long periodNanos, boolean wakeOnFifoFull) { if (!mEnabled) { throw new IllegalStateException(); } if (periodNanos <= 0) { Log.e(TAG, "Invalid periodNanos " + periodNanos + " in batching request, not started"); return false; } mStarted = mNative.startBatch(periodNanos, wakeOnFifoFull); if (mStarted) { mPeriodNanos = periodNanos; mWakeOnFifoFull = wakeOnFifoFull; } return mStarted; } /** * Forces a flush of existing locations from the hardware batching */ public void flush() { if (!mStarted) { Log.w(TAG, "Cannot flush since GNSS batching has not started."); return; } mNative.flushBatch(); } /** * Stops the batching operation */ public boolean stop() { boolean stopped = mNative.stopBatch(); if (stopped) { mStarted = false; } return stopped; } /** Disable GNSS batching. */ public void disable() { stop(); mNative.cleanupBatching(); mEnabled = false; } // TODO(b/37460011): Use this with death recovery logic. void resumeIfStarted() { if (DEBUG) { Log.d(TAG, "resumeIfStarted"); } if (mStarted) { mNative.startBatch(mPeriodNanos, mWakeOnFifoFull); } } @VisibleForTesting static class GnssBatchingProviderNative { public int getBatchSize() { return native_get_batch_size(); } public boolean startBatch(long periodNanos, boolean wakeOnFifoFull) { return native_start_batch(periodNanos, wakeOnFifoFull); } public void flushBatch() { native_flush_batch(); } public boolean stopBatch() { return native_stop_batch(); } public boolean initBatching() { return native_init_batching(); } public void cleanupBatching() { native_cleanup_batching(); } } private static native int native_get_batch_size(); private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull); private static native void native_flush_batch(); private static native boolean native_stop_batch(); private static native boolean native_init_batching(); private static native void native_cleanup_batching(); }
services/core/java/com/android/server/location/GnssLocationProvider.java +5 −81 Original line number Original line Diff line number Diff line Loading @@ -418,6 +418,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener(); private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener(); private final LocationChangeListener mFusedLocationListener = new FusedLocationListener(); private final LocationChangeListener mFusedLocationListener = new FusedLocationListener(); private final NtpTimeHelper mNtpTimeHelper; private final NtpTimeHelper mNtpTimeHelper; private final GnssBatchingProvider mGnssBatchingProvider; // Handler for processing events // Handler for processing events private Handler mHandler; private Handler mHandler; Loading Loading @@ -885,6 +886,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext, mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext, looper, this); looper, this); mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist); mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist); mGnssBatchingProvider = new GnssBatchingProvider(); } } /** /** Loading Loading @@ -1267,7 +1269,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mGnssMeasurementsProvider.onGpsEnabledChanged(); mGnssMeasurementsProvider.onGpsEnabledChanged(); mGnssNavigationMessageProvider.onGpsEnabledChanged(); mGnssNavigationMessageProvider.onGpsEnabledChanged(); enableBatching(); mGnssBatchingProvider.enable(); } else { } else { synchronized (mLock) { synchronized (mLock) { mEnabled = false; mEnabled = false; Loading Loading @@ -1299,7 +1301,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt mAlarmManager.cancel(mWakeupIntent); mAlarmManager.cancel(mWakeupIntent); mAlarmManager.cancel(mTimeoutIntent); mAlarmManager.cancel(mTimeoutIntent); disableBatching(); mGnssBatchingProvider.disable(); // do this before releasing wakelock // do this before releasing wakelock native_cleanup(); native_cleanup(); Loading Loading @@ -2001,58 +2003,11 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt }; }; } } public interface GnssBatchingProvider { /** * Returns the GNSS batching size */ int getSize(); /** * Starts the hardware batching operation */ boolean start(long periodNanos, boolean wakeOnFifoFull); /** * Forces a flush of existing locations from the hardware batching */ void flush(); /** * Stops the batching operation */ boolean stop(); } /** /** * @hide * @hide */ */ public GnssBatchingProvider getGnssBatchingProvider() { public GnssBatchingProvider getGnssBatchingProvider() { return new GnssBatchingProvider() { return mGnssBatchingProvider; @Override public int getSize() { return native_get_batch_size(); } @Override public boolean start(long periodNanos, boolean wakeOnFifoFull) { if (periodNanos <= 0) { Log.e(TAG, "Invalid periodNanos " + periodNanos + "in batching request, not started"); return false; } return native_start_batch(periodNanos, wakeOnFifoFull); } @Override public void flush() { native_flush_batch(); } @Override public boolean stop() { return native_stop_batch(); } }; } } public interface GnssMetricsProvider { public interface GnssMetricsProvider { Loading @@ -2074,23 +2029,6 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt }; }; } } /** * Initialize Batching if enabled */ private void enableBatching() { if (!native_init_batching()) { Log.e(TAG, "Failed to initialize GNSS batching"); } } /** * Disable batching */ private void disableBatching() { native_stop_batch(); native_cleanup_batching(); } /** /** * called from native code - GNSS location batch callback * called from native code - GNSS location batch callback */ */ Loading Loading @@ -2912,19 +2850,5 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds); private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds); // GNSS Batching private static native int native_get_batch_size(); private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull); private static native void native_flush_batch(); private static native boolean native_stop_batch(); private static native boolean native_init_batching(); private static native void native_cleanup_batching(); } }
services/core/jni/com_android_server_location_GnssLocationProvider.cpp +21 −15 Original line number Original line Diff line number Diff line Loading @@ -2050,7 +2050,7 @@ static jboolean android_location_GnssLocationProvider_set_satellite_blacklist( } } static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) { static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return 0; // batching not supported, size = 0 return 0; // batching not supported, size = 0 } } Loading @@ -2062,7 +2062,7 @@ static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass } } } } static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) { static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return JNI_FALSE; // batching not supported return JNI_FALSE; // batching not supported } } Loading @@ -2071,14 +2071,14 @@ static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jcl return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface)); return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface)); } } static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) { static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return; // batching not supported return; // batching not supported } } gnssBatchingIface->cleanup(); gnssBatchingIface->cleanup(); } } static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass, static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass, jlong periodNanos, jboolean wakeOnFifoFull) { jlong periodNanos, jboolean wakeOnFifoFull) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return JNI_FALSE; // batching not supported return JNI_FALSE; // batching not supported Loading @@ -2095,7 +2095,7 @@ static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclas return static_cast<jboolean>(gnssBatchingIface->start(options)); return static_cast<jboolean>(gnssBatchingIface->start(options)); } } static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) { static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return; // batching not supported return; // batching not supported } } Loading @@ -2103,7 +2103,7 @@ static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) { gnssBatchingIface->flush(); gnssBatchingIface->flush(); } } static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) { static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { if (gnssBatchingIface == nullptr) { return JNI_FALSE; // batching not supported return JNI_FALSE; // batching not supported } } Loading Loading @@ -2241,30 +2241,36 @@ static const JNINativeMethod sMethods[] = { {"native_set_satellite_blacklist", {"native_set_satellite_blacklist", "([I[I)Z", "([I[I)Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)}, reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)}, }; static const JNINativeMethod sMethodsBatching[] = { /* name, signature, funcPtr */ {"native_get_batch_size", {"native_get_batch_size", "()I", "()I", reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)}, {"native_init_batching", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)}, {"native_start_batch", {"native_start_batch", "(JZ)Z", "(JZ)Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)}, {"native_flush_batch", {"native_flush_batch", "()V", "()V", reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)}, {"native_stop_batch", {"native_stop_batch", "()Z", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)}, {"native_init_batching", {"native_init_batching", "()Z", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)}, {"native_cleanup_batching", {"native_cleanup_batching", "()V", "()V", reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)}, reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)}, }; }; int register_android_server_location_GnssLocationProvider(JNIEnv* env) { int register_android_server_location_GnssLocationProvider(JNIEnv* env) { jniRegisterNativeMethods( env, "com/android/server/location/GnssBatchingProvider", sMethodsBatching, NELEM(sMethodsBatching)); return jniRegisterNativeMethods( return jniRegisterNativeMethods( env, env, "com/android/server/location/GnssLocationProvider", "com/android/server/location/GnssLocationProvider", Loading
services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java 0 → 100644 +91 −0 Original line number Original line Diff line number Diff line package com.android.server.location; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.platform.test.annotations.Presubmit; import com.android.server.location.GnssBatchingProvider.GnssBatchingProviderNative; import com.android.server.testing.FrameworkRobolectricTestRunner; import com.android.server.testing.SystemLoaderPackages; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; /** * Unit tests for {@link GnssBatchingProvider}. */ @RunWith(FrameworkRobolectricTestRunner.class) @Config( manifest = Config.NONE, shadows = { }, sdk = 27 ) @SystemLoaderPackages({"com.android.server.location"}) @Presubmit public class GnssBatchingProviderTest { private static final long PERIOD_NANOS = (long) 1e9; private static final boolean WAKE_ON_FIFO_FULL = true; private static final int BATCH_SIZE = 3; @Mock private GnssBatchingProviderNative mMockNative; private GnssBatchingProvider mTestProvider; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mMockNative.initBatching()).thenReturn(true); when(mMockNative.startBatch(anyLong(), anyBoolean())).thenReturn(true); when(mMockNative.stopBatch()).thenReturn(true); when(mMockNative.getBatchSize()).thenReturn(BATCH_SIZE); mTestProvider = new GnssBatchingProvider(mMockNative); mTestProvider.enable(); mTestProvider.start(PERIOD_NANOS, WAKE_ON_FIFO_FULL); } @Test public void start_nativeStarted() { verify(mMockNative).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL)); } @Test public void stop_nativeStopped() { mTestProvider.stop(); verify(mMockNative).stopBatch(); } @Test public void flush_nativeFlushed() { mTestProvider.flush(); verify(mMockNative).flushBatch(); } @Test public void getBatchSize_nativeGetBatchSize() { assertThat(mTestProvider.getBatchSize()).isEqualTo(BATCH_SIZE); } @Test public void started_resume_started() { mTestProvider.resumeIfStarted(); verify(mMockNative, times(2)).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL)); } @Test public void stopped_resume_notStarted() { mTestProvider.stop(); mTestProvider.resumeIfStarted(); verify(mMockNative, times(1)).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL)); } }