Merge "[Settings] Avoid from immediate update when UI inactive and SIM absent" into sc-qpr1-dev

This commit is contained in:
Bonian Chen
2021-09-16 00:36:31 +00:00
committed by Android (Google) Code Review

View File

@@ -39,7 +39,6 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import com.android.internal.util.CollectionUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.SettingsBaseActivity; import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.network.ProxySubscriptionManager; import com.android.settings.network.ProxySubscriptionManager;
@@ -48,6 +47,7 @@ import com.android.settings.network.helper.SelectableSubscriptions;
import com.android.settings.network.helper.SubscriptionAnnotation; import com.android.settings.network.helper.SubscriptionAnnotation;
import java.util.List; import java.util.List;
import java.util.function.Function;
/** /**
* Activity for displaying MobileNetworkSettings * Activity for displaying MobileNetworkSettings
@@ -64,15 +64,14 @@ public class MobileNetworkActivity extends SettingsBaseActivity
@VisibleForTesting @VisibleForTesting
ProxySubscriptionManager mProxySubscriptionMgr; ProxySubscriptionManager mProxySubscriptionMgr;
private int mCurSubscriptionId; private int mCurSubscriptionId = SUB_ID_NULL;
// This flag forces subscription information fragment to be re-created. // This flag forces subscription information fragment to be re-created.
// Otherwise, fragment will be kept when subscription id has not been changed. // 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 // Set initial value to true allows subscription information fragment to be re-created when
// Activity re-create occur. // Activity re-create occur.
private boolean mFragmentForceReload = true; private boolean mPendingSubscriptionChange = true;
private boolean mPendingSubscriptionChange = false;
@Override @Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
@@ -80,21 +79,25 @@ public class MobileNetworkActivity extends SettingsBaseActivity
validate(intent); validate(intent);
setIntent(intent); setIntent(intent);
int updateSubscriptionIndex = SUB_ID_NULL; int updateSubscriptionIndex = mCurSubscriptionId;
if (intent != null) { if (intent != null) {
updateSubscriptionIndex = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_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; int oldSubId = mCurSubscriptionId;
mCurSubscriptionId = updateSubscriptionIndex;
mFragmentForceReload = (mCurSubscriptionId == oldSubId);
final SubscriptionInfo info = getSubscription();
updateSubscriptions(info, null); updateSubscriptions(info, null);
// If the subscription has changed or the new intent doesnt contain the opt in action, // 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 // 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 // onCreate -> onNewIntent, so the dialog will first be recreated for the old subscription
// and then removed. // and then removed.
if (updateSubscriptionIndex != oldSubId || !doesIntentContainOptInAction(intent)) { if (mCurSubscriptionId != oldSubId || !doesIntentContainOptInAction(intent)) {
removeContactDiscoveryDialog(oldSubId); removeContactDiscoveryDialog(oldSubId);
} }
// evaluate showing the new discovery dialog if this intent contains an action to show the // evaluate showing the new discovery dialog if this intent contains an action to show the
@@ -135,7 +138,13 @@ public class MobileNetworkActivity extends SettingsBaseActivity
// perform registration after mCurSubscriptionId been configured. // perform registration after mCurSubscriptionId been configured.
registerActiveSubscriptionsListener(); registerActiveSubscriptionsListener();
final SubscriptionInfo subscription = getSubscription(); SubscriptionInfo subscription = getSubscriptionOrDefault(mCurSubscriptionId);
if (subscription == null) {
Log.d(TAG, "Invalid subId request " + mCurSubscriptionId);
tryToFinishActivity();
return;
}
maybeShowContactDiscoveryDialog(subscription); maybeShowContactDiscoveryDialog(subscription);
updateSubscriptions(subscription, null); updateSubscriptions(subscription, null);
@@ -158,39 +167,81 @@ public class MobileNetworkActivity extends SettingsBaseActivity
* Implementation of ProxySubscriptionManager.OnActiveSubscriptionChangedListener * Implementation of ProxySubscriptionManager.OnActiveSubscriptionChangedListener
*/ */
public void onChanged() { public void onChanged() {
mPendingSubscriptionChange = false;
if (mCurSubscriptionId == SUB_ID_NULL) {
return;
}
if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
mPendingSubscriptionChange = true; mPendingSubscriptionChange = true;
return; return;
} }
SubscriptionInfo info = getSubscription();
int oldSubIndex = mCurSubscriptionId;
updateSubscriptions(info, null);
// Remove the dialog if the subscription associated with this activity changes. SubscriptionInfo subInfo = getSubscription(mCurSubscriptionId, null);
if (info == null) { if (subInfo != null) {
// Close the activity when subscription removed if (mCurSubscriptionId != subInfo.getSubscriptionId()) {
if ((oldSubIndex != SUB_ID_NULL) // update based on subscription status change
&& (!isFinishing()) && (!isDestroyed())) { removeContactDiscoveryDialog(mCurSubscriptionId);
finish(); updateSubscriptions(subInfo, null);
} }
return; return;
} }
int subIndex = info.getSubscriptionId();
if (subIndex != oldSubIndex) { Log.w(TAG, "subId missing: " + mCurSubscriptionId);
removeContactDiscoveryDialog(oldSubIndex);
// 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 @Override
protected void onStart() { protected void onStart() {
getProxySubscriptionManager().setLifecycle(getLifecycle()); getProxySubscriptionManager().setLifecycle(getLifecycle());
super.onStart();
// updateSubscriptions doesn't need to be called, onChanged will always be called after we
// register a listener.
if (mPendingSubscriptionChange) { if (mPendingSubscriptionChange) {
mPendingSubscriptionChange = false; mPendingSubscriptionChange = false;
onChanged(); runSubscriptionUpdate(() -> super.onStart());
return;
} }
super.onStart();
}
@Override
protected void onResume() {
if (mPendingSubscriptionChange) {
mPendingSubscriptionChange = false;
runSubscriptionUpdate(() -> super.onResume());
return;
}
super.onResume();
} }
@Override @Override
@@ -235,30 +286,49 @@ public class MobileNetworkActivity extends SettingsBaseActivity
} }
mCurSubscriptionId = subscriptionIndex; 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 * 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 * Settings#EXTRA_SUB_ID} and if so find the subscription with that id.
* first one in the mSubscriptionInfos list since it is already sorted by sim slot. * If not, select default one based on {@link Function} provided.
*
* @param preferredSubscriptionId preferred subscription id
* @param selectionOfDefault when true current subscription is absent
*/ */
@VisibleForTesting @VisibleForTesting
SubscriptionInfo getSubscription() { protected SubscriptionInfo getSubscription(int preferredSubscriptionId,
Function<List<SubscriptionAnnotation>, SubscriptionAnnotation> selectionOfDefault) {
List<SubscriptionAnnotation> subList = List<SubscriptionAnnotation> subList =
(new SelectableSubscriptions(this, true)).call(); (new SelectableSubscriptions(this, true)).call();
SubscriptionAnnotation currentSubInfo = null; Log.d(TAG, "get subId=" + preferredSubscriptionId + " from " + subList);
if (mCurSubscriptionId != SUB_ID_NULL) { SubscriptionAnnotation currentSubInfo = subList.stream()
currentSubInfo = subList.stream() .filter(SubscriptionAnnotation::isDisplayAllowed)
.filter(SubscriptionAnnotation::isDisplayAllowed) .filter(subAnno -> (subAnno.getSubscriptionId() == preferredSubscriptionId))
.filter(subAnno -> (subAnno.getSubscriptionId() == mCurSubscriptionId)) .findFirst().orElse(null);
.findFirst().orElse(null); if ((currentSubInfo == null) && (selectionOfDefault != null)) {
} currentSubInfo = selectionOfDefault.apply(subList);
if (currentSubInfo == null) {
currentSubInfo = subList.stream()
.filter(SubscriptionAnnotation::isDisplayAllowed)
.filter(SubscriptionAnnotation::isActive)
.findFirst().orElse(null);
} }
return (currentSubInfo == null) ? null : currentSubInfo.getSubInfo(); return (currentSubInfo == null) ? null : currentSubInfo.getSubInfo();
} }
@@ -285,10 +355,6 @@ public class MobileNetworkActivity extends SettingsBaseActivity
final String fragmentTag = buildFragmentTag(subId); final String fragmentTag = buildFragmentTag(subId);
if (fragmentManager.findFragmentByTag(fragmentTag) != null) { if (fragmentManager.findFragmentByTag(fragmentTag) != null) {
if (!mFragmentForceReload) {
Log.d(TAG, "Keep current fragment: " + fragmentTag);
return;
}
Log.d(TAG, "Construct fragment: " + fragmentTag); Log.d(TAG, "Construct fragment: " + fragmentTag);
} }