Merge "Handle emergency SUPL on active SIM" into tm-d1-dev am: 45811541cf

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19290988

Change-Id: I0daaf96ba8ff6b2eaa2d138f9b1afe2dbcc94a52
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 190e1cc..fba4249 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -142,6 +142,14 @@
         public int textEncoding;
     }
 
+    /** Callbacks for Emergency call events. */
+    public interface EmergencyCallCallback {
+        /** Callback invoked when an emergency call starts */
+        void onEmergencyCallStart(int subId);
+        /** Callback invoked when an emergency call ends */
+        void onEmergencyCallEnd();
+    }
+
     private class EmergencyCallListener extends TelephonyCallback implements
             TelephonyCallback.OutgoingEmergencyCallListener,
             TelephonyCallback.CallStateListener {
@@ -152,6 +160,7 @@
                 int subscriptionId) {
             mIsInEmergencyCall = true;
             if (DEBUG) Log.d(TAG, "onOutgoingEmergencyCall(): inEmergency = " + getInEmergency());
+            mEmergencyCallCallback.onEmergencyCallStart(subscriptionId);
         }
 
         @Override
@@ -163,6 +172,7 @@
                 if (mIsInEmergencyCall) {
                     mCallEndElapsedRealtimeMillis = SystemClock.elapsedRealtime();
                     mIsInEmergencyCall = false;
+                    mEmergencyCallCallback.onEmergencyCallEnd();
                 }
             }
         }
@@ -180,8 +190,11 @@
      */
     private Notification.Builder mNiNotificationBuilder;
 
+    private final EmergencyCallCallback mEmergencyCallCallback;
+
     public GpsNetInitiatedHandler(Context context,
                                   INetInitiatedListener netInitiatedListener,
+                                  EmergencyCallCallback emergencyCallCallback,
                                   boolean isSuplEsEnabled) {
         mContext = context;
 
@@ -190,6 +203,7 @@
         } else {
             mNetInitiatedListener = netInitiatedListener;
         }
+        mEmergencyCallCallback = emergencyCallCallback;
 
         setSuplEsEnabled(isSuplEsEnabled);
         mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index 12f8776..1435016 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -21,6 +21,7 @@
 import android.os.SystemProperties;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -73,6 +74,8 @@
     static final String CONFIG_NFW_PROXY_APPS = "NFW_PROXY_APPS";
     private static final String CONFIG_ENABLE_PSDS_PERIODIC_DOWNLOAD =
             "ENABLE_PSDS_PERIODIC_DOWNLOAD";
+    private static final String CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL =
+            "ENABLE_ACTIVE_SIM_EMERGENCY_SUPL";
     static final String CONFIG_LONGTERM_PSDS_SERVER_1 = "LONGTERM_PSDS_SERVER_1";
     static final String CONFIG_LONGTERM_PSDS_SERVER_2 = "LONGTERM_PSDS_SERVER_2";
     static final String CONFIG_LONGTERM_PSDS_SERVER_3 = "LONGTERM_PSDS_SERVER_3";
@@ -207,6 +210,14 @@
     }
 
     /**
+     * Returns true if during an emergency call, the GnssConfiguration of the activeSubId will be
+     * injected for the emergency SUPL flow; Returns false otherwise. Default false if not set.
+     */
+    boolean isActiveSimEmergencySuplEnabled() {
+        return getBooleanConfig(CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL, false);
+    }
+
+    /**
      * Returns true if a long-term PSDS server is configured.
      */
     boolean isLongTermPsdsServerConfigured() {
@@ -232,16 +243,31 @@
 
     /**
      * Loads the GNSS properties from carrier config file followed by the properties from
-     * gps debug config file.
+     * gps debug config file, and injects the GNSS properties into the HAL.
      */
     void reloadGpsProperties() {
-        if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + mProperties.size());
-        loadPropertiesFromCarrierConfig();
+        reloadGpsProperties(/* inEmergency= */ false, /* activeSubId= */ -1);
+    }
 
