Set the Network Specifier on Emergency SUPL am: dffe0cee3c

Change-Id: I8925a5abffd0a72acb14072b70d2ef033bf16836
This commit is contained in:
Dante Russo
2020-03-25 12:48:23 +00:00
committed by Automerger Merge Worker
2 changed files with 117 additions and 4 deletions

View File

@@ -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) {

View File

@@ -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,