[Settings] Replacing accessing of PhoneConstants$DataState
1. Replaced by PhoneStateListner#onPreciseDataConnectionStateChanged().
2. Remove usage of hidden API SubscriptionManager#getPhoneId()
Bug: 147080692
Test: manual
Change-Id: I6e7c9910ed63e027fc02c1835853175745b31b66
diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java
index 94d7bca..eb6c9b1 100755
--- a/src/com/android/settings/network/ApnSettings.java
+++ b/src/com/android/settings/network/ApnSettings.java
@@ -38,6 +38,8 @@
import android.os.UserManager;
import android.provider.Telephony;
import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.PreciseDataConnectionState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -52,8 +54,6 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -107,6 +107,7 @@
private static boolean mRestoreDefaultApnMode;
private UserManager mUserManager;
+ private TelephonyManager mTelephonyManager;
private RestoreApnUiHandler mRestoreApnUiHandler;
private RestoreApnProcessHandler mRestoreApnProcessHandler;
private HandlerThread mRestoreDefaultApnThread;
@@ -130,32 +131,35 @@
super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
}
+ private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onPreciseDataConnectionStateChanged(
+ PreciseDataConnectionState dataConnectionState) {
+ if (dataConnectionState.getState() == TelephonyManager.DATA_CONNECTED) {
+ if (!mRestoreDefaultApnMode) {
+ fillList();
+ } else {
+ showDialog(DIALOG_RESTORE_DEFAULTAPN);
+ }
+ }
+ }
+ };
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
- TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
- PhoneConstants.DataState state = getMobileDataState(intent);
- switch (state) {
- case CONNECTED:
- if (!mRestoreDefaultApnMode) {
- fillList();
- } else {
- showDialog(DIALOG_RESTORE_DEFAULTAPN);
- }
- break;
- }
- } else if(intent.getAction().equals(
TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED)) {
if (!mRestoreDefaultApnMode) {
int extraSubId = intent.getIntExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (SubscriptionManager.isValidSubscriptionId(extraSubId) &&
- mPhoneId == SubscriptionManager.getPhoneId(extraSubId) &&
- extraSubId != mSubId) {
+ if (SubscriptionManager.isValidSubscriptionId(extraSubId)
+ && mPhoneId == SubscriptionUtil.getPhoneId(context, extraSubId)
+ && extraSubId != mSubId) {
// subscription has changed
mSubId = extraSubId;
mSubscriptionInfo = getSubscriptionInfo(mSubId);
+ restartPhoneStateListener(mSubId);
}
fillList();
}
@@ -163,13 +167,22 @@
}
};
- private static PhoneConstants.DataState getMobileDataState(Intent intent) {
- String str = intent.getStringExtra(PhoneConstants.STATE_KEY);
- if (str != null) {
- return Enum.valueOf(PhoneConstants.DataState.class, str);
- } else {
- return PhoneConstants.DataState.DISCONNECTED;
+ private void restartPhoneStateListener(int subId) {
+ if (mRestoreDefaultApnMode) {
+ return;
}
+
+ final TelephonyManager updatedTelephonyManager =
+ mTelephonyManager.createForSubscriptionId(subId);
+
+ // restart monitoring when subscription has been changed
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_NONE);
+
+ mTelephonyManager = updatedTelephonyManager;
+
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE);
}
@Override
@@ -183,14 +196,14 @@
final Activity activity = getActivity();
mSubId = activity.getIntent().getIntExtra(SUB_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+ mPhoneId = SubscriptionUtil.getPhoneId(activity, mSubId);
mIntentFilter = new IntentFilter(
- TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
- mIntentFilter.addAction(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);
+ TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);
setIfOnlyAvailableForAdmins(true);
mSubscriptionInfo = getSubscriptionInfo(mSubId);
+ mTelephonyManager = activity.getSystemService(TelephonyManager.class);
CarrierConfigManager configManager = (CarrierConfigManager)
getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -235,6 +248,8 @@
getActivity().registerReceiver(mReceiver, mIntentFilter);
+ restartPhoneStateListener(mSubId);
+
if (!mRestoreDefaultApnMode) {
fillList();
}
@@ -249,6 +264,9 @@
}
getActivity().unregisterReceiver(mReceiver);
+
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_NONE);
}
@Override
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 9007c0b..f0c1583 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -16,15 +16,18 @@
package com.android.settings.network;
+import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
import static com.android.internal.util.CollectionUtils.emptyIfNull;
import android.content.Context;
+import android.os.ParcelUuid;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.UiccSlotInfo;
+import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
@@ -66,6 +69,12 @@
slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT;
}
+ /**
+ * Get all of the subscriptions which is available to display to the user.
+ *
+ * @param context {@code Context}
+ * @return list of {@code SubscriptionInfo}
+ */
public static List<SubscriptionInfo> getAvailableSubscriptions(Context context) {
if (sAvailableResultsForTesting != null) {
return sAvailableResultsForTesting;
@@ -73,12 +82,12 @@
final SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class);
final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
- List<SubscriptionInfo> subscriptions =
+ final List<SubscriptionInfo> subscriptions =
new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList()));
// Look for inactive but present physical SIMs that are missing from the selectable list.
final List<UiccSlotInfo> missing = new ArrayList<>();
- UiccSlotInfo[] slotsInfo = telMgr.getUiccSlotsInfo();
+ final UiccSlotInfo[] slotsInfo = telMgr.getUiccSlotsInfo();
for (int i = 0; slotsInfo != null && i < slotsInfo.length; i++) {
final UiccSlotInfo slotInfo = slotsInfo[i];
if (isInactiveInsertedPSim(slotInfo)) {
@@ -92,20 +101,164 @@
}
}
}
- if (!missing.isEmpty()) {
- for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) {
- for (UiccSlotInfo slotInfo : missing) {
- if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() &&
- info.getCardString().equals(slotInfo.getCardId())) {
- subscriptions.add(info);
- break;
- }
+ if (missing.isEmpty()) {
+ return subscriptions;
+ }
+ for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) {
+ for (UiccSlotInfo slotInfo : missing) {
+ if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx()
+ && info.getCardString().equals(slotInfo.getCardId())) {
+ subscriptions.add(info);
+ break;
}
}
}
return subscriptions;
}
+ /**
+ * Get subscription which is available to be displayed to the user
+ * per subscription id.
+ *
+ * @param context {@code Context}
+ * @param subscriptionManager The ProxySubscriptionManager for accessing subcription
+ * information
+ * @param subId The id of subscription to be retrieved
+ * @return {@code SubscriptionInfo} based on the given subscription id. Null of subscription
+ * is invalid or not allowed to be displayed to the user.
+ */
+ public static SubscriptionInfo getAvailableSubscription(Context context,
+ ProxySubscriptionManager subscriptionManager, int subId) {
+ final SubscriptionInfo subInfo = subscriptionManager.getAccessibleSubscriptionInfo(subId);
+ if (subInfo == null) {
+ return null;
+ }
+
+ final ParcelUuid groupUuid = subInfo.getGroupUuid();
+
+ if (groupUuid != null) {
+ if (isPrimarySubscriptionWithinSameUuid(getUiccSlotsInfo(context), groupUuid,
+ subscriptionManager.getAccessibleSubscriptionsInfo(), subId)) {
+ return subInfo;
+ }
+ return null;
+ }
+
+ if (subInfo.isEmbedded()) {
+ return subInfo;
+ }
+
+ // Look for physical SIM which presented in slots no mater active or not.
+ final UiccSlotInfo[] slotsInfo = getUiccSlotsInfo(context);
+ if (slotsInfo == null) {
+ return null;
+ }
+ for (UiccSlotInfo slotInfo : slotsInfo) {
+ if ((!slotInfo.getIsEuicc())
+ && (slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT)
+ && (slotInfo.getLogicalSlotIdx() == subInfo.getSimSlotIndex())
+ && TextUtils.equals(slotInfo.getCardId(), subInfo.getCardString())) {
+ return subInfo;
+ }
+ }
+ return null;
+ }
+
+ private static UiccSlotInfo [] getUiccSlotsInfo(Context context) {
+ final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
+ return telMgr.getUiccSlotsInfo();
+ }
+
+ private static boolean isPrimarySubscriptionWithinSameUuid(UiccSlotInfo[] slotsInfo,
+ ParcelUuid groupUuid, List<SubscriptionInfo> subscriptions, int subId) {
+ // only interested in subscriptions with this group UUID
+ final ArrayList<SubscriptionInfo> physicalSubInfoList =
+ new ArrayList<SubscriptionInfo>();
+ final ArrayList<SubscriptionInfo> nonOpportunisticSubInfoList =
+ new ArrayList<SubscriptionInfo>();
+ final ArrayList<SubscriptionInfo> activeSlotSubInfoList =
+ new ArrayList<SubscriptionInfo>();
+ final ArrayList<SubscriptionInfo> inactiveSlotSubInfoList =
+ new ArrayList<SubscriptionInfo>();
+ for (SubscriptionInfo subInfo : subscriptions) {
+ if (groupUuid.equals(subInfo.getGroupUuid())) {
+ if (!subInfo.isEmbedded()) {
+ physicalSubInfoList.add(subInfo);
+ } else {
+ if (!subInfo.isOpportunistic()) {
+ nonOpportunisticSubInfoList.add(subInfo);
+ }
+ if (subInfo.getSimSlotIndex()
+ != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+ activeSlotSubInfoList.add(subInfo);
+ } else {
+ inactiveSlotSubInfoList.add(subInfo);
+ }
+ }
+ }
+ }
+
+ // find any physical SIM which is currently inserted within logical slot
+ // and which is our target subscription
+ if ((slotsInfo != null) && (physicalSubInfoList.size() > 0)) {
+ final SubscriptionInfo subInfo = searchForSubscriptionId(physicalSubInfoList, subId);
+ if (subInfo == null) {
+ return false;
+ }
+ // verify if subscription is inserted within slot
+ for (UiccSlotInfo slotInfo : slotsInfo) {
+ if ((slotInfo != null) && (!slotInfo.getIsEuicc())
+ && (slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT)
+ && (slotInfo.getLogicalSlotIdx() == subInfo.getSimSlotIndex())
+ && TextUtils.equals(slotInfo.getCardId(), subInfo.getCardString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // When all of the eSIM profiles are opprtunistic and no physical SIM,
+ // first opportunistic subscriptions with same group UUID can be primary.
+ if (nonOpportunisticSubInfoList.size() <= 0) {
+ if (physicalSubInfoList.size() > 0) {
+ return false;
+ }
+ if (activeSlotSubInfoList.size() > 0) {
+ return (activeSlotSubInfoList.get(0).getSubscriptionId() == subId);
+ }
+ return (inactiveSlotSubInfoList.get(0).getSubscriptionId() == subId);
+ }
+
+ // Allow non-opportunistic + active eSIM subscription as primary
+ int numberOfActiveNonOpportunisticSubs = 0;
+ boolean isTargetNonOpportunistic = false;
+ for (SubscriptionInfo subInfo : nonOpportunisticSubInfoList) {
+ final boolean isTargetSubInfo = (subInfo.getSubscriptionId() == subId);
+ if (subInfo.getSimSlotIndex() != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+ if (isTargetSubInfo) {
+ return true;
+ }
+ numberOfActiveNonOpportunisticSubs++;
+ } else {
+ isTargetNonOpportunistic |= isTargetSubInfo;
+ }
+ }
+ if (numberOfActiveNonOpportunisticSubs > 0) {
+ return false;
+ }
+ return isTargetNonOpportunistic;
+ }
+
+ private static SubscriptionInfo searchForSubscriptionId(List<SubscriptionInfo> subInfoList,
+ int subscriptionId) {
+ for (SubscriptionInfo subInfo : subInfoList) {
+ if (subInfo.getSubscriptionId() == subscriptionId) {
+ return subInfo;
+ }
+ }
+ return null;
+ }
+
public static String getDisplayName(SubscriptionInfo info) {
final CharSequence name = info.getDisplayName();
if (name != null) {
@@ -113,4 +266,26 @@
}
return "";
}
+
+ /**
+ * Whether Settings should show a "Use SIM" toggle in pSIM detailed page.
+ */
+ public static boolean showToggleForPhysicalSim(SubscriptionManager subMgr) {
+ return subMgr.canDisablePhysicalSubscription();
+ }
+
+ /**
+ * Get phoneId or logical slot index for a subId if active, or INVALID_PHONE_INDEX if inactive.
+ */
+ public static int getPhoneId(Context context, int subId) {
+ final SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
+ if (subManager == null) {
+ return INVALID_SIM_SLOT_INDEX;
+ }
+ final SubscriptionInfo info = subManager.getActiveSubscriptionInfo(subId);
+ if (info == null) {
+ return INVALID_SIM_SLOT_INDEX;
+ }
+ return info.getSimSlotIndex();
+ }
}