Loading services/core/java/com/android/server/location/GnssLocationProvider.java +3 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { Loading services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java +114 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading
services/core/java/com/android/server/location/GnssLocationProvider.java +3 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { Loading
services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java +114 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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, Loading