summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java6
-rw-r--r--services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java115
2 files changed, 117 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 58e332ab6d1d..c1fbcfba864a 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -653,9 +653,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
- mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
- GnssLocationProvider.this::onNetworkAvailable, mLooper);
-
// App ops service to keep track of who is accessing the GPS
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -677,6 +674,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
mNIHandler = new GpsNetInitiatedHandler(context,
mNetInitiatedListener,
mSuplEsEnabled);
+ mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
+ GnssLocationProvider.this::onNetworkAvailable, mLooper, mNIHandler);
+
sendMessage(INITIALIZE_HANDLER, 0, null);
mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
index 9ee9dcba9a81..5d6474bdbccc 100644
--- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -29,12 +29,22 @@ import android.os.PowerManager;
import android.provider.Telephony.Carriers;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.PreciseCallState;
+import android.telephony.PhoneStateListener;
import android.util.Log;
+import com.android.internal.location.GpsNetInitiatedHandler;
+
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
+import java.util.Map;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Iterator;
/**
* Handles network connection requests and network state change updates for AGPS data download.
@@ -86,6 +96,9 @@ class GnssNetworkConnectivityHandler {
private HashMap<Network, NetworkAttributes> mAvailableNetworkAttributes =
new HashMap<>(HASH_MAP_INITIAL_CAPACITY_TO_TRACK_CONNECTED_NETWORKS);
+ // Phone State Listeners to track all the active sub IDs
+ private HashMap<Integer, SubIdPhoneStateListener> mPhoneStateListeners;
+
private final ConnectivityManager mConnMgr;
private final Handler mHandler;
@@ -94,6 +107,9 @@ class GnssNetworkConnectivityHandler {
private int mAGpsDataConnectionState;
private InetAddress mAGpsDataConnectionIpAddr;
private int mAGpsType;
+ private int mActiveSubId = -1;
+ private final GpsNetInitiatedHandler mNiHandler;
+
private final Context mContext;
@@ -166,18 +182,109 @@ class GnssNetworkConnectivityHandler {
GnssNetworkConnectivityHandler(Context context,
GnssNetworkListener gnssNetworkListener,
- Looper looper) {
+ Looper looper,
+ GpsNetInitiatedHandler niHandler) {
mContext = context;
mGnssNetworkListener = gnssNetworkListener;
+ SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+ if (subManager != null) {
+ subManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
+ }
+
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
mHandler = new Handler(looper);
+ mNiHandler = niHandler;
mConnMgr = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
mSuplConnectivityCallback = createSuplConnectivityCallback();
}
+ /**
+ * SubId Phone State Listener is used cache the last active Sub ID when a call is made,
+ * which will be used during an emergency call to set the Network Specifier to the particular
+ * sub when an emergency supl connection is requested
+ */
+ private final class SubIdPhoneStateListener extends PhoneStateListener {
+ private Integer mSubId;
+ SubIdPhoneStateListener(Integer subId) {
+ mSubId = subId;
+ }
+ @Override
+ public void onPreciseCallStateChanged(PreciseCallState state) {
+ if (state.PRECISE_CALL_STATE_ACTIVE == state.getForegroundCallState()) {
+ mActiveSubId = mSubId;
+ if (DEBUG) Log.d(TAG, "mActiveSubId: " + mActiveSubId);
+ }
+ }
+ };
+
+ /**
+ * Subscription Changed Listener is used to get all active subscriptions and create a
+ * Phone State Listener for each Sub ID that we find in the active subscription list
+ */
+ private final SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangeListener
+ = new SubscriptionManager.OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ if (mPhoneStateListeners == null) {
+ // Capacity=2 Load-Factor=1.0, as typically no more than 2 SIMs
+ mPhoneStateListeners = new HashMap<Integer, SubIdPhoneStateListener>(2,1);
+ }
+ SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+ TelephonyManager telManager = mContext.getSystemService(TelephonyManager.class);
+ if (subManager != null && telManager != null) {
+ List<SubscriptionInfo> subscriptionInfoList =
+ subManager.getActiveSubscriptionInfoList();
+ HashSet<Integer> activeSubIds = new HashSet<Integer>();
+ if (subscriptionInfoList != null) {
+ if (DEBUG) Log.d(TAG, "Active Sub List size: " + subscriptionInfoList.size());
+ // populate phone state listeners with all new active subs
+ for (SubscriptionInfo subInfo : subscriptionInfoList) {
+ activeSubIds.add(subInfo.getSubscriptionId());
+ if (!mPhoneStateListeners.containsKey(subInfo.getSubscriptionId())) {
+ TelephonyManager subIdTelManager =
+ telManager.createForSubscriptionId(subInfo.getSubscriptionId());
+ if (subIdTelManager != null) {
+ if (DEBUG) Log.d(TAG, "Listener sub" + subInfo.getSubscriptionId());
+ SubIdPhoneStateListener subIdPhoneStateListener =
+ new SubIdPhoneStateListener(subInfo.getSubscriptionId());
+ mPhoneStateListeners.put(subInfo.getSubscriptionId(),
+ subIdPhoneStateListener);
+ subIdTelManager.listen(subIdPhoneStateListener,
+ PhoneStateListener.LISTEN_PRECISE_CALL_STATE);
+ }
+ }
+ }
+ }
+ // clean up phone state listeners than no longer have active subs
+ Iterator<Map.Entry<Integer, SubIdPhoneStateListener> > iterator =
+ mPhoneStateListeners.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<Integer, SubIdPhoneStateListener> element = iterator.next();
+ if (!activeSubIds.contains(element.getKey())) {
+ TelephonyManager subIdTelManager =
+ telManager.createForSubscriptionId(element.getKey());
+ if (subIdTelManager != null) {
+ if (DEBUG) Log.d(TAG, "unregister listener sub " + element.getKey());
+ subIdTelManager.listen(element.getValue(),
+ PhoneStateListener.LISTEN_NONE);
+ // removes the element from mPhoneStateListeners
+ iterator.remove();
+ } else {
+ Log.e(TAG, "Telephony Manager for Sub " + element.getKey() + " null");
+ }
+ }
+ }
+ // clean up cached active phone call sub if it is no longer an active sub
+ if (!activeSubIds.contains(mActiveSubId)) {
+ mActiveSubId = -1;
+ }
+ }
+ }
+ };
+
void registerNetworkCallbacks() {
// register for connectivity change events.
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
@@ -467,6 +574,12 @@ class GnssNetworkConnectivityHandler {
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
networkRequestBuilder.addCapability(getNetworkCapability(mAGpsType));
networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ // During an emergency call, and when we have cached the Active Sub Id, we set the
+ // Network Specifier so that the network request goes to the correct Sub Id
+ if (mNiHandler.getInEmergency() && mActiveSubId >= 0) {
+ if (DEBUG) Log.d(TAG, "Adding Network Specifier: " + Integer.toString(mActiveSubId));
+ networkRequestBuilder.setNetworkSpecifier(Integer.toString(mActiveSubId));
+ }
NetworkRequest networkRequest = networkRequestBuilder.build();
mConnMgr.requestNetwork(
networkRequest,