Merge "Refactor GnssMeasurementsProvider" into pi-dev
This commit is contained in:
@@ -818,37 +818,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
||||
}
|
||||
};
|
||||
|
||||
mGnssMeasurementsProvider = new GnssMeasurementsProvider(mHandler) {
|
||||
@Override
|
||||
public boolean isAvailableInPlatform() {
|
||||
return native_is_measurement_supported();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int registerWithService() {
|
||||
int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0);
|
||||
int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING , 0);
|
||||
boolean result = false;
|
||||
if (devOptions == 1 /* Developer Mode enabled */
|
||||
&& fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */) {
|
||||
result = native_start_measurement_collection(true /* enableFullTracking */);
|
||||
} else {
|
||||
result = native_start_measurement_collection(false /* enableFullTracking */);
|
||||
}
|
||||
if (result) {
|
||||
return RemoteListenerHelper.RESULT_SUCCESS;
|
||||
} else {
|
||||
return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unregisterFromService() {
|
||||
native_stop_measurement_collection();
|
||||
}
|
||||
|
||||
mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
|
||||
@Override
|
||||
protected boolean isGpsEnabled() {
|
||||
return isEnabled();
|
||||
@@ -1032,7 +1002,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
||||
Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleRequestLocation(boolean independentFromGnss) {
|
||||
if (isRequestLocationRateLimited()) {
|
||||
if (DEBUG) {
|
||||
@@ -2790,13 +2760,6 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
||||
private native void native_update_network_state(boolean connected, int type,
|
||||
boolean roaming, boolean available, String extraInfo, String defaultAPN);
|
||||
|
||||
// Gps Hal measurements support.
|
||||
private static native boolean native_is_measurement_supported();
|
||||
|
||||
private native boolean native_start_measurement_collection(boolean enableFullTracking);
|
||||
|
||||
private native boolean native_stop_measurement_collection();
|
||||
|
||||
// Gps Navigation message support.
|
||||
private static native boolean native_is_navigation_message_supported();
|
||||
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.GnssMeasurementsEvent;
|
||||
import android.location.IGnssMeasurementsListener;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* An base implementation for GPS measurements provider.
|
||||
* It abstracts out the responsibility of handling listeners, while still allowing technology
|
||||
@@ -29,22 +33,73 @@ import android.util.Log;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class GnssMeasurementsProvider
|
||||
extends RemoteListenerHelper<IGnssMeasurementsListener> {
|
||||
public abstract class GnssMeasurementsProvider extends
|
||||
RemoteListenerHelper<IGnssMeasurementsListener> {
|
||||
private static final String TAG = "GnssMeasurementsProvider";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
protected GnssMeasurementsProvider(Handler handler) {
|
||||
private final Context mContext;
|
||||
private final GnssMeasurementProviderNative mNative;
|
||||
|
||||
private boolean mIsCollectionStarted;
|
||||
private boolean mEnableFullTracking;
|
||||
|
||||
protected GnssMeasurementsProvider(Context context, Handler handler) {
|
||||
this(context, handler, new GnssMeasurementProviderNative());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
GnssMeasurementsProvider(Context context, Handler handler,
|
||||
GnssMeasurementProviderNative aNative) {
|
||||
super(handler, TAG);
|
||||
mContext = context;
|
||||
mNative = aNative;
|
||||
}
|
||||
|
||||
// TODO(b/37460011): Use this with death recovery logic.
|
||||
void resumeIfStarted() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "resumeIfStarted");
|
||||
}
|
||||
if (mIsCollectionStarted) {
|
||||
mNative.startMeasurementCollection(mEnableFullTracking);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailableInPlatform() {
|
||||
return mNative.isMeasurementSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int registerWithService() {
|
||||
int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
|
||||
int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, 0);
|
||||
boolean enableFullTracking = (devOptions == 1 /* Developer Mode enabled */)
|
||||
&& (fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */);
|
||||
boolean result = mNative.startMeasurementCollection(enableFullTracking);
|
||||
if (result) {
|
||||
mIsCollectionStarted = true;
|
||||
mEnableFullTracking = enableFullTracking;
|
||||
return RemoteListenerHelper.RESULT_SUCCESS;
|
||||
} else {
|
||||
return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unregisterFromService() {
|
||||
boolean stopped = mNative.stopMeasurementCollection();
|
||||
if (stopped) {
|
||||
mIsCollectionStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
|
||||
ListenerOperation<IGnssMeasurementsListener> operation =
|
||||
new ListenerOperation<IGnssMeasurementsListener>() {
|
||||
@Override
|
||||
public void execute(IGnssMeasurementsListener listener) throws RemoteException {
|
||||
listener.onGnssMeasurementsReceived(event);
|
||||
}
|
||||
};
|
||||
listener -> listener.onGnssMeasurementsReceived(event);
|
||||
foreach(operation);
|
||||
}
|
||||
|
||||
@@ -98,4 +153,25 @@ public abstract class GnssMeasurementsProvider
|
||||
listener.onStatusChanged(mStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class GnssMeasurementProviderNative {
|
||||
public boolean isMeasurementSupported() {
|
||||
return native_is_measurement_supported();
|
||||
}
|
||||
|
||||
public boolean startMeasurementCollection(boolean enableFullTracking) {
|
||||
return native_start_measurement_collection(enableFullTracking);
|
||||
}
|
||||
|
||||
public boolean stopMeasurementCollection() {
|
||||
return native_stop_measurement_collection();
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean native_is_measurement_supported();
|
||||
|
||||
private static native boolean native_start_measurement_collection(boolean enableFullTracking);
|
||||
|
||||
private static native boolean native_stop_measurement_collection();
|
||||
}
|
||||
|
||||
@@ -1799,7 +1799,7 @@ static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /*
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
static jboolean android_location_GnssLocationProvider_is_measurement_supported(
|
||||
static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
|
||||
JNIEnv* env, jclass clazz) {
|
||||
if (gnssMeasurementIface != nullptr) {
|
||||
return JNI_TRUE;
|
||||
@@ -1808,7 +1808,7 @@ static jboolean android_location_GnssLocationProvider_is_measurement_supported(
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
static jboolean android_location_GnssLocationProvider_start_measurement_collection(
|
||||
static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
|
||||
JNIEnv* /* env */,
|
||||
jobject /* obj */,
|
||||
jboolean enableFullTracking) {
|
||||
@@ -1842,7 +1842,7 @@ static jboolean android_location_GnssLocationProvider_start_measurement_collecti
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
|
||||
static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
|
||||
JNIEnv* env,
|
||||
jobject obj) {
|
||||
if (gnssMeasurementIface == nullptr) {
|
||||
@@ -2178,18 +2178,6 @@ static const JNINativeMethod sMethods[] = {
|
||||
{"native_update_network_state",
|
||||
"(ZIZZLjava/lang/String;Ljava/lang/String;)V",
|
||||
reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
|
||||
{"native_is_measurement_supported",
|
||||
"()Z",
|
||||
reinterpret_cast<void *>(
|
||||
android_location_GnssLocationProvider_is_measurement_supported)},
|
||||
{"native_start_measurement_collection",
|
||||
"(Z)Z",
|
||||
reinterpret_cast<void *>(
|
||||
android_location_GnssLocationProvider_start_measurement_collection)},
|
||||
{"native_stop_measurement_collection",
|
||||
"()Z",
|
||||
reinterpret_cast<void *>(
|
||||
android_location_GnssLocationProvider_stop_measurement_collection)},
|
||||
{"native_is_navigation_message_supported",
|
||||
"()Z",
|
||||
reinterpret_cast<void *>(
|
||||
@@ -2269,6 +2257,22 @@ static const JNINativeMethod sGeofenceMethods[] = {
|
||||
reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
|
||||
};
|
||||
|
||||
static const JNINativeMethod sMeasurementMethods[] = {
|
||||
/* name, signature, funcPtr */
|
||||
{"native_is_measurement_supported",
|
||||
"()Z",
|
||||
reinterpret_cast<void *>(
|
||||
android_location_GnssMeasurementsProvider_is_measurement_supported)},
|
||||
{"native_start_measurement_collection",
|
||||
"(Z)Z",
|
||||
reinterpret_cast<void *>(
|
||||
android_location_GnssMeasurementsProvider_start_measurement_collection)},
|
||||
{"native_stop_measurement_collection",
|
||||
"()Z",
|
||||
reinterpret_cast<void *>(
|
||||
android_location_GnssMeasurementsProvider_stop_measurement_collection)},
|
||||
};
|
||||
|
||||
int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
|
||||
jniRegisterNativeMethods(
|
||||
env,
|
||||
@@ -2280,6 +2284,11 @@ int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
|
||||
"com/android/server/location/GnssGeofenceProvider",
|
||||
sGeofenceMethods,
|
||||
NELEM(sGeofenceMethods));
|
||||
jniRegisterNativeMethods(
|
||||
env,
|
||||
"com/android/server/location/GnssMeasurementsProvider",
|
||||
sMeasurementMethods,
|
||||
NELEM(sMeasurementMethods));
|
||||
return jniRegisterNativeMethods(
|
||||
env,
|
||||
"com/android/server/location/GnssLocationProvider",
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.android.server.location;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
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.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GnssMeasurementsProvider}.
|
||||
*/
|
||||
@RunWith(FrameworkRobolectricTestRunner.class)
|
||||
@Config(
|
||||
manifest = Config.NONE,
|
||||
sdk = 27
|
||||
)
|
||||
@SystemLoaderPackages({"com.android.server.location"})
|
||||
@Presubmit
|
||||
public class GnssMeasurementsProviderTest {
|
||||
@Mock
|
||||
private GnssMeasurementsProvider.GnssMeasurementProviderNative mMockNative;
|
||||
private GnssMeasurementsProvider mTestProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mMockNative.startMeasurementCollection(anyBoolean())).thenReturn(true);
|
||||
when(mMockNative.stopMeasurementCollection()).thenReturn(true);
|
||||
|
||||
mTestProvider = new GnssMeasurementsProvider(RuntimeEnvironment.application,
|
||||
new Handler(Looper.myLooper()), mMockNative) {
|
||||
@Override
|
||||
public boolean isGpsEnabled() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_nativeStarted() {
|
||||
mTestProvider.registerWithService();
|
||||
verify(mMockNative).startMeasurementCollection(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unregister_nativeStopped() {
|
||||
mTestProvider.registerWithService();
|
||||
mTestProvider.unregisterFromService();
|
||||
verify(mMockNative).stopMeasurementCollection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSupported_nativeIsSupported() {
|
||||
when(mMockNative.isMeasurementSupported()).thenReturn(true);
|
||||
assertThat(mTestProvider.isAvailableInPlatform()).isTrue();
|
||||
|
||||
when(mMockNative.isMeasurementSupported()).thenReturn(false);
|
||||
assertThat(mTestProvider.isAvailableInPlatform()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_resume_started() {
|
||||
mTestProvider.registerWithService();
|
||||
mTestProvider.resumeIfStarted();
|
||||
verify(mMockNative, times(2)).startMeasurementCollection(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unregister_resume_notStarted() {
|
||||
mTestProvider.registerWithService();
|
||||
mTestProvider.unregisterFromService();
|
||||
mTestProvider.resumeIfStarted();
|
||||
verify(mMockNative, times(1)).startMeasurementCollection(anyBoolean());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user