diff options
4 files changed, 180 insertions, 42 deletions
| diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 03046b6b4eb0..64750b00368b 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -827,26 +827,6 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt          mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {              @Override -            protected boolean isAvailableInPlatform() { -                return native_is_navigation_message_supported(); -            } - -            @Override -            protected int registerWithService() { -                boolean result = native_start_navigation_message_collection(); -                if (result) { -                    return RemoteListenerHelper.RESULT_SUCCESS; -                } else { -                    return RemoteListenerHelper.RESULT_INTERNAL_ERROR; -                } -            } - -            @Override -            protected void unregisterFromService() { -                native_stop_navigation_message_collection(); -            } - -            @Override              protected boolean isGpsEnabled() {                  return isEnabled();              } @@ -2760,13 +2740,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 Navigation message support. -    private static native boolean native_is_navigation_message_supported(); - -    private native boolean native_start_navigation_message_collection(); - -    private native boolean native_stop_navigation_message_collection(); -      // GNSS Configuration      private static native boolean native_set_supl_version(int version); diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java index df3c49bd2ed5..1b4fd187051a 100644 --- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java +++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java @@ -22,6 +22,8 @@ import android.os.Handler;  import android.os.RemoteException;  import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; +  /**   * An base implementation for GPS navigation messages provider.   * It abstracts out the responsibility of handling listeners, while still allowing technology @@ -32,9 +34,53 @@ import android.util.Log;  public abstract class GnssNavigationMessageProvider          extends RemoteListenerHelper<IGnssNavigationMessageListener> {      private static final String TAG = "GnssNavigationMessageProvider"; +    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + +    private final GnssNavigationMessageProviderNative mNative; +    private boolean mCollectionStarted;      protected GnssNavigationMessageProvider(Handler handler) { +        this(handler, new GnssNavigationMessageProviderNative()); +    } + +    @VisibleForTesting +    GnssNavigationMessageProvider(Handler handler, GnssNavigationMessageProviderNative aNative) {          super(handler, TAG); +        mNative = aNative; +    } + +    // TODO(b/37460011): Use this with death recovery logic. +    void resumeIfStarted() { +        if (DEBUG) { +            Log.d(TAG, "resumeIfStarted"); +        } +        if (mCollectionStarted) { +            mNative.startNavigationMessageCollection(); +        } +    } + +    @Override +    protected boolean isAvailableInPlatform() { +        return mNative.isNavigationMessageSupported(); +    } + +    @Override +    protected int registerWithService() { +        boolean result = mNative.startNavigationMessageCollection(); +        if (result) { +            mCollectionStarted = true; +            return RemoteListenerHelper.RESULT_SUCCESS; +        } else { +            return RemoteListenerHelper.RESULT_INTERNAL_ERROR; +        } +    } + +    @Override +    protected void unregisterFromService() { +        boolean stopped = mNative.stopNavigationMessageCollection(); +        if (stopped) { +            mCollectionStarted = false; +        }      }      public void onNavigationMessageAvailable(final GnssNavigationMessage event) { @@ -96,4 +142,25 @@ public abstract class GnssNavigationMessageProvider              listener.onStatusChanged(mStatus);          }      } + +    @VisibleForTesting +    static class GnssNavigationMessageProviderNative { +        public boolean isNavigationMessageSupported() { +            return native_is_navigation_message_supported(); +        } + +        public boolean startNavigationMessageCollection() { +            return native_start_navigation_message_collection(); +        } + +        public boolean stopNavigationMessageCollection() { +            return native_stop_navigation_message_collection(); +        } +    } + +    private static native boolean native_is_navigation_message_supported(); + +    private static native boolean native_start_navigation_message_collection(); + +    private static native boolean native_stop_navigation_message_collection();  } diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index b3b37d6de564..a3a7e1e7d1b2 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -1854,7 +1854,7 @@ static jboolean android_location_GnssMeasurementsProvider_stop_measurement_colle      return boolToJbool(result.isOk());  } -static jboolean android_location_GnssLocationProvider_is_navigation_message_supported( +static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(          JNIEnv* env,          jclass clazz) {      if (gnssNavigationMessageIface != nullptr) { @@ -1863,7 +1863,7 @@ static jboolean android_location_GnssLocationProvider_is_navigation_message_supp      return JNI_FALSE;  } -static jboolean android_location_GnssLocationProvider_start_navigation_message_collection( +static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(          JNIEnv* env,          jobject obj) {      if (gnssNavigationMessageIface == nullptr) { @@ -1884,7 +1884,7 @@ static jboolean android_location_GnssLocationProvider_start_navigation_message_c      return JNI_TRUE;  } -static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection( +static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(          JNIEnv* env,          jobject obj) {      if (gnssNavigationMessageIface == 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_navigation_message_supported", -            "()Z", -            reinterpret_cast<void *>( -                    android_location_GnssLocationProvider_is_navigation_message_supported)}, -    {"native_start_navigation_message_collection", -            "()Z", -            reinterpret_cast<void *>( -                    android_location_GnssLocationProvider_start_navigation_message_collection)}, -    {"native_stop_navigation_message_collection", -            "()Z", -            reinterpret_cast<void *>( -                    android_location_GnssLocationProvider_stop_navigation_message_collection)},      {"native_set_supl_es",              "(I)Z",              reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)}, @@ -2273,6 +2261,22 @@ static const JNINativeMethod sMeasurementMethods[] = {                      android_location_GnssMeasurementsProvider_stop_measurement_collection)},  }; +static const JNINativeMethod sNavigationMessageMethods[] = { +     /* name, signature, funcPtr */ +    {"native_is_navigation_message_supported", +            "()Z", +            reinterpret_cast<void *>( +                    android_location_GnssNavigationMessageProvider_is_navigation_message_supported)}, +    {"native_start_navigation_message_collection", +            "()Z", +            reinterpret_cast<void *>( +                    android_location_GnssNavigationMessageProvider_start_navigation_message_collection)}, +    {"native_stop_navigation_message_collection", +            "()Z", +            reinterpret_cast<void *>( +                    android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)}, +}; +  int register_android_server_location_GnssLocationProvider(JNIEnv* env) {      jniRegisterNativeMethods(              env, @@ -2289,6 +2293,11 @@ int register_android_server_location_GnssLocationProvider(JNIEnv* env) {              "com/android/server/location/GnssMeasurementsProvider",              sMeasurementMethods,              NELEM(sMeasurementMethods)); +    jniRegisterNativeMethods( +            env, +            "com/android/server/location/GnssNavigationMessageProvider", +            sNavigationMessageMethods, +            NELEM(sNavigationMessageMethods));      return jniRegisterNativeMethods(              env,              "com/android/server/location/GnssLocationProvider", diff --git a/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java b/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java new file mode 100644 index 000000000000..8d3de3c9dbc1 --- /dev/null +++ b/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java @@ -0,0 +1,89 @@ +package com.android.server.location; + +import static com.google.common.truth.Truth.assertThat; + +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.annotation.Config; + +/** + * Unit tests for {@link GnssNavigationMessageProvider}. + */ +@RunWith(FrameworkRobolectricTestRunner.class) +@Config( +        manifest = Config.NONE, +        sdk = 27 +) +@SystemLoaderPackages({"com.android.server.location"}) +@Presubmit +public class GnssNavigationMessageProviderTest { +    @Mock +    private GnssNavigationMessageProvider.GnssNavigationMessageProviderNative mMockNative; +    private GnssNavigationMessageProvider mTestProvider; + +    @Before +    public void setUp() { +        MockitoAnnotations.initMocks(this); +        when(mMockNative.startNavigationMessageCollection()).thenReturn(true); +        when(mMockNative.stopNavigationMessageCollection()).thenReturn(true); + +        mTestProvider = new GnssNavigationMessageProvider(new Handler(Looper.myLooper()), +                mMockNative) { +            @Override +            public boolean isGpsEnabled() { +                return true; +            } +        }; +    } + +    @Test +    public void register_nativeStarted() { +        mTestProvider.registerWithService(); +        verify(mMockNative).startNavigationMessageCollection(); +    } + +    @Test +    public void unregister_nativeStopped() { +        mTestProvider.registerWithService(); +        mTestProvider.unregisterFromService(); +        verify(mMockNative).stopNavigationMessageCollection(); +    } + +    @Test +    public void isSupported_nativeIsSupported() { +        when(mMockNative.isNavigationMessageSupported()).thenReturn(true); +        assertThat(mTestProvider.isAvailableInPlatform()).isTrue(); + +        when(mMockNative.isNavigationMessageSupported()).thenReturn(false); +        assertThat(mTestProvider.isAvailableInPlatform()).isFalse(); +    } + +    @Test +    public void register_resume_started() { +        mTestProvider.registerWithService(); +        mTestProvider.resumeIfStarted(); +        verify(mMockNative, times(2)).startNavigationMessageCollection(); +    } + +    @Test +    public void unregister_resume_notStarted() { +        mTestProvider.registerWithService(); +        mTestProvider.unregisterFromService(); +        mTestProvider.resumeIfStarted(); +        verify(mMockNative, times(1)).startNavigationMessageCollection(); +    } +} |