Merge "Avoid ANR when UI query network selection state" into tm-qpr-dev am: d911a095eb
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/22135268 Change-Id: Ideef6fbd4bd904456cb2b91207f8e2acdf54637f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -207,7 +207,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
|
||||
use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
|
||||
final AutoSelectPreferenceController autoSelectPreferenceController =
|
||||
use(AutoSelectPreferenceController.class)
|
||||
.init(mSubId)
|
||||
.init(getLifecycle(), mSubId)
|
||||
.addListener(openNetworkSelectPagePreferenceController);
|
||||
use(NetworkPreferenceCategoryController.class).init(mSubId)
|
||||
.setChildren(Arrays.asList(autoSelectPreferenceController));
|
||||
|
@@ -33,9 +33,12 @@ import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.Preference;
|
||||
@@ -62,6 +65,9 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
|
||||
implements LifecycleObserver{
|
||||
private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
|
||||
private static final String LOG_TAG = "AutoSelectPreferenceController";
|
||||
private static final String INTERNAL_LOG_TAG_INIT = "Init";
|
||||
private static final String INTERNAL_LOG_TAG_AFTERSET = "AfterSet";
|
||||
|
||||
private final Handler mUiHandler;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@@ -76,6 +82,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
private AtomicBoolean mUpdatingConfig;
|
||||
private int mCacheOfModeStatus;
|
||||
private AtomicLong mRecursiveUpdate;
|
||||
TelephonyCallbackListener mTelephonyCallbackListener;
|
||||
|
||||
public AutoSelectPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
@@ -90,6 +97,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
new HandlerExecutor(mUiHandler));
|
||||
mAllowedNetworkTypesListener.setAllowedNetworkTypesListener(
|
||||
() -> updatePreference());
|
||||
mTelephonyCallbackListener = new TelephonyCallbackListener();
|
||||
}
|
||||
|
||||
private void updatePreference() {
|
||||
@@ -106,11 +114,14 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
@OnLifecycleEvent(ON_START)
|
||||
public void onStart() {
|
||||
mAllowedNetworkTypesListener.register(mContext, mSubId);
|
||||
mTelephonyManager.registerTelephonyCallback(new HandlerExecutor(mUiHandler),
|
||||
mTelephonyCallbackListener);
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_STOP)
|
||||
public void onStop() {
|
||||
mAllowedNetworkTypesListener.unregister(mContext, mSubId);
|
||||
mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallbackListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,12 +140,6 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
if (!mUpdatingConfig.get()) {
|
||||
mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
|
||||
for (OnNetworkSelectModeListener lsn : mListeners) {
|
||||
lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
|
||||
}
|
||||
}
|
||||
return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||
}
|
||||
|
||||
@@ -197,12 +202,23 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
|
||||
//Update UI in UI thread
|
||||
final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
|
||||
|
||||
mUiHandler.postDelayed(() -> {
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
mSwitchPreference.setEnabled(true);
|
||||
mSwitchPreference.setChecked(isChecked());
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
dismissProgressBar();
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
queryNetworkSelectionMode(INTERNAL_LOG_TAG_AFTERSET);
|
||||
|
||||
//Update UI in UI thread
|
||||
mUiHandler.post(() -> {
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
if (mSwitchPreference != null) {
|
||||
mSwitchPreference.setEnabled(true);
|
||||
mSwitchPreference.setChecked(isChecked());
|
||||
}
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
updateListenerValue();
|
||||
dismissProgressBar();
|
||||
});
|
||||
});
|
||||
}, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
|
||||
});
|
||||
}
|
||||
@@ -210,7 +226,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
/**
|
||||
* Initialization based on given subscription id.
|
||||
**/
|
||||
public AutoSelectPreferenceController init(int subId) {
|
||||
public AutoSelectPreferenceController init(Lifecycle lifecycle, int subId) {
|
||||
mSubId = subId;
|
||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(mSubId);
|
||||
@@ -221,6 +237,19 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
|
||||
: false;
|
||||
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
queryNetworkSelectionMode(INTERNAL_LOG_TAG_INIT);
|
||||
|
||||
//Update UI in UI thread
|
||||
mUiHandler.post(() -> {
|
||||
if (mSwitchPreference != null) {
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
mSwitchPreference.setChecked(isChecked());
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
updateListenerValue();
|
||||
}
|
||||
});
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -230,6 +259,39 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
return this;
|
||||
}
|
||||
|
||||
private void queryNetworkSelectionMode(String tag) {
|
||||
mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
|
||||
Log.d(LOG_TAG, tag + ": query command done. mCacheOfModeStatus: " + mCacheOfModeStatus);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateUiAutoSelectValue(ServiceState status) {
|
||||
if (status == null) {
|
||||
return;
|
||||
}
|
||||
if (!mUpdatingConfig.get()) {
|
||||
int networkSelectionMode = status.getIsManualSelection()
|
||||
? TelephonyManager.NETWORK_SELECTION_MODE_MANUAL
|
||||
: TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||
if (mCacheOfModeStatus == networkSelectionMode) {
|
||||
return;
|
||||
}
|
||||
mCacheOfModeStatus = networkSelectionMode;
|
||||
Log.d(LOG_TAG, "updateUiAutoSelectValue: mCacheOfModeStatus: " + mCacheOfModeStatus);
|
||||
|
||||
mRecursiveUpdate.getAndIncrement();
|
||||
updateState(mSwitchPreference);
|
||||
mRecursiveUpdate.decrementAndGet();
|
||||
updateListenerValue();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateListenerValue() {
|
||||
for (OnNetworkSelectModeListener lsn : mListeners) {
|
||||
lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private void showAutoSelectProgressBar() {
|
||||
if (mProgressDialog == null) {
|
||||
mProgressDialog = new ProgressDialog(mContext);
|
||||
@@ -260,4 +322,13 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
||||
public interface OnNetworkSelectModeListener {
|
||||
void onNetworkSelectModeUpdated(int mode);
|
||||
}
|
||||
|
||||
private class TelephonyCallbackListener extends TelephonyCallback
|
||||
implements TelephonyCallback.ServiceStateListener {
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(ServiceState serviceState) {
|
||||
updateUiAutoSelectValue(serviceState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -28,9 +28,11 @@ import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
@@ -61,6 +63,10 @@ public class AutoSelectPreferenceControllerTest {
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
@Mock
|
||||
private ProgressDialog mProgressDialog;
|
||||
@Mock
|
||||
private ServiceState mTestServiceState;
|
||||
@Mock
|
||||
private Lifecycle mLifecycle;
|
||||
|
||||
private PersistableBundle mCarrierConfig;
|
||||
private AutoSelectPreferenceController mController;
|
||||
@@ -88,7 +94,16 @@ public class AutoSelectPreferenceControllerTest {
|
||||
mController = new AutoSelectPreferenceController(mContext, "auto_select");
|
||||
mController.mProgressDialog = mProgressDialog;
|
||||
mController.mSwitchPreference = mSwitchPreference;
|
||||
mController.init(SUB_ID);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
sleepAfterInit();
|
||||
}
|
||||
|
||||
private void sleepAfterInit() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception e) {
|
||||
fail("Sleep timeout " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,7 +126,8 @@ public class AutoSelectPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateState_isRoaming_enabled() {
|
||||
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(true);
|
||||
when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
|
||||
when(mTestServiceState.getRoaming()).thenReturn(true);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
@@ -120,7 +136,8 @@ public class AutoSelectPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateState_notRoamingWithAutoSelectOn_disabled() {
|
||||
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(false);
|
||||
when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
|
||||
when(mTestServiceState.getRoaming()).thenReturn(false);
|
||||
doReturn(OPERATOR_NAME).when(mTelephonyManager).getSimOperatorName();
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
@@ -136,6 +153,34 @@ public class AutoSelectPreferenceControllerTest {
|
||||
when(mCarrierConfigCache.getConfigForSubId(SUB_ID)).thenReturn(null);
|
||||
|
||||
// Should not crash
|
||||
mController.init(SUB_ID);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiAutoSelectValue_serviceStateGetIsManualSelection_isCheckedFalse() {
|
||||
when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
|
||||
TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
|
||||
when(mTestServiceState.getIsManualSelection()).thenReturn(true);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
sleepAfterInit();
|
||||
|
||||
mController.updateUiAutoSelectValue(mTestServiceState);
|
||||
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiAutoSelectValue_serviceStateGetIsAutoSelection_isCheckedTrue() {
|
||||
when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
|
||||
TelephonyManager.NETWORK_SELECTION_MODE_MANUAL);
|
||||
when(mTestServiceState.getIsManualSelection()).thenReturn(false);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
sleepAfterInit();
|
||||
|
||||
mController.updateUiAutoSelectValue(mTestServiceState);
|
||||
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
assertThat(mSwitchPreference.isChecked()).isTrue();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user