Merge "[Settings] Avoid from immediate update when UI inactive and SIM absent" into sc-qpr1-dev
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index c6fe39c..efb5f8c 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -39,7 +39,6 @@
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle;
-import com.android.internal.util.CollectionUtils;
import com.android.settings.R;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.network.ProxySubscriptionManager;
@@ -48,6 +47,7 @@
import com.android.settings.network.helper.SubscriptionAnnotation;
import java.util.List;
+import java.util.function.Function;
/**
* Activity for displaying MobileNetworkSettings
@@ -64,15 +64,14 @@
@VisibleForTesting
ProxySubscriptionManager mProxySubscriptionMgr;
- private int mCurSubscriptionId;
+ private int mCurSubscriptionId = SUB_ID_NULL;
// This flag forces subscription information fragment to be re-created.
// Otherwise, fragment will be kept when subscription id has not been changed.
//
// Set initial value to true allows subscription information fragment to be re-created when
// Activity re-create occur.
- private boolean mFragmentForceReload = true;
- private boolean mPendingSubscriptionChange = false;
+ private boolean mPendingSubscriptionChange = true;
@Override
protected void onNewIntent(Intent intent) {
@@ -80,21 +79,25 @@
validate(intent);
setIntent(intent);
- int updateSubscriptionIndex = SUB_ID_NULL;
+ int updateSubscriptionIndex = mCurSubscriptionId;
if (intent != null) {
updateSubscriptionIndex = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
}
+ SubscriptionInfo info = getSubscriptionOrDefault(updateSubscriptionIndex);
+ if (info == null) {
+ Log.d(TAG, "Invalid subId request " + mCurSubscriptionId
+ + " -> " + updateSubscriptionIndex);
+ return;
+ }
+
int oldSubId = mCurSubscriptionId;
- mCurSubscriptionId = updateSubscriptionIndex;
- mFragmentForceReload = (mCurSubscriptionId == oldSubId);
- final SubscriptionInfo info = getSubscription();
updateSubscriptions(info, null);
// If the subscription has changed or the new intent doesnt contain the opt in action,
// remove the old discovery dialog. If the activity is being recreated, we will see
// onCreate -> onNewIntent, so the dialog will first be recreated for the old subscription
// and then removed.
- if (updateSubscriptionIndex != oldSubId || !doesIntentContainOptInAction(intent)) {
+ if (mCurSubscriptionId != oldSubId || !doesIntentContainOptInAction(intent)) {
removeContactDiscoveryDialog(oldSubId);
}
// evaluate showing the new discovery dialog if this intent contains an action to show the
@@ -135,7 +138,13 @@
// perform registration after mCurSubscriptionId been configured.
registerActiveSubscriptionsListener();
- final SubscriptionInfo subscription = getSubscription();
+ SubscriptionInfo subscription = getSubscriptionOrDefault(mCurSubscriptionId);
+ if (subscription == null) {
+ Log.d(TAG, "Invalid subId request " + mCurSubscriptionId);
+ tryToFinishActivity();
+ return;
+ }
+
maybeShowContactDiscoveryDialog(subscription);
updateSubscriptions(subscription, null);
@@ -158,39 +167,81 @@
* Implementation of ProxySubscriptionManager.OnActiveSubscriptionChangedListener
*/
public void onChanged() {
+ mPendingSubscriptionChange = false;
+
+ if (mCurSubscriptionId == SUB_ID_NULL) {
+ return;
+ }
+
if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
mPendingSubscriptionChange = true;
return;
}
- SubscriptionInfo info = getSubscription();
- int oldSubIndex = mCurSubscriptionId;
- updateSubscriptions(info, null);
- // Remove the dialog if the subscription associated with this activity changes.
- if (info == null) {
- // Close the activity when subscription removed
- if ((oldSubIndex != SUB_ID_NULL)
- && (!isFinishing()) && (!isDestroyed())) {
- finish();
+ SubscriptionInfo subInfo = getSubscription(mCurSubscriptionId, null);
+ if (subInfo != null) {
+ if (mCurSubscriptionId != subInfo.getSubscriptionId()) {
+ // update based on subscription status change
+ removeContactDiscoveryDialog(mCurSubscriptionId);
+ updateSubscriptions(subInfo, null);
}
return;
}
- int subIndex = info.getSubscriptionId();
- if (subIndex != oldSubIndex) {
- removeContactDiscoveryDialog(oldSubIndex);
+
+ Log.w(TAG, "subId missing: " + mCurSubscriptionId);
+
+ // When UI is not the active one, avoid from destroy it immediately
+ // but wait until onResume() to see if subscription back online again.
+ // This is to avoid from glitch behavior of subscription which changes
+ // the UI when UI is considered as in the background or only partly
+ // visible.
+ if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
+ mPendingSubscriptionChange = true;
+ return;
+ }
+
+ // Subscription could be missing
+ tryToFinishActivity();
+ }
+
+ protected void runSubscriptionUpdate(Runnable onUpdateRemaining) {
+ SubscriptionInfo subInfo = getSubscription(mCurSubscriptionId, null);
+ if (subInfo == null) {
+ tryToFinishActivity();
+ return;
+ }
+ if (mCurSubscriptionId != subInfo.getSubscriptionId()) {
+ removeContactDiscoveryDialog(mCurSubscriptionId);
+ updateSubscriptions(subInfo, null);
+ }
+ onUpdateRemaining.run();
+ }
+
+ protected void tryToFinishActivity() {
+ if ((!isFinishing()) && (!isDestroyed())) {
+ finish();
}
}
@Override
protected void onStart() {
getProxySubscriptionManager().setLifecycle(getLifecycle());
- super.onStart();
- // updateSubscriptions doesn't need to be called, onChanged will always be called after we
- // register a listener.
if (mPendingSubscriptionChange) {
mPendingSubscriptionChange = false;
- onChanged();
+ runSubscriptionUpdate(() -> super.onStart());
+ return;
}
+ super.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ if (mPendingSubscriptionChange) {
+ mPendingSubscriptionChange = false;
+ runSubscriptionUpdate(() -> super.onResume());
+ return;
+ }
+ super.onResume();
}
@Override
@@ -235,30 +286,49 @@
}
mCurSubscriptionId = subscriptionIndex;
- mFragmentForceReload = false;
+ }
+
+ /**
+ * Select one of the subscription as the default subscription.
+ * @param subAnnoList a list of {@link SubscriptionAnnotation}
+ * @return ideally the {@link SubscriptionAnnotation} as expected
+ */
+ protected SubscriptionAnnotation defaultSubscriptionSelection(
+ List<SubscriptionAnnotation> subAnnoList) {
+ return (subAnnoList == null) ? null :
+ subAnnoList.stream()
+ .filter(SubscriptionAnnotation::isDisplayAllowed)
+ .filter(SubscriptionAnnotation::isActive)
+ .findFirst().orElse(null);
+ }
+
+ protected SubscriptionInfo getSubscriptionOrDefault(int subscriptionId) {
+ return getSubscription(subscriptionId,
+ (subscriptionId != SUB_ID_NULL) ? null : (
+ subAnnoList -> defaultSubscriptionSelection(subAnnoList)
+ ));
}
/**
* Get the current subscription to display. First check whether intent has {@link
- * Settings#EXTRA_SUB_ID} and if so find the subscription with that id. If not, just return the
- * first one in the mSubscriptionInfos list since it is already sorted by sim slot.
+ * Settings#EXTRA_SUB_ID} and if so find the subscription with that id.
+ * If not, select default one based on {@link Function} provided.
+ *
+ * @param preferredSubscriptionId preferred subscription id
+ * @param selectionOfDefault when true current subscription is absent
*/
@VisibleForTesting
- SubscriptionInfo getSubscription() {
+ protected SubscriptionInfo getSubscription(int preferredSubscriptionId,
+ Function<List<SubscriptionAnnotation>, SubscriptionAnnotation> selectionOfDefault) {
List<SubscriptionAnnotation> subList =
(new SelectableSubscriptions(this, true)).call();
- SubscriptionAnnotation currentSubInfo = null;
- if (mCurSubscriptionId != SUB_ID_NULL) {
- currentSubInfo = subList.stream()
- .filter(SubscriptionAnnotation::isDisplayAllowed)
- .filter(subAnno -> (subAnno.getSubscriptionId() == mCurSubscriptionId))
- .findFirst().orElse(null);
- }
- if (currentSubInfo == null) {
- currentSubInfo = subList.stream()
- .filter(SubscriptionAnnotation::isDisplayAllowed)
- .filter(SubscriptionAnnotation::isActive)
- .findFirst().orElse(null);
+ Log.d(TAG, "get subId=" + preferredSubscriptionId + " from " + subList);
+ SubscriptionAnnotation currentSubInfo = subList.stream()
+ .filter(SubscriptionAnnotation::isDisplayAllowed)
+ .filter(subAnno -> (subAnno.getSubscriptionId() == preferredSubscriptionId))
+ .findFirst().orElse(null);
+ if ((currentSubInfo == null) && (selectionOfDefault != null)) {
+ currentSubInfo = selectionOfDefault.apply(subList);
}
return (currentSubInfo == null) ? null : currentSubInfo.getSubInfo();
}
@@ -285,10 +355,6 @@
final String fragmentTag = buildFragmentTag(subId);
if (fragmentManager.findFragmentByTag(fragmentTag) != null) {
- if (!mFragmentForceReload) {
- Log.d(TAG, "Keep current fragment: " + fragmentTag);
- return;
- }
Log.d(TAG, "Construct fragment: " + fragmentTag);
}