Loading src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java +83 −12 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ package com.android.settings.network.telephony; import static androidx.lifecycle.Lifecycle.Event.ON_START; import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType; import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes; import static com.android.settings.network.telephony.mode.NetworkModes.addNrToLteNetworkMode; Loading @@ -33,15 +30,17 @@ import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; import android.telephony.satellite.SatelliteModemStateCallback; import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.ListPreference; import androidx.preference.ListPreferenceDialogFragmentCompat; import androidx.preference.Preference; Loading @@ -67,7 +66,7 @@ import java.util.stream.Stream; */ public class EnabledNetworkModePreferenceController extends BasePreferenceController implements ListPreference.OnPreferenceChangeListener, LifecycleObserver, ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient { private static final String LOG_TAG = "EnabledNetworkMode"; Loading @@ -83,6 +82,43 @@ public class EnabledNetworkModePreferenceController extends private PhoneCallStateTelephonyCallback mTelephonyCallback; private FragmentManager mFragmentManager; private LifecycleOwner mViewLifecycleOwner; private SatelliteManager mSatelliteManager; private boolean mIsSatelliteSessionStarted = false; private boolean mIsCurrentSubscriptionForSatellite = false; @VisibleForTesting final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback = new SelectedNbIotSatelliteSubscriptionCallback() { @Override public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) { mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId; updatePreference(); } }; @VisibleForTesting final SatelliteModemStateCallback mSatelliteModemStateCallback = new SatelliteModemStateCallback() { @Override public void onSatelliteModemStateChanged(int state) { switch (state) { case SatelliteManager.SATELLITE_MODEM_STATE_OFF: case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE: case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN: if (mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = false; updatePreference(); } break; default: if (!mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = true; updatePreference(); } break; } } }; public EnabledNetworkModePreferenceController(Context context, String key) { super(context, key); Loading @@ -90,6 +126,7 @@ public class EnabledNetworkModePreferenceController extends if (mTelephonyCallback == null) { mTelephonyCallback = new PhoneCallStateTelephonyCallback(); } mSatelliteManager = context.getSystemService(SatelliteManager.class); } @Override Loading @@ -103,8 +140,22 @@ public class EnabledNetworkModePreferenceController extends return mCallState == TelephonyManager.CALL_STATE_IDLE; } @OnLifecycleEvent(ON_START) public void onStart() { @Override public void onStart(@NonNull LifecycleOwner owner) { if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.registerForModemStateChanged( mContext.getMainExecutor(), mSatelliteModemStateCallback); mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged( mContext.getMainExecutor(), mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(LOG_TAG, "IllegalStateException : " + e); } } } mSubscriptionsListener.start(); if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) { return; Loading @@ -113,9 +164,21 @@ public class EnabledNetworkModePreferenceController extends mTelephonyCallback.register(mTelephonyManager, mSubId); } @OnLifecycleEvent(ON_STOP) public void onStop() { @Override public void onStop(@NonNull LifecycleOwner owner) { mSubscriptionsListener.stop(); if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback); mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(LOG_TAG, "IllegalStateException : " + e); } } } if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) { return; } Loading Loading @@ -147,7 +210,7 @@ public class EnabledNetworkModePreferenceController extends listPreference.setEntryValues(mBuilder.getEntryValues()); listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue())); listPreference.setSummary(mBuilder.getSummary()); boolean listPreferenceEnabled = isCallStateIdle(); boolean listPreferenceEnabled = isPreferenceShallEnabled(); listPreference.setEnabled(listPreferenceEnabled); if (!listPreferenceEnabled) { // If dialog is already opened when ListPreference disabled, dismiss them. Loading Loading @@ -203,6 +266,14 @@ public class EnabledNetworkModePreferenceController extends } } private boolean isPreferenceShallEnabled() { Log.d(LOG_TAG, "isPreferenceShallEnabled, mIsSatelliteSessionStarted : " + mIsSatelliteSessionStarted + " / mIsCurrentSubscriptionForSatellite : " + mIsCurrentSubscriptionForSatellite); return isCallStateIdle() && !(mIsSatelliteSessionStarted && mIsCurrentSubscriptionForSatellite); } private final class PreferenceEntriesBuilder { private CarrierConfigCache mCarrierConfigCache; private Context mContext; Loading src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java +93 −4 Original line number Diff line number Diff line Loading @@ -24,10 +24,18 @@ import android.telephony.CarrierConfigManager; import android.telephony.RadioAccessFamily; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; import android.telephony.satellite.SatelliteModemStateCallback; import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; Loading @@ -38,17 +46,56 @@ import com.android.settings.network.telephony.mode.NetworkModes; * Preference controller for "Preferred network mode" */ public class PreferredNetworkModePreferenceController extends BasePreferenceController implements ListPreference.OnPreferenceChangeListener { implements ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver { private static final String TAG = "PrefNetworkModeCtrl"; private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private CarrierConfigCache mCarrierConfigCache; private TelephonyManager mTelephonyManager; private boolean mIsGlobalCdma; private SatelliteManager mSatelliteManager; private Preference mPreference; private boolean mIsSatelliteSessionStarted = false; private boolean mIsCurrentSubscriptionForSatellite = false; @VisibleForTesting final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback = new SelectedNbIotSatelliteSubscriptionCallback() { @Override public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) { mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId; updateState(mPreference); } }; @VisibleForTesting final SatelliteModemStateCallback mSatelliteModemStateCallback = new SatelliteModemStateCallback() { @Override public void onSatelliteModemStateChanged(int state) { switch (state) { case SatelliteManager.SATELLITE_MODEM_STATE_OFF: case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE: case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN: if (mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = false; updateState(mPreference); } break; default: if (!mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = true; updateState(mPreference); } break; } } }; public PreferredNetworkModePreferenceController(Context context, String key) { super(context, key); mCarrierConfigCache = CarrierConfigCache.getInstance(context); mSatelliteManager = context.getSystemService(SatelliteManager.class); } @Override Loading @@ -58,9 +105,19 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mPreference = screen.findPreference(getPreferenceKey()); } @Override public void updateState(Preference preference) { if (preference == null) { return; } super.updateState(preference); preference.setEnabled(!(mIsCurrentSubscriptionForSatellite && mIsSatelliteSessionStarted)); final ListPreference listPreference = (ListPreference) preference; final int networkMode = getPreferredNetworkMode(); listPreference.setValue(Integer.toString(networkMode)); Loading Loading @@ -90,6 +147,38 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL); } @Override public void onStart(@NonNull LifecycleOwner owner) { if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.registerForModemStateChanged( mContext.getMainExecutor(), mSatelliteModemStateCallback); mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged( mContext.getMainExecutor(), mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(TAG, "IllegalStateException : " + e); } } } } @Override public void onStop(@NonNull LifecycleOwner owner) { if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback); mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(TAG, "IllegalStateException : " + e); } } } } private int getPreferredNetworkMode() { if (mTelephonyManager == null) { Log.w(TAG, "TelephonyManager is null"); Loading src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.kt +66 −7 Original line number Diff line number Diff line Loading @@ -25,18 +25,22 @@ import android.telephony.CarrierConfigManager import android.telephony.ServiceState import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.satellite.SatelliteManager import android.telephony.satellite.SatelliteModemStateCallback import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback import android.util.Log import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.res.stringResource import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settings.R import com.android.settings.Settings.NetworkSelectActivity import com.android.settings.flags.Flags import com.android.settings.network.CarrierConfigCache import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.network.telephony.allowedNetworkTypesFlow Loading @@ -46,8 +50,6 @@ import com.android.settingslib.spa.framework.compose.OverridableFlow import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import kotlin.properties.Delegates.notNull import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.delay Loading @@ -59,6 +61,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlin.time.Duration.Companion.seconds /** * Preference controller for "Auto Select Network" Loading @@ -73,9 +76,13 @@ class AutoSelectPreferenceController @JvmOverloads constructor( private val getConfigForSubId: (subId: Int) -> PersistableBundle = { subId -> CarrierConfigCache.getInstance(context).getConfigForSubId(subId) }, ) : ComposePreferenceController(context, key) { ) : ComposePreferenceController(context, key), DefaultLifecycleObserver { private var isSatelliteSessionStarted = false private var isSelectedSubIdForSatellite = false private lateinit var telephonyManager: TelephonyManager private lateinit var satelliteManager: SatelliteManager private val listeners = mutableListOf<OnNetworkSelectModeListener>() @VisibleForTesting Loading @@ -83,6 +90,21 @@ class AutoSelectPreferenceController @JvmOverloads constructor( private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID val satelliteModemStateCallback = SatelliteModemStateCallback { state -> isSatelliteSessionStarted = when (state) { SatelliteManager.SATELLITE_MODEM_STATE_OFF, SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE, SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN -> false else -> true } } val selectedNbIotSatelliteSubscriptionCallback = SelectedNbIotSatelliteSubscriptionCallback { selectedSubId -> isSelectedSubIdForSatellite = selectedSubId == subId } /** * Initialization based on given subscription id. */ Loading @@ -90,7 +112,7 @@ class AutoSelectPreferenceController @JvmOverloads constructor( this.subId = subId telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!! .createForSubscriptionId(subId) satelliteManager = mContext.getSystemService(SatelliteManager::class.java)!! return this } Loading @@ -117,7 +139,10 @@ class AutoSelectPreferenceController @JvmOverloads constructor( SwitchPreference(object : SwitchPreferenceModel { override val title = stringResource(R.string.select_automatically) override val summary = { disallowedSummary } override val changeable = { disallowedSummary.isEmpty() } override val changeable = { disallowedSummary.isEmpty() && !(isSatelliteSessionStarted && isSelectedSubIdForSatellite) } override val checked = { isAuto } override val onCheckedChange: (Boolean) -> Unit = { newChecked -> if (newChecked) { Loading @@ -132,6 +157,38 @@ class AutoSelectPreferenceController @JvmOverloads constructor( }) } override fun onStart(owner: LifecycleOwner) { if (Flags.satelliteOemSettingsUxMigration()) { if (satelliteManager != null) { try { satelliteManager.registerForModemStateChanged( mContext.mainExecutor, satelliteModemStateCallback ) satelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged( mContext.mainExecutor, selectedNbIotSatelliteSubscriptionCallback ) } catch (e: IllegalStateException) { Log.w(TAG, "IllegalStateException $e") } } } } override fun onStop(owner: LifecycleOwner) { if (Flags.satelliteOemSettingsUxMigration()) { if (satelliteManager != null) { try { satelliteManager.unregisterForModemStateChanged(satelliteModemStateCallback) satelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( selectedNbIotSatelliteSubscriptionCallback ) } catch (e: IllegalStateException) { Log.w(TAG, "IllegalStateException $e") } } } } private suspend fun getDisallowedSummary(serviceState: ServiceState): String = withContext(Dispatchers.Default) { if (!serviceState.roaming && onlyAutoSelectInHome()) { Loading Loading @@ -213,6 +270,8 @@ class AutoSelectPreferenceController @JvmOverloads constructor( } companion object { private const val TAG = "AutoSelectPreferenceController" private val MINIMUM_DIALOG_TIME = 1.seconds } } tests/spa_unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.kt +60 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ package com.android.settings.network.telephony.gsm import android.content.Context import android.content.Intent import android.platform.test.annotations.EnableFlags import android.provider.Settings import android.telephony.CarrierConfigManager import android.telephony.ServiceState import android.telephony.TelephonyManager import android.telephony.satellite.SatelliteManager import androidx.compose.ui.test.assertIsEnabled import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertIsOff Loading @@ -36,6 +38,7 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R import com.android.settings.Settings.NetworkSelectActivity import com.android.settings.flags.Flags import com.android.settings.spa.preference.ComposePreference import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.delay Loading @@ -46,6 +49,8 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnit import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doNothing Loading @@ -57,6 +62,9 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class AutoSelectPreferenceControllerTest { @get:Rule val mockito = MockitoJUnit.rule() @get:Rule val composeTestRule = createComposeRule() Loading @@ -65,8 +73,12 @@ class AutoSelectPreferenceControllerTest { on { simOperatorName } doReturn OPERATOR_NAME } private val mockSatelliteManager = mock<SatelliteManager> { } private val context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager on { getSystemService(SatelliteManager::class.java) } doReturn mockSatelliteManager doNothing().whenever(mock).startActivity(any()) } Loading Loading @@ -115,7 +127,6 @@ class AutoSelectPreferenceControllerTest { .assertIsOff() } @Test fun isEnabled_isRoaming_enabled() { serviceState.roaming = true Loading Loading @@ -158,6 +169,54 @@ class AutoSelectPreferenceControllerTest { .assertIsNotEnabled() } @Test @EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) fun isEnabled_isSatelliteSessionStartedAndSelectedSubForSatellite_disabled() { controller.selectedNbIotSatelliteSubscriptionCallback .onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID) controller.satelliteModemStateCallback .onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED) composeTestRule.setContent { controller.Content() } composeTestRule.onNodeWithText(context.getString(R.string.select_automatically)) .assertIsNotEnabled() } @Test @EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) fun isEnabled_isSatelliteSessionNotStartedButIsSelectedSubForSatellite_enabled() { controller.selectedNbIotSatelliteSubscriptionCallback .onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID) controller.satelliteModemStateCallback .onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF) composeTestRule.setContent { controller.Content() } composeTestRule.onNodeWithText(context.getString(R.string.select_automatically)) .assertIsEnabled() } @Test @EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) fun isEnabled_isSatelliteSessionStartedButNotSelectedSubForSatellite_enabled() { controller.selectedNbIotSatelliteSubscriptionCallback .onSelectedNbIotSatelliteSubscriptionChanged(0) controller.satelliteModemStateCallback .onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED) composeTestRule.setContent { controller.Content() } composeTestRule.onNodeWithText(context.getString(R.string.select_automatically)) .assertIsEnabled() } @Test fun onClick_turnOff_startNetworkSelectActivity() { serviceState.isManualSelection = false Loading tests/unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java +49 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java +83 −12 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ package com.android.settings.network.telephony; import static androidx.lifecycle.Lifecycle.Event.ON_START; import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType; import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes; import static com.android.settings.network.telephony.mode.NetworkModes.addNrToLteNetworkMode; Loading @@ -33,15 +30,17 @@ import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; import android.telephony.satellite.SatelliteModemStateCallback; import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.ListPreference; import androidx.preference.ListPreferenceDialogFragmentCompat; import androidx.preference.Preference; Loading @@ -67,7 +66,7 @@ import java.util.stream.Stream; */ public class EnabledNetworkModePreferenceController extends BasePreferenceController implements ListPreference.OnPreferenceChangeListener, LifecycleObserver, ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient { private static final String LOG_TAG = "EnabledNetworkMode"; Loading @@ -83,6 +82,43 @@ public class EnabledNetworkModePreferenceController extends private PhoneCallStateTelephonyCallback mTelephonyCallback; private FragmentManager mFragmentManager; private LifecycleOwner mViewLifecycleOwner; private SatelliteManager mSatelliteManager; private boolean mIsSatelliteSessionStarted = false; private boolean mIsCurrentSubscriptionForSatellite = false; @VisibleForTesting final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback = new SelectedNbIotSatelliteSubscriptionCallback() { @Override public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) { mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId; updatePreference(); } }; @VisibleForTesting final SatelliteModemStateCallback mSatelliteModemStateCallback = new SatelliteModemStateCallback() { @Override public void onSatelliteModemStateChanged(int state) { switch (state) { case SatelliteManager.SATELLITE_MODEM_STATE_OFF: case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE: case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN: if (mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = false; updatePreference(); } break; default: if (!mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = true; updatePreference(); } break; } } }; public EnabledNetworkModePreferenceController(Context context, String key) { super(context, key); Loading @@ -90,6 +126,7 @@ public class EnabledNetworkModePreferenceController extends if (mTelephonyCallback == null) { mTelephonyCallback = new PhoneCallStateTelephonyCallback(); } mSatelliteManager = context.getSystemService(SatelliteManager.class); } @Override Loading @@ -103,8 +140,22 @@ public class EnabledNetworkModePreferenceController extends return mCallState == TelephonyManager.CALL_STATE_IDLE; } @OnLifecycleEvent(ON_START) public void onStart() { @Override public void onStart(@NonNull LifecycleOwner owner) { if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.registerForModemStateChanged( mContext.getMainExecutor(), mSatelliteModemStateCallback); mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged( mContext.getMainExecutor(), mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(LOG_TAG, "IllegalStateException : " + e); } } } mSubscriptionsListener.start(); if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) { return; Loading @@ -113,9 +164,21 @@ public class EnabledNetworkModePreferenceController extends mTelephonyCallback.register(mTelephonyManager, mSubId); } @OnLifecycleEvent(ON_STOP) public void onStop() { @Override public void onStop(@NonNull LifecycleOwner owner) { mSubscriptionsListener.stop(); if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback); mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(LOG_TAG, "IllegalStateException : " + e); } } } if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) { return; } Loading Loading @@ -147,7 +210,7 @@ public class EnabledNetworkModePreferenceController extends listPreference.setEntryValues(mBuilder.getEntryValues()); listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue())); listPreference.setSummary(mBuilder.getSummary()); boolean listPreferenceEnabled = isCallStateIdle(); boolean listPreferenceEnabled = isPreferenceShallEnabled(); listPreference.setEnabled(listPreferenceEnabled); if (!listPreferenceEnabled) { // If dialog is already opened when ListPreference disabled, dismiss them. Loading Loading @@ -203,6 +266,14 @@ public class EnabledNetworkModePreferenceController extends } } private boolean isPreferenceShallEnabled() { Log.d(LOG_TAG, "isPreferenceShallEnabled, mIsSatelliteSessionStarted : " + mIsSatelliteSessionStarted + " / mIsCurrentSubscriptionForSatellite : " + mIsCurrentSubscriptionForSatellite); return isCallStateIdle() && !(mIsSatelliteSessionStarted && mIsCurrentSubscriptionForSatellite); } private final class PreferenceEntriesBuilder { private CarrierConfigCache mCarrierConfigCache; private Context mContext; Loading
src/com/android/settings/network/telephony/PreferredNetworkModePreferenceController.java +93 −4 Original line number Diff line number Diff line Loading @@ -24,10 +24,18 @@ import android.telephony.CarrierConfigManager; import android.telephony.RadioAccessFamily; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; import android.telephony.satellite.SatelliteModemStateCallback; import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; Loading @@ -38,17 +46,56 @@ import com.android.settings.network.telephony.mode.NetworkModes; * Preference controller for "Preferred network mode" */ public class PreferredNetworkModePreferenceController extends BasePreferenceController implements ListPreference.OnPreferenceChangeListener { implements ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver { private static final String TAG = "PrefNetworkModeCtrl"; private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private CarrierConfigCache mCarrierConfigCache; private TelephonyManager mTelephonyManager; private boolean mIsGlobalCdma; private SatelliteManager mSatelliteManager; private Preference mPreference; private boolean mIsSatelliteSessionStarted = false; private boolean mIsCurrentSubscriptionForSatellite = false; @VisibleForTesting final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback = new SelectedNbIotSatelliteSubscriptionCallback() { @Override public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) { mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId; updateState(mPreference); } }; @VisibleForTesting final SatelliteModemStateCallback mSatelliteModemStateCallback = new SatelliteModemStateCallback() { @Override public void onSatelliteModemStateChanged(int state) { switch (state) { case SatelliteManager.SATELLITE_MODEM_STATE_OFF: case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE: case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN: if (mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = false; updateState(mPreference); } break; default: if (!mIsSatelliteSessionStarted) { mIsSatelliteSessionStarted = true; updateState(mPreference); } break; } } }; public PreferredNetworkModePreferenceController(Context context, String key) { super(context, key); mCarrierConfigCache = CarrierConfigCache.getInstance(context); mSatelliteManager = context.getSystemService(SatelliteManager.class); } @Override Loading @@ -58,9 +105,19 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mPreference = screen.findPreference(getPreferenceKey()); } @Override public void updateState(Preference preference) { if (preference == null) { return; } super.updateState(preference); preference.setEnabled(!(mIsCurrentSubscriptionForSatellite && mIsSatelliteSessionStarted)); final ListPreference listPreference = (ListPreference) preference; final int networkMode = getPreferredNetworkMode(); listPreference.setValue(Integer.toString(networkMode)); Loading Loading @@ -90,6 +147,38 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL); } @Override public void onStart(@NonNull LifecycleOwner owner) { if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.registerForModemStateChanged( mContext.getMainExecutor(), mSatelliteModemStateCallback); mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged( mContext.getMainExecutor(), mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(TAG, "IllegalStateException : " + e); } } } } @Override public void onStop(@NonNull LifecycleOwner owner) { if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) { if (mSatelliteManager != null) { try { mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback); mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( mSelectedNbIotSatelliteSubscriptionCallback); } catch (IllegalStateException e) { Log.w(TAG, "IllegalStateException : " + e); } } } } private int getPreferredNetworkMode() { if (mTelephonyManager == null) { Log.w(TAG, "TelephonyManager is null"); Loading
src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.kt +66 −7 Original line number Diff line number Diff line Loading @@ -25,18 +25,22 @@ import android.telephony.CarrierConfigManager import android.telephony.ServiceState import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.satellite.SatelliteManager import android.telephony.satellite.SatelliteModemStateCallback import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback import android.util.Log import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.res.stringResource import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settings.R import com.android.settings.Settings.NetworkSelectActivity import com.android.settings.flags.Flags import com.android.settings.network.CarrierConfigCache import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.network.telephony.allowedNetworkTypesFlow Loading @@ -46,8 +50,6 @@ import com.android.settingslib.spa.framework.compose.OverridableFlow import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import kotlin.properties.Delegates.notNull import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.delay Loading @@ -59,6 +61,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlin.time.Duration.Companion.seconds /** * Preference controller for "Auto Select Network" Loading @@ -73,9 +76,13 @@ class AutoSelectPreferenceController @JvmOverloads constructor( private val getConfigForSubId: (subId: Int) -> PersistableBundle = { subId -> CarrierConfigCache.getInstance(context).getConfigForSubId(subId) }, ) : ComposePreferenceController(context, key) { ) : ComposePreferenceController(context, key), DefaultLifecycleObserver { private var isSatelliteSessionStarted = false private var isSelectedSubIdForSatellite = false private lateinit var telephonyManager: TelephonyManager private lateinit var satelliteManager: SatelliteManager private val listeners = mutableListOf<OnNetworkSelectModeListener>() @VisibleForTesting Loading @@ -83,6 +90,21 @@ class AutoSelectPreferenceController @JvmOverloads constructor( private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID val satelliteModemStateCallback = SatelliteModemStateCallback { state -> isSatelliteSessionStarted = when (state) { SatelliteManager.SATELLITE_MODEM_STATE_OFF, SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE, SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN -> false else -> true } } val selectedNbIotSatelliteSubscriptionCallback = SelectedNbIotSatelliteSubscriptionCallback { selectedSubId -> isSelectedSubIdForSatellite = selectedSubId == subId } /** * Initialization based on given subscription id. */ Loading @@ -90,7 +112,7 @@ class AutoSelectPreferenceController @JvmOverloads constructor( this.subId = subId telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!! .createForSubscriptionId(subId) satelliteManager = mContext.getSystemService(SatelliteManager::class.java)!! return this } Loading @@ -117,7 +139,10 @@ class AutoSelectPreferenceController @JvmOverloads constructor( SwitchPreference(object : SwitchPreferenceModel { override val title = stringResource(R.string.select_automatically) override val summary = { disallowedSummary } override val changeable = { disallowedSummary.isEmpty() } override val changeable = { disallowedSummary.isEmpty() && !(isSatelliteSessionStarted && isSelectedSubIdForSatellite) } override val checked = { isAuto } override val onCheckedChange: (Boolean) -> Unit = { newChecked -> if (newChecked) { Loading @@ -132,6 +157,38 @@ class AutoSelectPreferenceController @JvmOverloads constructor( }) } override fun onStart(owner: LifecycleOwner) { if (Flags.satelliteOemSettingsUxMigration()) { if (satelliteManager != null) { try { satelliteManager.registerForModemStateChanged( mContext.mainExecutor, satelliteModemStateCallback ) satelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged( mContext.mainExecutor, selectedNbIotSatelliteSubscriptionCallback ) } catch (e: IllegalStateException) { Log.w(TAG, "IllegalStateException $e") } } } } override fun onStop(owner: LifecycleOwner) { if (Flags.satelliteOemSettingsUxMigration()) { if (satelliteManager != null) { try { satelliteManager.unregisterForModemStateChanged(satelliteModemStateCallback) satelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged( selectedNbIotSatelliteSubscriptionCallback ) } catch (e: IllegalStateException) { Log.w(TAG, "IllegalStateException $e") } } } } private suspend fun getDisallowedSummary(serviceState: ServiceState): String = withContext(Dispatchers.Default) { if (!serviceState.roaming && onlyAutoSelectInHome()) { Loading Loading @@ -213,6 +270,8 @@ class AutoSelectPreferenceController @JvmOverloads constructor( } companion object { private const val TAG = "AutoSelectPreferenceController" private val MINIMUM_DIALOG_TIME = 1.seconds } }
tests/spa_unit/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceControllerTest.kt +60 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ package com.android.settings.network.telephony.gsm import android.content.Context import android.content.Intent import android.platform.test.annotations.EnableFlags import android.provider.Settings import android.telephony.CarrierConfigManager import android.telephony.ServiceState import android.telephony.TelephonyManager import android.telephony.satellite.SatelliteManager import androidx.compose.ui.test.assertIsEnabled import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertIsOff Loading @@ -36,6 +38,7 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R import com.android.settings.Settings.NetworkSelectActivity import com.android.settings.flags.Flags import com.android.settings.spa.preference.ComposePreference import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.delay Loading @@ -46,6 +49,8 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnit import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doNothing Loading @@ -57,6 +62,9 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class AutoSelectPreferenceControllerTest { @get:Rule val mockito = MockitoJUnit.rule() @get:Rule val composeTestRule = createComposeRule() Loading @@ -65,8 +73,12 @@ class AutoSelectPreferenceControllerTest { on { simOperatorName } doReturn OPERATOR_NAME } private val mockSatelliteManager = mock<SatelliteManager> { } private val context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager on { getSystemService(SatelliteManager::class.java) } doReturn mockSatelliteManager doNothing().whenever(mock).startActivity(any()) } Loading Loading @@ -115,7 +127,6 @@ class AutoSelectPreferenceControllerTest { .assertIsOff() } @Test fun isEnabled_isRoaming_enabled() { serviceState.roaming = true Loading Loading @@ -158,6 +169,54 @@ class AutoSelectPreferenceControllerTest { .assertIsNotEnabled() } @Test @EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) fun isEnabled_isSatelliteSessionStartedAndSelectedSubForSatellite_disabled() { controller.selectedNbIotSatelliteSubscriptionCallback .onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID) controller.satelliteModemStateCallback .onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED) composeTestRule.setContent { controller.Content() } composeTestRule.onNodeWithText(context.getString(R.string.select_automatically)) .assertIsNotEnabled() } @Test @EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) fun isEnabled_isSatelliteSessionNotStartedButIsSelectedSubForSatellite_enabled() { controller.selectedNbIotSatelliteSubscriptionCallback .onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID) controller.satelliteModemStateCallback .onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF) composeTestRule.setContent { controller.Content() } composeTestRule.onNodeWithText(context.getString(R.string.select_automatically)) .assertIsEnabled() } @Test @EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION) fun isEnabled_isSatelliteSessionStartedButNotSelectedSubForSatellite_enabled() { controller.selectedNbIotSatelliteSubscriptionCallback .onSelectedNbIotSatelliteSubscriptionChanged(0) controller.satelliteModemStateCallback .onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED) composeTestRule.setContent { controller.Content() } composeTestRule.onNodeWithText(context.getString(R.string.select_automatically)) .assertIsEnabled() } @Test fun onClick_turnOff_startNetworkSelectActivity() { serviceState.isManualSelection = false Loading
tests/unit/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java +49 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes