Merge "Avoid ANR when UI query network selection state"
This commit is contained in:
committed by
Android (Google) Code Review
commit
65734dd29b
@@ -272,7 +272,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
|||||||
use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
|
use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
|
||||||
final AutoSelectPreferenceController autoSelectPreferenceController =
|
final AutoSelectPreferenceController autoSelectPreferenceController =
|
||||||
use(AutoSelectPreferenceController.class)
|
use(AutoSelectPreferenceController.class)
|
||||||
.init(mSubId)
|
.init(getLifecycle(), mSubId)
|
||||||
.addListener(openNetworkSelectPagePreferenceController);
|
.addListener(openNetworkSelectPagePreferenceController);
|
||||||
use(NetworkPreferenceCategoryController.class).init(mSubId)
|
use(NetworkPreferenceCategoryController.class).init(mSubId)
|
||||||
.setChildren(Arrays.asList(autoSelectPreferenceController));
|
.setChildren(Arrays.asList(autoSelectPreferenceController));
|
||||||
|
@@ -34,8 +34,10 @@ import android.telephony.CarrierConfigManager;
|
|||||||
import android.telephony.ServiceState;
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.lifecycle.Lifecycle;
|
||||||
import androidx.lifecycle.LifecycleObserver;
|
import androidx.lifecycle.LifecycleObserver;
|
||||||
import androidx.lifecycle.OnLifecycleEvent;
|
import androidx.lifecycle.OnLifecycleEvent;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -45,6 +47,7 @@ import androidx.preference.SwitchPreference;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.network.AllowedNetworkTypesListener;
|
import com.android.settings.network.AllowedNetworkTypesListener;
|
||||||
import com.android.settings.network.CarrierConfigCache;
|
import com.android.settings.network.CarrierConfigCache;
|
||||||
|
import com.android.settings.network.helper.ServiceStateStatus;
|
||||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||||
import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
|
import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
|
||||||
import com.android.settingslib.utils.ThreadUtils;
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
@@ -62,6 +65,9 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
|
public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController
|
||||||
implements LifecycleObserver{
|
implements LifecycleObserver{
|
||||||
private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
|
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 final Handler mUiHandler;
|
||||||
private PreferenceScreen mPreferenceScreen;
|
private PreferenceScreen mPreferenceScreen;
|
||||||
@@ -76,6 +82,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
|||||||
private AtomicBoolean mUpdatingConfig;
|
private AtomicBoolean mUpdatingConfig;
|
||||||
private int mCacheOfModeStatus;
|
private int mCacheOfModeStatus;
|
||||||
private AtomicLong mRecursiveUpdate;
|
private AtomicLong mRecursiveUpdate;
|
||||||
|
ServiceStateStatus mServiceStateStatus;
|
||||||
|
|
||||||
public AutoSelectPreferenceController(Context context, String key) {
|
public AutoSelectPreferenceController(Context context, String key) {
|
||||||
super(context, key);
|
super(context, key);
|
||||||
@@ -129,12 +136,6 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChecked() {
|
public boolean isChecked() {
|
||||||
if (!mUpdatingConfig.get()) {
|
|
||||||
mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
|
|
||||||
for (OnNetworkSelectModeListener lsn : mListeners) {
|
|
||||||
lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,12 +198,22 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
|||||||
|
|
||||||
//Update UI in UI thread
|
//Update UI in UI thread
|
||||||
final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
|
final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
|
||||||
|
|
||||||
mUiHandler.postDelayed(() -> {
|
mUiHandler.postDelayed(() -> {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
queryNetworkSelectionMode(INTERNAL_LOG_TAG_AFTERSET);
|
||||||
|
|
||||||
|
//Update UI in UI thread
|
||||||
|
mUiHandler.post(() -> {
|
||||||
mRecursiveUpdate.getAndIncrement();
|
mRecursiveUpdate.getAndIncrement();
|
||||||
|
if (mSwitchPreference != null) {
|
||||||
mSwitchPreference.setEnabled(true);
|
mSwitchPreference.setEnabled(true);
|
||||||
mSwitchPreference.setChecked(isChecked());
|
mSwitchPreference.setChecked(isChecked());
|
||||||
|
}
|
||||||
mRecursiveUpdate.decrementAndGet();
|
mRecursiveUpdate.decrementAndGet();
|
||||||
dismissProgressBar();
|
dismissProgressBar();
|
||||||
|
});
|
||||||
|
});
|
||||||
}, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
|
}, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -210,7 +221,7 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
|||||||
/**
|
/**
|
||||||
* Initialization based on given subscription id.
|
* Initialization based on given subscription id.
|
||||||
**/
|
**/
|
||||||
public AutoSelectPreferenceController init(int subId) {
|
public AutoSelectPreferenceController init(Lifecycle lifecycle, int subId) {
|
||||||
mSubId = subId;
|
mSubId = subId;
|
||||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
|
mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
|
||||||
.createForSubscriptionId(mSubId);
|
.createForSubscriptionId(mSubId);
|
||||||
@@ -221,6 +232,29 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
|||||||
CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
|
CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
|
mServiceStateStatus = new ServiceStateStatus(lifecycle, mTelephonyManager,
|
||||||
|
new HandlerExecutor(mUiHandler)) {
|
||||||
|
@Override
|
||||||
|
protected void setValue(ServiceState status) {
|
||||||
|
if (status == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateUiAutoSelectValue(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
queryNetworkSelectionMode(INTERNAL_LOG_TAG_INIT);
|
||||||
|
|
||||||
|
//Update UI in UI thread
|
||||||
|
mUiHandler.post(() -> {
|
||||||
|
if (mSwitchPreference != null) {
|
||||||
|
mRecursiveUpdate.getAndIncrement();
|
||||||
|
mSwitchPreference.setChecked(isChecked());
|
||||||
|
mRecursiveUpdate.decrementAndGet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +264,41 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void queryNetworkSelectionMode(String tag) {
|
||||||
|
mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode();
|
||||||
|
Log.d(LOG_TAG, tag + ": query commend done. mCacheOfModeStatus: " + mCacheOfModeStatus);
|
||||||
|
updateListenerValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
updateListenerValue();
|
||||||
|
|
||||||
|
mRecursiveUpdate.getAndIncrement();
|
||||||
|
updateState(mSwitchPreference);
|
||||||
|
mRecursiveUpdate.decrementAndGet();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateListenerValue() {
|
||||||
|
for (OnNetworkSelectModeListener lsn : mListeners) {
|
||||||
|
lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void showAutoSelectProgressBar() {
|
private void showAutoSelectProgressBar() {
|
||||||
if (mProgressDialog == null) {
|
if (mProgressDialog == null) {
|
||||||
mProgressDialog = new ProgressDialog(mContext);
|
mProgressDialog = new ProgressDialog(mContext);
|
||||||
|
@@ -28,9 +28,11 @@ import android.app.ProgressDialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.telephony.CarrierConfigManager;
|
import android.telephony.CarrierConfigManager;
|
||||||
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import androidx.lifecycle.Lifecycle;
|
||||||
import androidx.preference.SwitchPreference;
|
import androidx.preference.SwitchPreference;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
@@ -61,6 +63,10 @@ public class AutoSelectPreferenceControllerTest {
|
|||||||
private CarrierConfigCache mCarrierConfigCache;
|
private CarrierConfigCache mCarrierConfigCache;
|
||||||
@Mock
|
@Mock
|
||||||
private ProgressDialog mProgressDialog;
|
private ProgressDialog mProgressDialog;
|
||||||
|
@Mock
|
||||||
|
private ServiceState mTestServiceState;
|
||||||
|
@Mock
|
||||||
|
private Lifecycle mLifecycle;
|
||||||
|
|
||||||
private PersistableBundle mCarrierConfig;
|
private PersistableBundle mCarrierConfig;
|
||||||
private AutoSelectPreferenceController mController;
|
private AutoSelectPreferenceController mController;
|
||||||
@@ -88,7 +94,16 @@ public class AutoSelectPreferenceControllerTest {
|
|||||||
mController = new AutoSelectPreferenceController(mContext, "auto_select");
|
mController = new AutoSelectPreferenceController(mContext, "auto_select");
|
||||||
mController.mProgressDialog = mProgressDialog;
|
mController.mProgressDialog = mProgressDialog;
|
||||||
mController.mSwitchPreference = mSwitchPreference;
|
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
|
@Test
|
||||||
@@ -111,7 +126,8 @@ public class AutoSelectPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateState_isRoaming_enabled() {
|
public void updateState_isRoaming_enabled() {
|
||||||
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(true);
|
when(mTelephonyManager.getServiceState()).thenReturn(mTestServiceState);
|
||||||
|
when(mTestServiceState.getRoaming()).thenReturn(true);
|
||||||
|
|
||||||
mController.updateState(mSwitchPreference);
|
mController.updateState(mSwitchPreference);
|
||||||
|
|
||||||
@@ -120,7 +136,8 @@ public class AutoSelectPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateState_notRoamingWithAutoSelectOn_disabled() {
|
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();
|
doReturn(OPERATOR_NAME).when(mTelephonyManager).getSimOperatorName();
|
||||||
|
|
||||||
mController.updateState(mSwitchPreference);
|
mController.updateState(mSwitchPreference);
|
||||||
@@ -136,6 +153,34 @@ public class AutoSelectPreferenceControllerTest {
|
|||||||
when(mCarrierConfigCache.getConfigForSubId(SUB_ID)).thenReturn(null);
|
when(mCarrierConfigCache.getConfigForSubId(SUB_ID)).thenReturn(null);
|
||||||
|
|
||||||
// Should not crash
|
// 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