-        String lpp_prof = SystemProperties.get(LPP_PROFILE);
-        if (!TextUtils.isEmpty(lpp_prof)) {
-            // override default value of this if lpp_prof is not empty
-            mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+    /**
+     * Loads the GNSS properties from carrier config file followed by the properties from
+     * gps debug config file, and injects the GNSS properties into the HAL.
+     */
+    void reloadGpsProperties(boolean inEmergency, int activeSubId) {
+        if (DEBUG) {
+            Log.d(TAG,
+                    "Reset GPS properties, previous size = " + mProperties.size() + ", inEmergency:"
+                            + inEmergency + ", activeSubId=" + activeSubId);
+        }
+        loadPropertiesFromCarrierConfig(inEmergency, activeSubId);
+
+        if (isSimAbsent(mContext)) {
+            // Use the default SIM's LPP profile when SIM is absent.
+            String lpp_prof = SystemProperties.get(LPP_PROFILE);
+            if (!TextUtils.isEmpty(lpp_prof)) {
+                // override default value of this if lpp_prof is not empty
+                mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+            }
         }
 
         /*
@@ -322,16 +348,19 @@
     /**
      * Loads GNSS properties from carrier config file.
      */
-    void loadPropertiesFromCarrierConfig() {
+    void loadPropertiesFromCarrierConfig(boolean inEmergency, int activeSubId) {
         CarrierConfigManager configManager = (CarrierConfigManager)
                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager == null) {
             return;
         }
 
-        int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
-        PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(ddSubId)
-                ? configManager.getConfigForSubId(ddSubId) : configManager.getConfig();
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (inEmergency && activeSubId >= 0) {
+            subId = activeSubId;
+        }
+        PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(subId)
+                ? configManager.getConfigForSubId(subId) : configManager.getConfig();
         if (configs == null) {
             if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config.");
             configs = CarrierConfigManager.getDefaultConfig();
@@ -422,6 +451,12 @@
         return gnssConfiguartionIfaceVersion.mMajor < 2;
     }
 
+    private static boolean isSimAbsent(Context context) {
+        TelephonyManager phone = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        return phone.getSimState() == TelephonyManager.SIM_STATE_ABSENT;
+    }
+
     private static native HalInterfaceVersion native_get_gnss_configuration_version();
 
     private static native boolean native_set_supl_version(int version);
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index f5c2bbc..a6a3db1 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -126,6 +126,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 /**
  * A GNSS implementation of LocationProvider used by LocationManager.
@@ -359,8 +360,9 @@
                 }
             }
             if (isKeepLppProfile) {
-                // load current properties for the carrier
-                mGnssConfiguration.loadPropertiesFromCarrierConfig();
+                // load current properties for the carrier of ddSubId
+                mGnssConfiguration.loadPropertiesFromCarrierConfig(/* inEmergency= */ false,
+                        /* activeSubId= */ -1);
                 String lpp_profile = mGnssConfiguration.getLppProfile();
                 // set the persist property LPP_PROFILE for the value
                 if (lpp_profile != null) {
@@ -431,13 +433,38 @@
         // this approach is just fine because events are posted to our handler anyway
         mGnssConfiguration = mGnssNative.getConfiguration();
         // Create a GPS net-initiated handler (also needed by handleInitialize)
+        GpsNetInitiatedHandler.EmergencyCallCallback emergencyCallCallback =
+                new GpsNetInitiatedHandler.EmergencyCallCallback() {
+
+                    @Override
+                    public void onEmergencyCallStart(int subId) {
+                        if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+                            return;
+                        }
+                        mHandler.post(() -> mGnssConfiguration.reloadGpsProperties(
+                                mNIHandler.getInEmergency(), subId));
+                    }
+
+                    @Override
+                    public void onEmergencyCallEnd() {
+                        if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+                            return;
+                        }
+                        mHandler.postDelayed(() -> mGnssConfiguration.reloadGpsProperties(
+                                        /* inEmergency= */ false,
+                                        SubscriptionManager.getDefaultDataSubscriptionId()),
+                                TimeUnit.SECONDS.toMillis(mGnssConfiguration.getEsExtensionSec()));
+                    }
+                };
         mNIHandler = new GpsNetInitiatedHandler(context,
                 mNetInitiatedListener,
+                emergencyCallCallback,
                 mSuplEsEnabled);
         // Trigger PSDS data download when the network comes up after booting.
         mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
         mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
-                GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler);
+                GnssLocationProvider.this::onNetworkAvailable,
+                mHandler.getLooper(), mNIHandler);
 
         mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this);
         mGnssSatelliteBlocklistHelper =
@@ -1694,9 +1721,12 @@
         int type = AGPS_SETID_TYPE_NONE;
         String setId = null;
 
-        int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
-        if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
-            phone = phone.createForSubscriptionId(ddSubId);
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (mNIHandler.getInEmergency() && mNetworkConnectivityHandler.getActiveSubId() >= 0) {
+            subId = mNetworkConnectivityHandler.getActiveSubId();
+        }
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            phone = phone.createForSubscriptionId(subId);
         }
         if ((flags & AGPS_REQUEST_SETID_IMSI) == AGPS_REQUEST_SETID_IMSI) {
             setId = phone.getSubscriberId();
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index aba7572..6f890cd 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -190,7 +190,7 @@
         mContext = context;
         mGnssNetworkListener = gnssNetworkListener;
 
-    SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
         if (subManager != null) {
             subManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
         }
@@ -311,6 +311,13 @@
     }
 
     /**
+     * Returns the active Sub ID for emergency SUPL connection.
+     */
+    int getActiveSubId() {
+        return mActiveSubId;
+    }
+
+    /**
      * Called from native code to update AGPS connection status, or to request or release a SUPL
      * connection.
      *