Add test case for location is not available

Bug: 366332766
Flag: com.android.internal.telephony.flags.oem_enabled_satellite_flag
Test: atest SatelliteAccessControllerTest
Test: Manually verified cases below (b/366332766#comment4)
- location query is unavailable and cache(true) is valid - allowed
- location query is unavailable and cache(false) is valid - not allowed
- location query is unavailable and cache is invalid - not allowed

Change-Id: I7f376a5db55f13c105cf31e3c3e69db6e3c0c003
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 08b041b..04bb952 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -3732,6 +3732,10 @@
                     state = "cache_allowed";
                     break;
                 }
+                case "-na": {
+                    state = "cache_not_allowed";
+                    break;
+                }
                 case "-n": {
                     state = "cache_clear_and_not_allowed";
                     break;
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index 7b244a1..f9bf0e8 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -259,9 +259,9 @@
      */
     private final ConcurrentHashMap<IBinder, ISatelliteCommunicationAllowedStateCallback>
             mSatelliteCommunicationAllowedStateChangedListeners = new ConcurrentHashMap<>();
-    private final Object mSatelliteCommunicationAllowStateLock = new Object();
+    protected final Object mSatelliteCommunicationAllowStateLock = new Object();
     @GuardedBy("mSatelliteCommunicationAllowStateLock")
-    private boolean mCurrentSatelliteAllowedState = false;
+    protected boolean mCurrentSatelliteAllowedState = false;
 
     protected static final long ALLOWED_STATE_CACHE_VALID_DURATION_NANOS =
             TimeUnit.HOURS.toNanos(4);
@@ -1920,6 +1920,10 @@
                 mLatestSatelliteCommunicationAllowedSetTime = getElapsedRealtimeNanos();
                 mLatestSatelliteCommunicationAllowed = true;
                 mCurrentSatelliteAllowedState = true;
+            } else if ("cache_not_allowed".equalsIgnoreCase(state)) {
+                mLatestSatelliteCommunicationAllowedSetTime = getElapsedRealtimeNanos();
+                mLatestSatelliteCommunicationAllowed = false;
+                mCurrentSatelliteAllowedState = false;
             } else if ("cache_clear_and_not_allowed".equalsIgnoreCase(state)) {
                 mLatestSatelliteCommunicationAllowedSetTime = 0;
                 mLatestSatelliteCommunicationAllowed = false;
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index 55f72fc..3d2c953 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -34,6 +34,7 @@
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_DELAY_MINUTES_BEFORE_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_THROTTLE_INTERVAL_FOR_LOCATION_QUERY_MINUTES;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_CONFIG_DATA_UPDATED;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.GOOGLE_US_SAN_SAT_S2_FILE_NAME;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
 
@@ -369,6 +370,49 @@
     }
 
     @Test
