Create unit tests for GnssManagerService
Test: atest GnssManagerServiceTest.java

Change-Id: I9ef40a99d898119251e3ea1d353a61368313ba07
diff --git a/services/core/java/com/android/server/GnssManagerService.java b/services/core/java/com/android/server/GnssManagerService.java
index 274e2f1..cbf2a62 100644
--- a/services/core/java/com/android/server/GnssManagerService.java
+++ b/services/core/java/com/android/server/GnssManagerService.java
@@ -67,7 +67,7 @@
 
 /** Manages Gnss providers and related Gnss functions for LocationManagerService. */
 public class GnssManagerService {
-    private static final String TAG = "LocationManagerService";
+    private static final String TAG = "GnssManagerService";
     private static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
 
     // Providers
@@ -124,7 +124,7 @@
 
     // Can use this constructor to inject GnssLocationProvider for testing
     @VisibleForTesting
-    GnssManagerService(LocationManagerService locationManagerService,
+    public GnssManagerService(LocationManagerService locationManagerService,
             Context context,
             GnssLocationProvider gnssLocationProvider,
             LocationUsageLogger locationUsageLogger) {
@@ -719,8 +719,10 @@
      * @param listener called when navigation message is received
      */
     public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) {
-        removeGnssDataListener(
-                listener, mGnssNavigationMessageProvider, mGnssNavigationMessageListeners);
+        synchronized (mGnssNavigationMessageListeners) {
+            removeGnssDataListener(
+                    listener, mGnssNavigationMessageProvider, mGnssNavigationMessageListeners);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/LocationUsageLogger.java b/services/core/java/com/android/server/LocationUsageLogger.java
index 4ca74bf..a8a3cc4 100644
--- a/services/core/java/com/android/server/LocationUsageLogger.java
+++ b/services/core/java/com/android/server/LocationUsageLogger.java
@@ -30,7 +30,7 @@
 /**
  * Logger for Location API usage logging.
  */
-class LocationUsageLogger {
+public class LocationUsageLogger {
     private static final String TAG = "LocationUsageLogger";
     private static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
 
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 8bf01a3..11b9ac4 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -67,6 +67,7 @@
 import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
@@ -304,6 +305,9 @@
     private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
             MAX_RETRY_INTERVAL);
 
+    private static boolean sIsInitialized = false;
+    private static boolean sStaticTestOverride = false;
+
     // True if we are enabled
     @GuardedBy("mLock")
     private boolean mGpsEnabled;
@@ -576,7 +580,15 @@
         }
     }
 
+    @VisibleForTesting
+    public static void setIsSupportedForTest(boolean override) {
+        sStaticTestOverride = override;
+    }
+
     public static boolean isSupported() {
+        if (sStaticTestOverride) {
+            return true;
+        }
         return native_is_supported();
     }
 
@@ -598,6 +610,13 @@
             Looper looper) {
         super(context, locationProviderManager);
 
+        synchronized (mLock) {
+            if (!sIsInitialized) {
+                class_init_native();
+            }
+            sIsInitialized = true;
+        }
+
         mLooper = looper;
 
         // Create a wake lock
@@ -2224,10 +2243,6 @@
     // preallocated to avoid memory allocation in reportNmea()
     private byte[] mNmeaBuffer = new byte[120];
 
-    static {
-        class_init_native();
-    }
-
     private static native void class_init_native();
 
     private static native boolean native_is_supported();
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index ec05c31..55e427f 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -47,7 +47,7 @@
     }
 
     @VisibleForTesting
-    GnssMeasurementsProvider(
+    public GnssMeasurementsProvider(
             Context context, Handler handler, GnssMeasurementProviderNative aNative) {
         super(context, handler, TAG);
         mNative = aNative;
@@ -158,7 +158,7 @@
     }
 
     @VisibleForTesting
-    static class GnssMeasurementProviderNative {
+    public static class GnssMeasurementProviderNative {
         public boolean isMeasurementSupported() {
             return native_is_measurement_supported();
         }
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 4c45ef6..983d1da 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -45,7 +45,7 @@
     }
 
     @VisibleForTesting
-    GnssNavigationMessageProvider(Context context, Handler handler,
+    public GnssNavigationMessageProvider(Context context, Handler handler,
             GnssNavigationMessageProviderNative aNative) {
         super(context, handler, TAG);
         mNative = aNative;
@@ -142,7 +142,7 @@
     }
 
     @VisibleForTesting
-    static class GnssNavigationMessageProviderNative {
+    public static class GnssNavigationMessageProviderNative {
         public boolean isNavigationMessageSupported() {
             return native_is_navigation_message_supported();
         }
diff --git a/services/tests/servicestests/src/com/android/server/GnssManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/GnssManagerServiceTest.java
new file mode 100644
index 0000000..9692c25
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/GnssManagerServiceTest.java
@@ -0,0 +1,743 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
+import android.Manifest;
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.GnssClock;
+import android.location.GnssMeasurementCorrections;
+import android.location.GnssMeasurementsEvent;
+import android.location.GnssNavigationMessage;
+import android.location.GnssSingleSatCorrection;
+import android.location.IBatchedLocationCallback;
+import android.location.IGnssMeasurementsListener;
+import android.location.IGnssNavigationMessageListener;
+import android.location.IGnssStatusListener;
+import android.location.INetInitiatedListener;
+import android.location.Location;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Message;
+import android.os.RemoteException;
+
+import com.android.server.location.GnssBatchingProvider;
+import com.android.server.location.GnssCapabilitiesProvider;
+import com.android.server.location.GnssLocationProvider;
+import com.android.server.location.GnssMeasurementCorrectionsProvider;
+import com.android.server.location.GnssMeasurementsProvider;
+import com.android.server.location.GnssMeasurementsProvider.GnssMeasurementProviderNative;
+import com.android.server.location.GnssNavigationMessageProvider;
+import com.android.server.location.GnssNavigationMessageProvider.GnssNavigationMessageProviderNative;
+import com.android.server.location.GnssStatusListenerHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.AdditionalMatchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Unit tests for {@link com.android.server.GnssManagerService}.
+ */
+public class GnssManagerServiceTest {
+
+    // Gnss Providers
+    @Mock
+    private GnssLocationProvider mMockGnssLocationProvider;
+    @Mock
+    private GnssBatchingProvider mMockGnssBatchingProvider;
+    @Mock
+    private GnssLocationProvider.GnssSystemInfoProvider mMockGnssSystemInfoProvider;
+    @Mock
+    private GnssCapabilitiesProvider mMockGnssCapabilitiesProvider;
+    @Mock
+    private GnssMeasurementCorrectionsProvider mMockGnssMeasurementCorrectionsProvider;
+    @Mock
+    private INetInitiatedListener mMockNetInitiatedListener;
+    private GnssMeasurementsProvider mTestGnssMeasurementsProvider;
+    private GnssStatusListenerHelper mTestGnssStatusProvider;
+    private GnssNavigationMessageProvider mTestGnssNavigationMessageProvider;
+
+    // Managers and services
+    @Mock
+    private AppOpsManager mMockAppOpsManager;
+    @Mock
+    private ActivityManager mMockActivityManager;
+    @Mock
+    private LocationManagerService mMockLocationManagerService;
+
+    // Context and handler
+    @Mock
+    private Handler mMockHandler;
+    @Mock
+    private Context mMockContext;
+
+    // Class under test
+    private GnssManagerService mGnssManagerService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        GnssLocationProvider.setIsSupportedForTest(true);
+
+        // Set up mock context
+        when(mMockContext.getSystemServiceName(AppOpsManager.class)).thenReturn(
+                Context.APP_OPS_SERVICE);
+        when(mMockContext.getSystemServiceName(ActivityManager.class)).thenReturn(
+                Context.ACTIVITY_SERVICE);
+        when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(
+                mMockAppOpsManager);
+        when(mMockContext.getSystemService(
+                eq(Context.ACTIVITY_SERVICE))).thenReturn(
+                mMockActivityManager);
+        enableLocationPermissions();
+
+        // Mock Handler will execute posted runnables immediately
+        when(mMockHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
+                (InvocationOnMock invocation) -> {
+                    Message msg = (Message) (invocation.getArguments()[0]);
+                    msg.getCallback().run();
+                    return null;
+                });
+
+        // Setup providers
+        mTestGnssMeasurementsProvider = createGnssMeasurementsProvider(
+                mMockContext, mMockHandler);
+        mTestGnssStatusProvider = createGnssStatusListenerHelper(
+                mMockContext, mMockHandler);
+        mTestGnssNavigationMessageProvider = createGnssNavigationMessageProvider(
+                mMockContext, mMockHandler);
+
+        // Setup GnssLocationProvider to return providers
+        when(mMockGnssLocationProvider.getGnssStatusProvider()).thenReturn(
+                mTestGnssStatusProvider);
+        when(mMockGnssLocationProvider.getGnssBatchingProvider()).thenReturn(
+                mMockGnssBatchingProvider);
+        when(mMockGnssLocationProvider.getGnssCapabilitiesProvider()).thenReturn(
+                mMockGnssCapabilitiesProvider);
+        when(mMockGnssLocationProvider.getGnssSystemInfoProvider()).thenReturn(
+                mMockGnssSystemInfoProvider);
+        when(mMockGnssLocationProvider.getGnssMeasurementCorrectionsProvider()).thenReturn(
+                mMockGnssMeasurementCorrectionsProvider);
+        when(mMockGnssLocationProvider.getGnssMeasurementsProvider()).thenReturn(
+                mTestGnssMeasurementsProvider);
+        when(mMockGnssLocationProvider.getGnssNavigationMessageProvider()).thenReturn(
+                mTestGnssNavigationMessageProvider);
+        when(mMockGnssLocationProvider.getNetInitiatedListener()).thenReturn(
+                mMockNetInitiatedListener);
+
+        // Setup GnssBatching provider
+        when(mMockGnssBatchingProvider.start(anyLong(), anyBoolean())).thenReturn(true);
+        when(mMockGnssBatchingProvider.stop()).thenReturn(true);
+
+        // Create GnssManagerService
+        mGnssManagerService = new GnssManagerService(mMockLocationManagerService, mMockContext,
+                mMockGnssLocationProvider, new LocationUsageLogger());
+    }
+
+    private void overrideAsBinder(IInterface mockListener) {
+        IBinder mockBinder = mock(IBinder.class);
+        when(mockListener.asBinder()).thenReturn(mockBinder);
+    }
+
+    private IGnssStatusListener createMockGnssStatusListener() {
+        IGnssStatusListener mockListener = mock(IGnssStatusListener.class);
+        overrideAsBinder(mockListener);
+        return mockListener;
+    }
+
+    private IGnssMeasurementsListener createMockGnssMeasurementsListener() {
+        IGnssMeasurementsListener mockListener = mock(
+                IGnssMeasurementsListener.class);
+        overrideAsBinder(mockListener);
+        return mockListener;
+    }
+
+    private IBatchedLocationCallback createMockBatchedLocationCallback() {
+        IBatchedLocationCallback mockedCallback = mock(IBatchedLocationCallback.class);
+        overrideAsBinder(mockedCallback);
+        return mockedCallback;
+    }
+
+    private IGnssNavigationMessageListener createMockGnssNavigationMessageListener() {
+        IGnssNavigationMessageListener mockListener = mock(IGnssNavigationMessageListener.class);
+        overrideAsBinder(mockListener);
+        return mockListener;
+    }
+
+    private GnssMeasurementCorrections createDummyGnssMeasurementCorrections() {
+        GnssSingleSatCorrection gnssSingleSatCorrection =
+                new GnssSingleSatCorrection.Builder().build();
+        return
+                new GnssMeasurementCorrections.Builder().setSingleSatelliteCorrectionList(
+                        Arrays.asList(gnssSingleSatCorrection)).build();
+    }
+
+    private void enableLocationPermissions() {
+        Mockito.doThrow(new SecurityException()).when(
+                mMockContext).enforceCallingPermission(
+                AdditionalMatchers.and(
+                        AdditionalMatchers.not(eq(Manifest.permission.LOCATION_HARDWARE)),
+                        AdditionalMatchers.not(eq(Manifest.permission.ACCESS_FINE_LOCATION))),
+                anyString());
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.LOCATION_HARDWARE), anyInt(), anyInt())).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+
+        // AppOpsManager will return true if OP_FINE_LOCATION is checked
+        when(mMockAppOpsManager.checkOp(anyInt(), anyInt(), anyString())).thenAnswer(
+                (InvocationOnMock invocation) -> {
+                    int code = (int) (invocation.getArguments()[0]);
+                    if (code == AppOpsManager.OP_FINE_LOCATION) {
+                        return AppOpsManager.MODE_ALLOWED;
+                    }
+                    return AppOpsManager.MODE_ERRORED;
+                });
+    }
+
+    private void disableLocationPermissions() {
+        Mockito.doThrow(new SecurityException()).when(
+                mMockContext).enforceCallingPermission(anyString(), anyString());
+        Mockito.doThrow(new SecurityException()).when(
+                mMockContext).checkPermission(anyString(), anyInt(), anyInt());
+
+        when(mMockAppOpsManager.checkOp(anyInt(), anyInt(),
+                anyString())).thenReturn(AppOpsManager.MODE_ERRORED);
+    }
+
+    private GnssStatusListenerHelper createGnssStatusListenerHelper(Context context,
+            Handler handler) {
+        return new GnssStatusListenerHelper(
+                context, handler) {
+            @Override
+            protected boolean isAvailableInPlatform() {
+                return true;
+            }
+
+            @Override
+            protected boolean isGpsEnabled() {
+                return true;
+            }
+        };
+    }
+
+    private GnssMeasurementsProvider createGnssMeasurementsProvider(Context context,
+            Handler handler) {
+        GnssMeasurementProviderNative
+                mockGnssMeasurementProviderNative = mock(GnssMeasurementProviderNative.class);
+        return new GnssMeasurementsProvider(
+                context, handler, mockGnssMeasurementProviderNative) {
+            @Override
+            protected boolean isGpsEnabled() {
+                return true;
+            }
+        };
+    }
+
+    private GnssNavigationMessageProvider createGnssNavigationMessageProvider(Context context,
+            Handler handler) {
+        GnssNavigationMessageProviderNative mockGnssNavigationMessageProviderNative = mock(
+                GnssNavigationMessageProviderNative.class);
+        return new GnssNavigationMessageProvider(context, handler,
+                mockGnssNavigationMessageProviderNative) {
+            @Override
+            protected boolean isGpsEnabled() {
+                return true;
+            }
+        };
+    }
+
+    @Test
+    public void getGnssYearOfHardwareTest() {
+        final int gnssYearOfHardware = 2012;
+        when(mMockGnssSystemInfoProvider.getGnssYearOfHardware()).thenReturn(gnssYearOfHardware);
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.getGnssYearOfHardware()).isEqualTo(gnssYearOfHardware);
+    }
+
+    @Test
+    public void getGnssHardwareModelNameTest() {
+        final String gnssHardwareModelName = "hardwarename";
+        when(mMockGnssSystemInfoProvider.getGnssHardwareModelName()).thenReturn(
+                gnssHardwareModelName);
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.getGnssHardwareModelName()).isEqualTo(
+                gnssHardwareModelName);
+    }
+
+    @Test
+    public void getGnssCapabilitiesWithoutPermissionsTest() {
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.getGnssCapabilities("com.android.server"));
+    }
+
+    @Test
+    public void getGnssCapabilitiesWithPermissionsTest() {
+        final long mGnssCapabilities = 23132L;
+        when(mMockGnssCapabilitiesProvider.getGnssCapabilities()).thenReturn(mGnssCapabilities);
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.getGnssCapabilities("com.android.server")).isEqualTo(
+                mGnssCapabilities);
+    }
+
+    @Test
+    public void getGnssBatchSizeWithoutPermissionsTest() {
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.getGnssBatchSize("com.android.server"));
+    }
+
+    @Test
+    public void getGnssBatchSizeWithPermissionsTest() {
+        final int gnssBatchSize = 10;
+        when(mMockGnssBatchingProvider.getBatchSize()).thenReturn(gnssBatchSize);
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.getGnssBatchSize("com.android.server")).isEqualTo(
+                gnssBatchSize);
+    }
+
+    @Test
+    public void startGnssBatchWithoutPermissionsTest() {
+        final long periodNanos = 100L;
+        final boolean wakeOnFifoFull = true;
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.startGnssBatch(periodNanos, wakeOnFifoFull,
+                        "com.android.server"));
+        verify(mMockGnssBatchingProvider, times(0)).start(periodNanos, wakeOnFifoFull);
+    }
+
+    @Test
+    public void startGnssBatchWithPermissionsTest() {
+        final long periodNanos = 100L;
+        final boolean wakeOnFifoFull = true;
+
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.startGnssBatch(periodNanos, wakeOnFifoFull,
+                "com.android.server"))
+                .isEqualTo(
+                        true);
+        verify(mMockGnssBatchingProvider, times(1)).start(100L, true);
+    }
+
+    @Test
+    public void addGnssBatchCallbackWithoutPermissionsTest() throws RemoteException {
+        IBatchedLocationCallback mockBatchedLocationCallback = createMockBatchedLocationCallback();
+        List<Location> mockLocationList = (List<Location>) mock(List.class);
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class, () -> mGnssManagerService.addGnssBatchingCallback(
+                mockBatchedLocationCallback, "com.android.server", "abcd123",
+                "TestBatchedLocationCallback"));
+
+        mGnssManagerService.onReportLocation(mockLocationList);
+
+        verify(mockBatchedLocationCallback, times(0)).onLocationBatch(mockLocationList);
+    }
+
+    @Test
+    public void addGnssBatchCallbackWithPermissionsTest() throws RemoteException {
+        IBatchedLocationCallback mockBatchedLocationCallback = createMockBatchedLocationCallback();
+        List<Location> mockLocationList = (List<Location>) mock(List.class);
+
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.addGnssBatchingCallback(
+                mockBatchedLocationCallback, "com.android.server",
+                "abcd123", "TestBatchedLocationCallback")).isEqualTo(true);
+
+        mGnssManagerService.onReportLocation(mockLocationList);
+
+        verify(mockBatchedLocationCallback, times(1)).onLocationBatch(mockLocationList);
+    }
+
+    @Test
+    public void replaceGnssBatchCallbackTest() throws RemoteException {
+        IBatchedLocationCallback mockBatchedLocationCallback1 = createMockBatchedLocationCallback();
+        IBatchedLocationCallback mockBatchedLocationCallback2 = createMockBatchedLocationCallback();
+        List<Location> mockLocationList = (List<Location>) mock(List.class);
+
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.addGnssBatchingCallback(
+                mockBatchedLocationCallback1, "com.android.server",
+                "abcd123", "TestBatchedLocationCallback")).isEqualTo(true);
+        assertThat(mGnssManagerService.addGnssBatchingCallback(
+                mockBatchedLocationCallback2, "com.android.server",
+                "abcd123", "TestBatchedLocationCallback")).isEqualTo(true);
+
+        mGnssManagerService.onReportLocation(mockLocationList);
+
+        verify(mockBatchedLocationCallback1, times(0)).onLocationBatch(mockLocationList);
+        verify(mockBatchedLocationCallback2, times(1)).onLocationBatch(mockLocationList);
+    }
+
+    @Test
+    public void flushGnssBatchWithoutPermissionsTest() {
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.flushGnssBatch("com.android.server"));
+        verify(mMockGnssBatchingProvider, times(0)).flush();
+    }
+
+    @Test
+    public void flushGnssBatchWithPermissionsTest() {
+        enableLocationPermissions();
+        mGnssManagerService.flushGnssBatch("com.android.server");
+
+        verify(mMockGnssBatchingProvider, times(1)).flush();
+    }
+
+    @Test
+    public void removeGnssBatchingCallbackWithoutPermissionsTest() throws RemoteException {
+        IBatchedLocationCallback mockBatchedLocationCallback = createMockBatchedLocationCallback();
+        List<Location> mockLocationList = (List<Location>) mock(List.class);
+
+        enableLocationPermissions();
+
+        mGnssManagerService.addGnssBatchingCallback(mockBatchedLocationCallback,
+                "com.android.server", "abcd123", "TestBatchedLocationCallback");
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.removeGnssBatchingCallback());
+
+        mGnssManagerService.onReportLocation(mockLocationList);
+
+        verify(mockBatchedLocationCallback, times(1)).onLocationBatch(mockLocationList);
+    }
+
+    @Test
+    public void removeGnssBatchingCallbackWithPermissionsTest() throws RemoteException {
+        IBatchedLocationCallback mockBatchedLocationCallback = createMockBatchedLocationCallback();
+        List<Location> mockLocationList = (List<Location>) mock(List.class);
+
+        enableLocationPermissions();
+
+        mGnssManagerService.addGnssBatchingCallback(mockBatchedLocationCallback,
+                "com.android.server", "abcd123", "TestBatchedLocationCallback");
+
+        mGnssManagerService.removeGnssBatchingCallback();
+
+        mGnssManagerService.onReportLocation(mockLocationList);
+
+        verify(mockBatchedLocationCallback, times(0)).onLocationBatch(mockLocationList);
+    }
+
+    @Test
+    public void stopGnssBatchWithoutPermissionsTest() {
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class, () -> mGnssManagerService.stopGnssBatch());
+        verify(mMockGnssBatchingProvider, times(0)).stop();
+    }
+
+    @Test
+    public void stopGnssBatchWithPermissionsTest() {
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.stopGnssBatch()).isEqualTo(true);
+        verify(mMockGnssBatchingProvider, times(1)).stop();
+    }
+
+    @Test
+    public void registerGnssStatusCallbackWithoutPermissionsTest() throws RemoteException {
+        final int timeToFirstFix = 20000;
+        IGnssStatusListener mockGnssStatusListener = createMockGnssStatusListener();
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class, () -> mGnssManagerService
+                .registerGnssStatusCallback(
+                        mockGnssStatusListener, "com.android.server", "abcd123"));
+
+        mTestGnssStatusProvider.onFirstFix(timeToFirstFix);
+
+        verify(mockGnssStatusListener, times(0)).onFirstFix(timeToFirstFix);
+    }
+
+    @Test
+    public void registerGnssStatusCallbackWithPermissionsTest() throws RemoteException {
+        final int timeToFirstFix = 20000;
+        IGnssStatusListener mockGnssStatusListener = createMockGnssStatusListener();
+
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.registerGnssStatusCallback(
+                mockGnssStatusListener, "com.android.server", "abcd123")).isEqualTo(true);
+
+        mTestGnssStatusProvider.onFirstFix(timeToFirstFix);
+
+        verify(mockGnssStatusListener, times(1)).onFirstFix(timeToFirstFix);
+    }
+
+    @Test
+    public void unregisterGnssStatusCallbackWithPermissionsTest() throws RemoteException {
+        final int timeToFirstFix = 20000;
+        IGnssStatusListener mockGnssStatusListener = createMockGnssStatusListener();
+
+        enableLocationPermissions();
+
+        mGnssManagerService.registerGnssStatusCallback(
+                mockGnssStatusListener, "com.android.server", "abcd123");
+
+        mGnssManagerService.unregisterGnssStatusCallback(mockGnssStatusListener);
+
+        mTestGnssStatusProvider.onFirstFix(timeToFirstFix);
+
+        verify(mockGnssStatusListener, times(0)).onFirstFix(timeToFirstFix);
+    }
+
+    @Test
+    public void addGnssMeasurementsListenerWithoutPermissionsTest() throws RemoteException {
+        IGnssMeasurementsListener mockGnssMeasurementsListener =
+                createMockGnssMeasurementsListener();
+        GnssMeasurementsEvent gnssMeasurementsEvent = new GnssMeasurementsEvent(new GnssClock(),
+                null);
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.addGnssMeasurementsListener(
+                        mockGnssMeasurementsListener,
+                        "com.android.server", "abcd123", "TestGnssMeasurementsListener"));
+
+        mTestGnssMeasurementsProvider.onMeasurementsAvailable(gnssMeasurementsEvent);
+        verify(mockGnssMeasurementsListener, times(0)).onGnssMeasurementsReceived(
+                gnssMeasurementsEvent);
+    }
+
+    @Test
+    public void addGnssMeasurementsListenerWithPermissionsTest() throws RemoteException {
+        IGnssMeasurementsListener mockGnssMeasurementsListener =
+                createMockGnssMeasurementsListener();
+        GnssMeasurementsEvent gnssMeasurementsEvent = new GnssMeasurementsEvent(new GnssClock(),
+                null);
+
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.addGnssMeasurementsListener(mockGnssMeasurementsListener,
+                "com.android.server", "abcd123", "TestGnssMeasurementsListener")).isEqualTo(true);
+
+        mTestGnssMeasurementsProvider.onMeasurementsAvailable(gnssMeasurementsEvent);
+        verify(mockGnssMeasurementsListener, times(1)).onGnssMeasurementsReceived(
+                gnssMeasurementsEvent);
+    }
+
+    @Test
+    public void injectGnssMeasurementCorrectionsWithoutPermissionsTest() {
+        GnssMeasurementCorrections gnssMeasurementCorrections =
+                createDummyGnssMeasurementCorrections();
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.injectGnssMeasurementCorrections(
+                        gnssMeasurementCorrections, "com.android.server"));
+        verify(mMockGnssMeasurementCorrectionsProvider, times(0))
+                .injectGnssMeasurementCorrections(
+                        gnssMeasurementCorrections);
+    }
+
+    @Test
+    public void injectGnssMeasurementCorrectionsWithPermissionsTest() {
+        GnssMeasurementCorrections gnssMeasurementCorrections =
+                createDummyGnssMeasurementCorrections();
+
+        enableLocationPermissions();
+
+        mGnssManagerService.injectGnssMeasurementCorrections(
+                gnssMeasurementCorrections, "com.android.server");
+        verify(mMockGnssMeasurementCorrectionsProvider, times(1))
+                .injectGnssMeasurementCorrections(
+                        gnssMeasurementCorrections);
+    }
+
+    @Test
+    public void removeGnssMeasurementsListenerWithoutPermissionsTest() throws RemoteException {
+        IGnssMeasurementsListener mockGnssMeasurementsListener =
+                createMockGnssMeasurementsListener();
+        GnssMeasurementsEvent gnssMeasurementsEvent = new GnssMeasurementsEvent(new GnssClock(),
+                null);
+
+        enableLocationPermissions();
+
+        mGnssManagerService.addGnssMeasurementsListener(mockGnssMeasurementsListener,
+                "com.android.server", "abcd123", "TestGnssMeasurementsListener");
+
+        disableLocationPermissions();
+
+        mGnssManagerService.removeGnssMeasurementsListener(
+                mockGnssMeasurementsListener);
+
+        mTestGnssMeasurementsProvider.onMeasurementsAvailable(gnssMeasurementsEvent);
+        verify(mockGnssMeasurementsListener, times(0)).onGnssMeasurementsReceived(
+                gnssMeasurementsEvent);
+    }
+
+    @Test
+    public void removeGnssMeasurementsListenerWithPermissionsTest() throws RemoteException {
+        IGnssMeasurementsListener mockGnssMeasurementsListener =
+                createMockGnssMeasurementsListener();
+        GnssMeasurementsEvent gnssMeasurementsEvent = new GnssMeasurementsEvent(new GnssClock(),
+                null);
+
+        enableLocationPermissions();
+
+        mGnssManagerService.addGnssMeasurementsListener(mockGnssMeasurementsListener,
+                "com.android.server", "abcd123", "TestGnssMeasurementsListener");
+
+        disableLocationPermissions();
+
+        mGnssManagerService.removeGnssMeasurementsListener(
+                mockGnssMeasurementsListener);
+
+        mTestGnssMeasurementsProvider.onMeasurementsAvailable(gnssMeasurementsEvent);
+        verify(mockGnssMeasurementsListener, times(0)).onGnssMeasurementsReceived(
+                gnssMeasurementsEvent);
+    }
+
+    @Test
+    public void addGnssNavigationMessageListenerWithoutPermissionsTest() throws RemoteException {
+        IGnssNavigationMessageListener mockGnssNavigationMessageListener =
+                createMockGnssNavigationMessageListener();
+        GnssNavigationMessage gnssNavigationMessage = new GnssNavigationMessage();
+
+        disableLocationPermissions();
+
+        assertThrows(SecurityException.class,
+                () -> mGnssManagerService.addGnssNavigationMessageListener(
+                        mockGnssNavigationMessageListener, "com.android.server",
+                        "abcd123", "TestGnssNavigationMessageListener"));
+
+        mTestGnssNavigationMessageProvider.onNavigationMessageAvailable(gnssNavigationMessage);
+
+        verify(mockGnssNavigationMessageListener, times(0)).onGnssNavigationMessageReceived(
+                gnssNavigationMessage);
+    }
+
+    @Test
+    public void addGnssNavigationMessageListenerWithPermissionsTest() throws RemoteException {
+        IGnssNavigationMessageListener mockGnssNavigationMessageListener =
+                createMockGnssNavigationMessageListener();
+        GnssNavigationMessage gnssNavigationMessage = new GnssNavigationMessage();
+
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.addGnssNavigationMessageListener(
+                mockGnssNavigationMessageListener, "com.android.server",
+                "abcd123", "TestGnssNavigationMessageListener")).isEqualTo(true);
+
+        mTestGnssNavigationMessageProvider.onNavigationMessageAvailable(gnssNavigationMessage);
+
+        verify(mockGnssNavigationMessageListener, times(1)).onGnssNavigationMessageReceived(
+                gnssNavigationMessage);
+    }
+
+    @Test
+    public void removeGnssNavigationMessageListenerWithoutPermissionsTest() throws RemoteException {
+        IGnssNavigationMessageListener mockGnssNavigationMessageListener =
+                createMockGnssNavigationMessageListener();
+        GnssNavigationMessage gnssNavigationMessage = new GnssNavigationMessage();
+
+        enableLocationPermissions();
+
+        mGnssManagerService.addGnssNavigationMessageListener(
+                mockGnssNavigationMessageListener, "com.android.server",
+                "abcd123", "TestGnssNavigationMessageListener");
+
+        disableLocationPermissions();
+
+        mGnssManagerService.removeGnssNavigationMessageListener(
+                mockGnssNavigationMessageListener);
+
+        mTestGnssNavigationMessageProvider.onNavigationMessageAvailable(gnssNavigationMessage);
+
+        verify(mockGnssNavigationMessageListener, times(0)).onGnssNavigationMessageReceived(
+                gnssNavigationMessage);
+    }
+
+    @Test
+    public void removeGnssNavigationMessageListenerWithPermissionsTest() throws RemoteException {
+        IGnssNavigationMessageListener mockGnssNavigationMessageListener =
+                createMockGnssNavigationMessageListener();
+        GnssNavigationMessage gnssNavigationMessage = new GnssNavigationMessage();
+
+        enableLocationPermissions();
+
+        mGnssManagerService.addGnssNavigationMessageListener(
+                mockGnssNavigationMessageListener, "com.android.server",
+                "abcd123", "TestGnssNavigationMessageListener");
+
+        mGnssManagerService.removeGnssNavigationMessageListener(
+                mockGnssNavigationMessageListener);
+
+        mTestGnssNavigationMessageProvider.onNavigationMessageAvailable(gnssNavigationMessage);
+
+        verify(mockGnssNavigationMessageListener, times(0)).onGnssNavigationMessageReceived(
+                gnssNavigationMessage);
+    }
+
+    @Test
+    public void sendNiResponseWithPermissionsTest() throws RemoteException {
+        when(mMockNetInitiatedListener.sendNiResponse(anyInt(), anyInt())).thenReturn(true);
+
+        int notifId = 0;
+        int userResponse = 0;
+        enableLocationPermissions();
+
+        assertThat(mGnssManagerService.sendNiResponse(notifId, userResponse)).isEqualTo(true);
+
+        verify(mMockNetInitiatedListener, times(1)).sendNiResponse(notifId, userResponse);
+    }
+}