Cache the country iso in APM, and use it in EmergencyNumberTracker

Test: Treehugger; atest LocaleTrackerTest
Bug: 152246523
Change-Id: Ia5941ff7d8a92c59b82f606766f9b06830d00c07
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index 4c1d36e..afb0715 100755
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
@@ -126,6 +127,10 @@
     /** The maximum fail count to prevent delay time overflow */
     private static final int MAX_FAIL_COUNT = 30;
 
+    /** The last known country iso */
+    private static final String LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY =
+            "last_known_country_iso";
+
     private String mTag;
 
     private final Phone mPhone;
@@ -577,6 +582,11 @@
             mLocalLog.log(msg);
             mCurrentCountryIso = countryIso;
 
+            // Update the last known country ISO
+            if (!TextUtils.isEmpty(mCurrentCountryIso)) {
+                updateLastKnownCountryIso(mCurrentCountryIso);
+            }
+
             int phoneId = mPhone.getPhoneId();
             if (SubscriptionManager.isValidPhoneId(phoneId)) {
                 List<String> newProp = new ArrayList<>(
@@ -588,6 +598,8 @@
 
             Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
             intent.putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, countryIso);
+            intent.putExtra(TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY,
+                    getLastKnownCountryIso());
             SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
             mPhone.getContext().sendBroadcast(intent);
         }
@@ -624,6 +636,30 @@
         return mIsTracking;
     }
 
+    private void updateLastKnownCountryIso(String countryIso) {
+        if (!TextUtils.isEmpty(countryIso)) {
+            final SharedPreferences prefs = mPhone.getContext().getSharedPreferences(
+                    LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, Context.MODE_PRIVATE);
+            final SharedPreferences.Editor editor = prefs.edit();
+            editor.putString(LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, countryIso);
+            editor.commit();
+            log("update country iso in sharedPrefs " + countryIso);
+        }
+    }
+
+    /**
+     *  Return the last known country ISO before device is not camping on a network
+     *  (e.g. Airplane Mode)
+     *
+     *  @return The device's last known country ISO.
+     */
+    @NonNull
+    public String getLastKnownCountryIso() {
+        final SharedPreferences prefs = mPhone.getContext().getSharedPreferences(
+                LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, Context.MODE_PRIVATE);
+        return prefs.getString(LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, "");
+    }
+
     private void log(String msg) {
         Rlog.d(mTag, msg);
     }
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index 346bb85..a44560a 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -147,21 +147,13 @@
                     logd("ACTION_NETWORK_COUNTRY_CHANGED: PhoneId: " + phoneId + " CountryIso: "
                             + countryIso);
 
-                    boolean isInApm = false;
-                    ServiceStateTracker serviceStateTracker = mPhone.getServiceStateTracker();
-                    if (serviceStateTracker != null) {
-                        if (serviceStateTracker.getServiceState().getState()
-                                == ServiceState.STATE_POWER_OFF) {
-                            isInApm = true;
-                        }
-                    }
                     // Sometimes the country is updated as an empty string when the network signal
                     // is lost; though we may not call emergency when there is no signal, we want
                     // to keep the old country iso to provide country-related emergency numbers,
                     // because they think they are still in that country. We don't need to update
                     // country change in this case. We will still need to update the empty string
                     // if device is in APM.
-                    if (TextUtils.isEmpty(countryIso) && !isInApm) {
+                    if (TextUtils.isEmpty(countryIso) && !isAirplaneModeEnabled()) {
                         return;
                     }
 
@@ -271,12 +263,29 @@
         }
     }
 
+    private boolean isAirplaneModeEnabled() {
+        ServiceStateTracker serviceStateTracker = mPhone.getServiceStateTracker();
+        if (serviceStateTracker != null) {
+            if (serviceStateTracker.getServiceState().getState()
+                    == ServiceState.STATE_POWER_OFF) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void initializeDatabaseEmergencyNumberList() {
         // If country iso has been cached when listener is set, don't need to cache the initial
         // country iso and initial database.
         if (mCountryIso == null) {
-            updateEmergencyCountryIso(getInitialCountryIso().toLowerCase());
-            cacheEmergencyDatabaseByCountry(mCountryIso);
+            String countryForDatabaseCache = getInitialCountryIso().toLowerCase();
+            updateEmergencyCountryIso(countryForDatabaseCache);
+            // Use the last known country to cache the database in APM
+            if (TextUtils.isEmpty(countryForDatabaseCache)
+                    && isAirplaneModeEnabled()) {
+                countryForDatabaseCache = getCountryIsoForCachingDatabase();
+            }
+            cacheEmergencyDatabaseByCountry(countryForDatabaseCache);
         }
     }
 
@@ -567,6 +576,12 @@
         logd("updateEmergencyNumberListDatabaseAndNotify(): receiving countryIso: "
                 + countryIso);
         updateEmergencyCountryIso(countryIso.toLowerCase());
+        // Use cached country iso in APM to load emergency number database.
+        if (TextUtils.isEmpty(countryIso) && isAirplaneModeEnabled()) {
+            countryIso = getCountryIsoForCachingDatabase();
+            logd("updateEmergencyNumberListDatabaseAndNotify(): using cached APM country "
+                    + countryIso);
+        }
         cacheEmergencyDatabaseByCountry(countryIso);
         writeUpdatedEmergencyNumberListMetrics(mEmergencyNumberListFromDatabase);
         if (!DBG) {
@@ -783,6 +798,17 @@
         return mCountryIso;
     }
 
+    private String getCountryIsoForCachingDatabase() {
+        ServiceStateTracker sst = mPhone.getServiceStateTracker();
+        if (sst != null) {
+            LocaleTracker lt = sst.getLocaleTracker();
+            if (lt != null) {
+                return lt.getLastKnownCountryIso();
+            }
+        }
+        return "";
+    }
+
     public int getEmergencyNumberDbVersion() {
         return mCurrentDatabaseVersion;
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
index d9f5dfb..5b147c0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
@@ -173,6 +173,7 @@
         sendServiceState(ServiceState.STATE_IN_SERVICE);
         mLocaleTracker.updateOperatorNumeric(US_MCC + FAKE_MNC);
         assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+        assertEquals(US_COUNTRY_CODE, mLocaleTracker.getLastKnownCountryIso());
         verifyCountryCodeNotified(new String[]{COUNTRY_CODE_UNAVAILABLE, US_COUNTRY_CODE});
         assertFalse(mLocaleTracker.isTracking());
 
@@ -180,6 +181,7 @@
         mLocaleTracker.updateOperatorNumeric("");
         processAllMessages();
         assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+        assertEquals(US_COUNTRY_CODE, mLocaleTracker.getLastKnownCountryIso());
         verifyCountryCodeNotified(new String[]{COUNTRY_CODE_UNAVAILABLE, US_COUNTRY_CODE});
         sendServiceState(ServiceState.STATE_POWER_OFF);
         assertFalse(mLocaleTracker.isTracking());
@@ -188,6 +190,7 @@
         mLocaleTracker.updateOperatorNumeric("");
         processAllMessages();
         assertEquals(COUNTRY_CODE_UNAVAILABLE, mLocaleTracker.getCurrentCountry());
+        assertEquals(US_COUNTRY_CODE, mLocaleTracker.getLastKnownCountryIso());
         verifyCountryCodeNotified(new String[]{COUNTRY_CODE_UNAVAILABLE, US_COUNTRY_CODE,
                 COUNTRY_CODE_UNAVAILABLE});
     }