+    public void testOnCurrentLocationNotAvailable() throws Exception {
+        // Verify the cache is used when the location is null and the cache is valid and true.
+        mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+                ALLOWED_STATE_CACHE_VALID_DURATION_NANOS - 1;
+        mSatelliteAccessControllerUT
+                .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_allowed");
+        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
+
+        sendCurrentLocationTimeoutEvent();
+        assertTrue(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
+
+        // Verify the cache is used when the location is null and the cache is valid and false.
+        mSatelliteAccessControllerUT
+                .setIsSatelliteCommunicationAllowedForCurrentLocationCache("cache_not_allowed");
+        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
+
+        sendCurrentLocationTimeoutEvent();
+        assertFalse(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
+
+        // Verify the result code is SATELLITE_RESULT_LOCATION_NOT_AVAILABLE
+        // and allowedState is false when the location is null and the cache is expired
+        mSatelliteAccessControllerUT.elapsedRealtimeNanos =
+                ALLOWED_STATE_CACHE_VALID_DURATION_NANOS + 1;
+        Iterator<ResultReceiver> mockIterator = mock(Iterator.class);
+        doReturn(mockIterator).when(mMockSatelliteAllowResultReceivers).iterator();
+        doReturn(true, false).when(mockIterator).hasNext();
+        doNothing().when(mMockSatelliteAllowResultReceivers).clear();
+        doReturn(mMockSatelliteSupportedResultReceiver).when(mockIterator).next();
+        replaceInstance(SatelliteAccessController.class, "mSatelliteAllowResultReceivers",
+                mSatelliteAccessControllerUT, mMockSatelliteAllowResultReceivers);
+        mSatelliteAccessControllerUT.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
+                "cache_clear_and_not_allowed");
+        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(false);
+
+        sendCurrentLocationTimeoutEvent();
+        verify(mMockSatelliteSupportedResultReceiver)
+                .send(mResultCodeIntCaptor.capture(), any());
+        assertEquals(Integer.valueOf(SATELLITE_RESULT_LOCATION_NOT_AVAILABLE),
+                mResultCodeIntCaptor.getValue());
+        assertFalse(mSatelliteAccessControllerUT.isCurrentSatelliteAllowedState());
+    }
+
+    @Test
     public void testIsSatelliteAccessAllowedForLocation() {
         when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
 
@@ -1056,7 +1100,7 @@
         // In emergency case,
         // verify if the location manager get FUSED provider and ignore location settings
         doReturn(true).when(mMockTelecomManager).isInEmergencyCall();
-        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull();
+        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionUsingGPS();
 
@@ -1074,7 +1118,7 @@
         doReturn(false).when(mMockPhone2).isInEcm();
         doReturn(false).when(mMockSatelliteController).isInEmergencyMode();
         doReturn(true).when(mMockLocationManager).isLocationEnabled();
-        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull();
+        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
         mSatelliteAccessControllerUT.checkSatelliteAccessRestrictionUsingGPS();
 
         verify(mMockLocationManager, times(1))
@@ -1173,7 +1217,7 @@
         doReturn(false).when(mMockPhone2).isInEcm();
         doReturn(false).when(mMockSatelliteController).isInEmergencyMode();
         doReturn(true).when(mMockLocationManager).isLocationEnabled();
-        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull();
+        mSatelliteAccessControllerUT.setLocationRequestCancellationSignalAsNull(true);
         mSatelliteAccessControllerUT.elapsedRealtimeNanos = TEST_LOCATION_FRESH_DURATION_NANOS + 1;
 
         // Invoking requestIsCommunicationAllowedForCurrentLocation(resultReceiver, "false");
@@ -1217,6 +1261,13 @@
         mTestableLooper.processAllMessages();
     }
 
+    private void sendCurrentLocationTimeoutEvent() {
+        Message msg = mSatelliteAccessControllerUT
+                .obtainMessage(EVENT_WAIT_FOR_CURRENT_LOCATION_TIMEOUT);
+        msg.sendToTarget();
+        mTestableLooper.processAllMessages();
+    }
+
     private void sendCommandValidateCountryCodeChangeEvent(Context context) {
         Message msg = mSatelliteAccessControllerUT.obtainMessage(EVENT_COUNTRY_CODE_CHANGED);
         msg.obj = new AsyncResult(context, SATELLITE_RESULT_SUCCESS, null);
@@ -1382,9 +1433,15 @@
             return mLocationModeChangedBroadcastReceiver;
         }
 
-        public void setLocationRequestCancellationSignalAsNull() {
+        public void setLocationRequestCancellationSignalAsNull(boolean isNull) {
             synchronized (mLock) {
-                mLocationRequestCancellationSignal = null;
+                mLocationRequestCancellationSignal = isNull ? null : new CancellationSignal();
+            }
+        }
+
+        public boolean isCurrentSatelliteAllowedState() {
+            synchronized (mSatelliteCommunicationAllowStateLock) {
+                return mCurrentSatelliteAllowedState;
             }
         }
     }