Merge "Refactor GnssMeasurementsProvider" into pi-dev

This commit is contained in:
Yu-Han Yang
2018-04-26 01:31:51 +00:00
committed by Android (Google) Code Review
4 changed files with 201 additions and 63 deletions

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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",

View File

@@ -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());
}
}