From fb4a0c25e0931d049221f27145a20377cce2bd2f Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Fri, 29 May 2020 14:53:43 +0800 Subject: [PATCH] [Settings] Avoid crash when switch SIM during PIN lock PIN lock status are stored without subscription ID mapping on it. Which makes SIM status change can't be processed correctly. Through storing the subscription ID for PIN lock screen, dialog can be reset when SIM status changed and crash can be avoided. Bug: 155852345 Test: manual Change-Id: Ic520bc34c5a460b4fcd199cd524b180d307e9ab4 --- src/com/android/settings/IccLockSettings.java | 187 ++++++++++++------ 1 file changed, 124 insertions(+), 63 deletions(-) diff --git a/src/com/android/settings/IccLockSettings.java b/src/com/android/settings/IccLockSettings.java index 4d12043f1b2..77cc03e92e7 100644 --- a/src/com/android/settings/IccLockSettings.java +++ b/src/com/android/settings/IccLockSettings.java @@ -87,6 +87,7 @@ public class IccLockSettings extends SettingsPreferenceFragment private static final String PIN_DIALOG = "sim_pin"; private static final String PIN_TOGGLE = "sim_toggle"; // Keys in icicle + private static final String DIALOG_SUB_ID = "dialogSubId"; private static final String DIALOG_STATE = "dialogState"; private static final String DIALOG_PIN = "dialogPin"; private static final String DIALOG_ERROR = "dialogError"; @@ -127,7 +128,7 @@ public class IccLockSettings extends SettingsPreferenceFragment // @see android.widget.Toast$TN private static final long LONG_DURATION_TIMEOUT = 7000; - private int mSlotId; + private int mSlotId = -1; private int mSubId; private TelephonyManager mTelephonyManager; @@ -155,7 +156,7 @@ public class IccLockSettings extends SettingsPreferenceFragment // For top-level settings screen to query private boolean isIccLockEnabled() { - mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId); + mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId); return mTelephonyManager.isIccLockEnabled(); } @@ -187,27 +188,13 @@ public class IccLockSettings extends SettingsPreferenceFragment mPinDialog = (EditPinPreference) findPreference(PIN_DIALOG); mPinToggle = (SwitchPreference) findPreference(PIN_TOGGLE); - if (savedInstanceState != null && savedInstanceState.containsKey(DIALOG_STATE)) { - mDialogState = savedInstanceState.getInt(DIALOG_STATE); - mPin = savedInstanceState.getString(DIALOG_PIN); - mError = savedInstanceState.getString(DIALOG_ERROR); - mToState = savedInstanceState.getBoolean(ENABLE_TO_STATE); - - // Restore inputted PIN code - switch (mDialogState) { - case ICC_NEW_MODE: - mOldPin = savedInstanceState.getString(OLD_PINCODE); - break; - - case ICC_REENTER_MODE: - mOldPin = savedInstanceState.getString(OLD_PINCODE); - mNewPin = savedInstanceState.getString(NEW_PINCODE); - break; - - case ICC_LOCK_MODE: - case ICC_OLD_MODE: - default: - break; + if (savedInstanceState != null) { + if (savedInstanceState.containsKey(DIALOG_STATE) + && restoreDialogStates(savedInstanceState)) { + Log.d(TAG, "onCreate: restore dialog for slotId=" + mSlotId + ", subId=" + mSubId); + } else if (savedInstanceState.containsKey(CURRENT_TAB) + && restoreTabFocus(savedInstanceState)) { + Log.d(TAG, "onCreate: restore focus on slotId=" + mSlotId + ", subId=" + mSubId); } } @@ -219,29 +206,75 @@ public class IccLockSettings extends SettingsPreferenceFragment mRes = getResources(); } + private boolean restoreDialogStates(Bundle savedInstanceState) { + final SubscriptionInfo subInfo = mProxySubscriptionMgr + .getActiveSubscriptionInfo(savedInstanceState.getInt(DIALOG_SUB_ID)); + if (subInfo == null) { + return false; + } + + final SubscriptionInfo visibleSubInfo = getVisibleSubscriptionInfoForSimSlotIndex( + subInfo.getSimSlotIndex()); + if (visibleSubInfo == null) { + return false; + } + if (visibleSubInfo.getSubscriptionId() != subInfo.getSubscriptionId()) { + return false; + } + + mSlotId = subInfo.getSimSlotIndex(); + mSubId = subInfo.getSubscriptionId(); + mDialogState = savedInstanceState.getInt(DIALOG_STATE); + mPin = savedInstanceState.getString(DIALOG_PIN); + mError = savedInstanceState.getString(DIALOG_ERROR); + mToState = savedInstanceState.getBoolean(ENABLE_TO_STATE); + + // Restore inputted PIN code + switch (mDialogState) { + case ICC_NEW_MODE: + mOldPin = savedInstanceState.getString(OLD_PINCODE); + break; + + case ICC_REENTER_MODE: + mOldPin = savedInstanceState.getString(OLD_PINCODE); + mNewPin = savedInstanceState.getString(NEW_PINCODE); + break; + } + return true; + } + + private boolean restoreTabFocus(Bundle savedInstanceState) { + int slotId = 0; + try { + slotId = Integer.parseInt(savedInstanceState.getString(CURRENT_TAB)); + } catch (NumberFormatException exception) { + return false; + } + + final SubscriptionInfo subInfo = getVisibleSubscriptionInfoForSimSlotIndex(slotId); + if (subInfo == null) { + return false; + } + + mSlotId = subInfo.getSimSlotIndex(); + mSubId = subInfo.getSubscriptionId(); + if (mTabHost != null) { + mTabHost.setCurrentTabByTag(getTagForSlotId(mSlotId)); + } + return true; + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final int numSims = mProxySubscriptionMgr.getActiveSubscriptionInfoCountMax(); - final List subInfoList = - mProxySubscriptionMgr.getActiveSubscriptionsInfo(); - mSlotId = 0; final List componenterList = new ArrayList<>(); for (int i = 0; i < numSims; ++i) { - final SubscriptionInfo subInfo = - getActiveSubscriptionInfoForSimSlotIndex(subInfoList, i); + final SubscriptionInfo subInfo = getVisibleSubscriptionInfoForSimSlotIndex(i); if (subInfo != null) { - final CarrierConfigManager carrierConfigManager = getContext().getSystemService( - CarrierConfigManager.class); - final PersistableBundle bundle = carrierConfigManager.getConfigForSubId( - subInfo.getSubscriptionId()); - if (bundle != null - && !bundle.getBoolean(CarrierConfigManager - .KEY_HIDE_SIM_LOCK_SETTINGS_BOOL)) { - componenterList.add(subInfo); - } + componenterList.add(subInfo); } } @@ -250,6 +283,12 @@ public class IccLockSettings extends SettingsPreferenceFragment return super.onCreateView(inflater, container, savedInstanceState); } + if (mSlotId < 0) { + mSlotId = componenterList.get(0).getSimSlotIndex(); + mSubId = componenterList.get(0).getSubscriptionId(); + Log.d(TAG, "onCreateView: default slotId=" + mSlotId + ", subId=" + mSubId); + } + if (componenterList.size() > 1) { final View view = inflater.inflate(R.layout.icc_lock_tabs, container, false); final ViewGroup prefs_container = (ViewGroup) view.findViewById(R.id.prefs_container); @@ -262,25 +301,21 @@ public class IccLockSettings extends SettingsPreferenceFragment mListView = (ListView) view.findViewById(android.R.id.list); mTabHost.setup(); - mTabHost.setOnTabChangedListener(mTabListener); mTabHost.clearAllTabs(); for (SubscriptionInfo subInfo : componenterList) { - int slot = subInfo.getSimSlotIndex(); - mTabHost.addTab(buildTabSpec(String.valueOf(slot), + final int slot = subInfo.getSimSlotIndex(); + final String tag = getTagForSlotId(slot); + mTabHost.addTab(buildTabSpec(tag, String.valueOf(subInfo == null ? getContext().getString(R.string.sim_editor_title, slot + 1) : subInfo.getDisplayName()))); } - mSubId = componenterList.get(0).getSubscriptionId(); - - if (savedInstanceState != null && savedInstanceState.containsKey(CURRENT_TAB)) { - mTabHost.setCurrentTabByTag(savedInstanceState.getString(CURRENT_TAB)); - } + mTabHost.setCurrentTabByTag(getTagForSlotId(mSlotId)); + mTabHost.setOnTabChangedListener(mTabListener); return view; } else { - mSlotId = componenterList.get(0).getSimSlotIndex(); return super.onCreateView(inflater, container, savedInstanceState); } } @@ -293,17 +328,20 @@ public class IccLockSettings extends SettingsPreferenceFragment private void updatePreferences() { - final List subInfoList = - mProxySubscriptionMgr.getActiveSubscriptionsInfo(); - final SubscriptionInfo sir = getActiveSubscriptionInfoForSimSlotIndex(subInfoList, mSlotId); - mSubId = (sir == null) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID - : sir.getSubscriptionId(); + final SubscriptionInfo sir = getVisibleSubscriptionInfoForSimSlotIndex(mSlotId); + final int subId = (sir != null) ? sir.getSubscriptionId() + : SubscriptionManager.INVALID_SUBSCRIPTION_ID; + + if (mSubId != subId) { + mSubId = subId; + resetDialogState(); + if ((mPinDialog != null) && mPinDialog.isDialogOpen()) { + mPinDialog.getDialog().dismiss(); + } + } if (mPinDialog != null) { mPinDialog.setEnabled(sir != null); - if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - mPinDialog.getDialog().dismiss(); - } } if (mPinToggle != null) { mPinToggle.setEnabled(sir != null); @@ -355,6 +393,7 @@ public class IccLockSettings extends SettingsPreferenceFragment // dialog state. In other cases, where this activity manually launches // the dialog, store the state of the dialog. if (mPinDialog.isDialogOpen()) { + out.putInt(DIALOG_SUB_ID, mSubId); out.putInt(DIALOG_STATE, mDialogState); out.putString(DIALOG_PIN, mPinDialog.getEditText().getText().toString()); out.putString(DIALOG_ERROR, mError); @@ -370,11 +409,6 @@ public class IccLockSettings extends SettingsPreferenceFragment out.putString(OLD_PINCODE, mOldPin); out.putString(NEW_PINCODE, mNewPin); break; - - case ICC_LOCK_MODE: - case ICC_OLD_MODE: - default: - break; } } else { super.onSaveInstanceState(out); @@ -672,23 +706,50 @@ public class IccLockSettings extends SettingsPreferenceFragment mDialogState = OFF_MODE; } - private static SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex( - List subInfoList, int slotId) { + private String getTagForSlotId(int slotId) { + return String.valueOf(slotId); + } + + private int getSlotIndexFromTag(String tag) { + int slotId = -1; + try { + slotId = Integer.parseInt(tag); + } catch (NumberFormatException exception) { + } + return slotId; + } + + private SubscriptionInfo getVisibleSubscriptionInfoForSimSlotIndex(int slotId) { + final List subInfoList = + mProxySubscriptionMgr.getActiveSubscriptionsInfo(); if (subInfoList == null) { return null; } + final CarrierConfigManager carrierConfigManager = getContext().getSystemService( + CarrierConfigManager.class); for (SubscriptionInfo subInfo : subInfoList) { - if (subInfo.getSimSlotIndex() == slotId) { + if ((isSubscriptionVisible(carrierConfigManager, subInfo) + && (subInfo.getSimSlotIndex() == slotId))) { return subInfo; } } return null; } + private boolean isSubscriptionVisible(CarrierConfigManager carrierConfigManager, + SubscriptionInfo subInfo) { + final PersistableBundle bundle = carrierConfigManager + .getConfigForSubId(subInfo.getSubscriptionId()); + if (bundle == null) { + return false; + } + return !bundle.getBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL); + } + private OnTabChangeListener mTabListener = new OnTabChangeListener() { @Override public void onTabChanged(String tabId) { - mSlotId = Integer.parseInt(tabId); + mSlotId = getSlotIndexFromTag(tabId); // The User has changed tab; update the body. updatePreferences();