Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a964ebe4 authored by Yu-Han Yang's avatar Yu-Han Yang Committed by android-build-merger
Browse files

Merge "Refactor GnssMeasurementsProvider" into pi-dev

am: 13d650d7

Change-Id: I9ff93b600fb0fdb1cf46ce569811f4f5eba75c88
parents 4e4f0926 13d650d7
Loading
Loading
Loading
Loading
+2 −39
Original line number Diff line number Diff line
@@ -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();
@@ -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();

+85 −9
Original line number Diff line number Diff line
@@ -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);

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

    protected GnssMeasurementsProvider(Handler handler) {
    @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);
        }
    }

    public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
        ListenerOperation<IGnssMeasurementsListener> operation =
                new ListenerOperation<IGnssMeasurementsListener>() {
    @Override
                    public void execute(IGnssMeasurementsListener listener) throws RemoteException {
                        listener.onGnssMeasurementsReceived(event);
    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 =
                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();
}
+24 −15
Original line number Diff line number Diff line
@@ -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",
+90 −0
Original line number Diff line number Diff line
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());
    }
}