Loading res/xml/mobile_network_settings.xml +1 −2 Original line number Diff line number Diff line Loading @@ -18,9 +18,8 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:key="mobile_network_pref_screen"> <com.android.settings.widget.SettingsMainSwitchPreference <com.android.settings.spa.preference.ComposePreference android:key="use_sim_switch" android:title="@string/mobile_network_use_sim_on" settings:controller="com.android.settings.network.telephony.MobileNetworkSwitchController"/> <PreferenceCategory Loading src/com/android/settings/network/SatelliteManagerUtil.kt→src/com/android/settings/network/SatelliteRepository.kt +138 −0 Original line number Diff line number Diff line Loading @@ -19,29 +19,36 @@ package com.android.settings.network import android.content.Context import android.os.OutcomeReceiver import android.telephony.satellite.SatelliteManager import android.telephony.satellite.SatelliteModemStateCallback import android.util.Log import androidx.annotation.VisibleForTesting import androidx.concurrent.futures.CallbackToFutureAdapter import com.google.common.util.concurrent.Futures.immediateFuture import com.google.common.util.concurrent.ListenableFuture import java.util.concurrent.Executor import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.flowOf /** * Utility class for interacting with the SatelliteManager API. * A repository class for interacting with the SatelliteManager API. */ object SatelliteManagerUtil { private const val TAG: String = "SatelliteManagerUtil" class SatelliteRepository( private val context: Context, ) { /** * Checks if the satellite modem is enabled. * * @param context The application context * @param executor The executor to run the asynchronous operation on * @return A ListenableFuture that will resolve to `true` if the satellite modem enabled, * `false` otherwise. */ @JvmStatic fun requestIsEnabled(context: Context, executor: Executor): ListenableFuture<Boolean> { fun requestIsEnabled(executor: Executor): ListenableFuture<Boolean> { val satelliteManager: SatelliteManager? = context.getSystemService(SatelliteManager::class.java) if (satelliteManager == null) { Loading @@ -66,4 +73,66 @@ object SatelliteManagerUtil { "requestIsEnabled" } } /** * Provides a Flow that emits the enabled state of the satellite modem. Updates are triggered * when the modem state changes. * * @param defaultDispatcher The CoroutineDispatcher to use (Defaults to `Dispatchers.Default`). * @return A Flow emitting `true` when the modem is enabled and `false` otherwise. */ fun getIsModemEnabledFlow( defaultDispatcher: CoroutineDispatcher = Dispatchers.Default, ): Flow<Boolean> { val satelliteManager: SatelliteManager? = context.getSystemService(SatelliteManager::class.java) if (satelliteManager == null) { Log.w(TAG, "SatelliteManager is null") return flowOf(false) } return callbackFlow { val callback = SatelliteModemStateCallback { state -> val isEnabled = convertSatelliteModemStateToEnabledState(state) Log.i(TAG, "Satellite modem state changed: state=$state, isEnabled=$isEnabled") trySend(isEnabled) } val result = satelliteManager.registerForModemStateChanged( defaultDispatcher.asExecutor(), callback ) Log.i(TAG, "Call registerForModemStateChanged: result=$result") awaitClose { satelliteManager.unregisterForModemStateChanged(callback) } } } /** * Converts a [SatelliteManager.SatelliteModemState] to a boolean representing whether the modem * is enabled. * * @param state The SatelliteModemState provided by the SatelliteManager. * @return `true` if the modem is enabled, `false` otherwise. */ @VisibleForTesting fun convertSatelliteModemStateToEnabledState( @SatelliteManager.SatelliteModemState state: Int, ): Boolean { // Mapping table based on logic from b/315928920#comment24 return when (state) { SatelliteManager.SATELLITE_MODEM_STATE_IDLE, SatelliteManager.SATELLITE_MODEM_STATE_LISTENING, SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING, SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING, SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED -> true else -> false } } companion object { private const val TAG: String = "SatelliteRepository" } } src/com/android/settings/network/SubscriptionInfoListViewModel.kt +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.Application import android.telephony.SubscriptionManager import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.android.settings.network.telephony.getSelectableSubscriptionInfoList import com.android.settings.network.telephony.subscriptionsChangedFlow import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted Loading @@ -41,10 +42,10 @@ class SubscriptionInfoListViewModel(application: Application) : AndroidViewModel }.stateIn(scope, SharingStarted.Eagerly, initialValue = emptyList()) /** * Getting the Selectable SubscriptionInfo List from the SubscriptionManager's * Getting the Selectable SubscriptionInfo List from the SubscriptionRepository's * getAvailableSubscriptionInfoList */ val selectableSubscriptionInfoListFlow = application.subscriptionsChangedFlow().map { SubscriptionUtil.getSelectableSubscriptionInfoList(application) application.getSelectableSubscriptionInfoList() }.stateIn(scope, SharingStarted.Eagerly, initialValue = emptyList()) } src/com/android/settings/network/SubscriptionUtil.java +2 −35 Original line number Diff line number Diff line Loading @@ -50,12 +50,12 @@ import com.android.settings.network.helper.SelectableSubscriptions; import com.android.settings.network.helper.SubscriptionAnnotation; import com.android.settings.network.telephony.DeleteEuiccSubscriptionDialogActivity; import com.android.settings.network.telephony.EuiccRacConnectivityDialogActivity; import com.android.settings.network.telephony.SubscriptionRepositoryKt; import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; Loading Loading @@ -505,40 +505,7 @@ public class SubscriptionUtil { * @return list of user selectable subscriptions. */ public static List<SubscriptionInfo> getSelectableSubscriptionInfoList(Context context) { SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class); List<SubscriptionInfo> availableList = subManager.getAvailableSubscriptionInfoList(); if (availableList == null) { return null; } else { // Multiple subscriptions in a group should only have one representative. // It should be the current active primary subscription if any, or any // primary subscription. List<SubscriptionInfo> selectableList = new ArrayList<>(); Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>(); for (SubscriptionInfo info : availableList) { // Opportunistic subscriptions are considered invisible // to users so they should never be returned. if (!isSubscriptionVisible(subManager, context, info)) continue; ParcelUuid groupUuid = info.getGroupUuid(); if (groupUuid == null) { // Doesn't belong to any group. Add in the list. selectableList.add(info); } else if (!groupMap.containsKey(groupUuid) || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) { // If it belongs to a group that has never been recorded or it's the current // active subscription, add it in the list. selectableList.remove(groupMap.get(groupUuid)); selectableList.add(info); groupMap.put(groupUuid, info); } } Log.d(TAG, "getSelectableSubscriptionInfoList: " + selectableList); return selectableList; } return SubscriptionRepositoryKt.getSelectableSubscriptionInfoList(context); } /** Loading src/com/android/settings/network/telephony/MobileNetworkSwitchController.javadeleted 100644 → 0 +0 −147 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.network.telephony; import static android.telephony.TelephonyManager.CALL_STATE_IDLE; import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; import android.content.Context; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.PreferenceScreen; import com.android.settings.core.BasePreferenceController; import com.android.settings.network.SubscriptionUtil; import com.android.settings.network.SubscriptionsChangeListener; import com.android.settings.widget.SettingsMainSwitchPreference; /** This controls a switch to allow enabling/disabling a mobile network */ public class MobileNetworkSwitchController extends BasePreferenceController implements SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver { private static final String TAG = "MobileNetworkSwitchCtrl"; private SettingsMainSwitchPreference mSwitchBar; private int mSubId; private SubscriptionsChangeListener mChangeListener; private SubscriptionManager mSubscriptionManager; private TelephonyManager mTelephonyManager; private CallStateTelephonyCallback mCallStateCallback; public MobileNetworkSwitchController(Context context, String preferenceKey) { super(context, preferenceKey); mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class); mTelephonyManager = mContext.getSystemService(TelephonyManager.class); mChangeListener = new SubscriptionsChangeListener(context, this); } void init(int subId) { mSubId = subId; mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId); } @OnLifecycleEvent(ON_RESUME) public void onResume() { mChangeListener.start(); if (mCallStateCallback == null) { mCallStateCallback = new CallStateTelephonyCallback(); mTelephonyManager.registerTelephonyCallback( mContext.getMainExecutor(), mCallStateCallback); } update(); } @OnLifecycleEvent(ON_PAUSE) public void onPause() { if (mCallStateCallback != null) { mTelephonyManager.unregisterTelephonyCallback(mCallStateCallback); mCallStateCallback = null; } mChangeListener.stop(); } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mSwitchBar = (SettingsMainSwitchPreference) screen.findPreference(mPreferenceKey); mSwitchBar.setOnBeforeCheckedChangeListener((isChecked) -> { // TODO b/135222940: re-evaluate whether to use // mSubscriptionManager#isSubscriptionEnabled if (mSubscriptionManager.isActiveSubscriptionId(mSubId) != isChecked) { SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, mSubId, isChecked); return true; } return false; }); update(); } private void update() { if (mSwitchBar == null) { return; } SubscriptionInfo subInfo = null; for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) { if (info.getSubscriptionId() == mSubId) { subInfo = info; break; } } // For eSIM, we always want the toggle. If telephony stack support disabling a pSIM // directly, we show the toggle. if (subInfo == null || (!subInfo.isEmbedded() && !SubscriptionUtil.showToggleForPhysicalSim( mSubscriptionManager))) { mSwitchBar.hide(); } else { mSwitchBar.show(); mSwitchBar.setCheckedInternal(mSubscriptionManager.isActiveSubscriptionId(mSubId)); } } @Override public int getAvailabilityStatus() { return AVAILABLE_UNSEARCHABLE; } @Override public void onAirplaneModeChanged(boolean airplaneModeEnabled) { } @Override public void onSubscriptionsChanged() { update(); } private class CallStateTelephonyCallback extends TelephonyCallback implements TelephonyCallback.CallStateListener { @Override public void onCallStateChanged(int state) { mSwitchBar.setSwitchBarEnabled(state == CALL_STATE_IDLE); } } } Loading
res/xml/mobile_network_settings.xml +1 −2 Original line number Diff line number Diff line Loading @@ -18,9 +18,8 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:key="mobile_network_pref_screen"> <com.android.settings.widget.SettingsMainSwitchPreference <com.android.settings.spa.preference.ComposePreference android:key="use_sim_switch" android:title="@string/mobile_network_use_sim_on" settings:controller="com.android.settings.network.telephony.MobileNetworkSwitchController"/> <PreferenceCategory Loading
src/com/android/settings/network/SatelliteManagerUtil.kt→src/com/android/settings/network/SatelliteRepository.kt +138 −0 Original line number Diff line number Diff line Loading @@ -19,29 +19,36 @@ package com.android.settings.network import android.content.Context import android.os.OutcomeReceiver import android.telephony.satellite.SatelliteManager import android.telephony.satellite.SatelliteModemStateCallback import android.util.Log import androidx.annotation.VisibleForTesting import androidx.concurrent.futures.CallbackToFutureAdapter import com.google.common.util.concurrent.Futures.immediateFuture import com.google.common.util.concurrent.ListenableFuture import java.util.concurrent.Executor import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.flowOf /** * Utility class for interacting with the SatelliteManager API. * A repository class for interacting with the SatelliteManager API. */ object SatelliteManagerUtil { private const val TAG: String = "SatelliteManagerUtil" class SatelliteRepository( private val context: Context, ) { /** * Checks if the satellite modem is enabled. * * @param context The application context * @param executor The executor to run the asynchronous operation on * @return A ListenableFuture that will resolve to `true` if the satellite modem enabled, * `false` otherwise. */ @JvmStatic fun requestIsEnabled(context: Context, executor: Executor): ListenableFuture<Boolean> { fun requestIsEnabled(executor: Executor): ListenableFuture<Boolean> { val satelliteManager: SatelliteManager? = context.getSystemService(SatelliteManager::class.java) if (satelliteManager == null) { Loading @@ -66,4 +73,66 @@ object SatelliteManagerUtil { "requestIsEnabled" } } /** * Provides a Flow that emits the enabled state of the satellite modem. Updates are triggered * when the modem state changes. * * @param defaultDispatcher The CoroutineDispatcher to use (Defaults to `Dispatchers.Default`). * @return A Flow emitting `true` when the modem is enabled and `false` otherwise. */ fun getIsModemEnabledFlow( defaultDispatcher: CoroutineDispatcher = Dispatchers.Default, ): Flow<Boolean> { val satelliteManager: SatelliteManager? = context.getSystemService(SatelliteManager::class.java) if (satelliteManager == null) { Log.w(TAG, "SatelliteManager is null") return flowOf(false) } return callbackFlow { val callback = SatelliteModemStateCallback { state -> val isEnabled = convertSatelliteModemStateToEnabledState(state) Log.i(TAG, "Satellite modem state changed: state=$state, isEnabled=$isEnabled") trySend(isEnabled) } val result = satelliteManager.registerForModemStateChanged( defaultDispatcher.asExecutor(), callback ) Log.i(TAG, "Call registerForModemStateChanged: result=$result") awaitClose { satelliteManager.unregisterForModemStateChanged(callback) } } } /** * Converts a [SatelliteManager.SatelliteModemState] to a boolean representing whether the modem * is enabled. * * @param state The SatelliteModemState provided by the SatelliteManager. * @return `true` if the modem is enabled, `false` otherwise. */ @VisibleForTesting fun convertSatelliteModemStateToEnabledState( @SatelliteManager.SatelliteModemState state: Int, ): Boolean { // Mapping table based on logic from b/315928920#comment24 return when (state) { SatelliteManager.SATELLITE_MODEM_STATE_IDLE, SatelliteManager.SATELLITE_MODEM_STATE_LISTENING, SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING, SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING, SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED -> true else -> false } } companion object { private const val TAG: String = "SatelliteRepository" } }
src/com/android/settings/network/SubscriptionInfoListViewModel.kt +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.Application import android.telephony.SubscriptionManager import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.android.settings.network.telephony.getSelectableSubscriptionInfoList import com.android.settings.network.telephony.subscriptionsChangedFlow import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted Loading @@ -41,10 +42,10 @@ class SubscriptionInfoListViewModel(application: Application) : AndroidViewModel }.stateIn(scope, SharingStarted.Eagerly, initialValue = emptyList()) /** * Getting the Selectable SubscriptionInfo List from the SubscriptionManager's * Getting the Selectable SubscriptionInfo List from the SubscriptionRepository's * getAvailableSubscriptionInfoList */ val selectableSubscriptionInfoListFlow = application.subscriptionsChangedFlow().map { SubscriptionUtil.getSelectableSubscriptionInfoList(application) application.getSelectableSubscriptionInfoList() }.stateIn(scope, SharingStarted.Eagerly, initialValue = emptyList()) }
src/com/android/settings/network/SubscriptionUtil.java +2 −35 Original line number Diff line number Diff line Loading @@ -50,12 +50,12 @@ import com.android.settings.network.helper.SelectableSubscriptions; import com.android.settings.network.helper.SubscriptionAnnotation; import com.android.settings.network.telephony.DeleteEuiccSubscriptionDialogActivity; import com.android.settings.network.telephony.EuiccRacConnectivityDialogActivity; import com.android.settings.network.telephony.SubscriptionRepositoryKt; import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; Loading Loading @@ -505,40 +505,7 @@ public class SubscriptionUtil { * @return list of user selectable subscriptions. */ public static List<SubscriptionInfo> getSelectableSubscriptionInfoList(Context context) { SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class); List<SubscriptionInfo> availableList = subManager.getAvailableSubscriptionInfoList(); if (availableList == null) { return null; } else { // Multiple subscriptions in a group should only have one representative. // It should be the current active primary subscription if any, or any // primary subscription. List<SubscriptionInfo> selectableList = new ArrayList<>(); Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>(); for (SubscriptionInfo info : availableList) { // Opportunistic subscriptions are considered invisible // to users so they should never be returned. if (!isSubscriptionVisible(subManager, context, info)) continue; ParcelUuid groupUuid = info.getGroupUuid(); if (groupUuid == null) { // Doesn't belong to any group. Add in the list. selectableList.add(info); } else if (!groupMap.containsKey(groupUuid) || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) { // If it belongs to a group that has never been recorded or it's the current // active subscription, add it in the list. selectableList.remove(groupMap.get(groupUuid)); selectableList.add(info); groupMap.put(groupUuid, info); } } Log.d(TAG, "getSelectableSubscriptionInfoList: " + selectableList); return selectableList; } return SubscriptionRepositoryKt.getSelectableSubscriptionInfoList(context); } /** Loading
src/com/android/settings/network/telephony/MobileNetworkSwitchController.javadeleted 100644 → 0 +0 −147 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.network.telephony; import static android.telephony.TelephonyManager.CALL_STATE_IDLE; import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; import android.content.Context; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.PreferenceScreen; import com.android.settings.core.BasePreferenceController; import com.android.settings.network.SubscriptionUtil; import com.android.settings.network.SubscriptionsChangeListener; import com.android.settings.widget.SettingsMainSwitchPreference; /** This controls a switch to allow enabling/disabling a mobile network */ public class MobileNetworkSwitchController extends BasePreferenceController implements SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver { private static final String TAG = "MobileNetworkSwitchCtrl"; private SettingsMainSwitchPreference mSwitchBar; private int mSubId; private SubscriptionsChangeListener mChangeListener; private SubscriptionManager mSubscriptionManager; private TelephonyManager mTelephonyManager; private CallStateTelephonyCallback mCallStateCallback; public MobileNetworkSwitchController(Context context, String preferenceKey) { super(context, preferenceKey); mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class); mTelephonyManager = mContext.getSystemService(TelephonyManager.class); mChangeListener = new SubscriptionsChangeListener(context, this); } void init(int subId) { mSubId = subId; mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId); } @OnLifecycleEvent(ON_RESUME) public void onResume() { mChangeListener.start(); if (mCallStateCallback == null) { mCallStateCallback = new CallStateTelephonyCallback(); mTelephonyManager.registerTelephonyCallback( mContext.getMainExecutor(), mCallStateCallback); } update(); } @OnLifecycleEvent(ON_PAUSE) public void onPause() { if (mCallStateCallback != null) { mTelephonyManager.unregisterTelephonyCallback(mCallStateCallback); mCallStateCallback = null; } mChangeListener.stop(); } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); mSwitchBar = (SettingsMainSwitchPreference) screen.findPreference(mPreferenceKey); mSwitchBar.setOnBeforeCheckedChangeListener((isChecked) -> { // TODO b/135222940: re-evaluate whether to use // mSubscriptionManager#isSubscriptionEnabled if (mSubscriptionManager.isActiveSubscriptionId(mSubId) != isChecked) { SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, mSubId, isChecked); return true; } return false; }); update(); } private void update() { if (mSwitchBar == null) { return; } SubscriptionInfo subInfo = null; for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) { if (info.getSubscriptionId() == mSubId) { subInfo = info; break; } } // For eSIM, we always want the toggle. If telephony stack support disabling a pSIM // directly, we show the toggle. if (subInfo == null || (!subInfo.isEmbedded() && !SubscriptionUtil.showToggleForPhysicalSim( mSubscriptionManager))) { mSwitchBar.hide(); } else { mSwitchBar.show(); mSwitchBar.setCheckedInternal(mSubscriptionManager.isActiveSubscriptionId(mSubId)); } } @Override public int getAvailabilityStatus() { return AVAILABLE_UNSEARCHABLE; } @Override public void onAirplaneModeChanged(boolean airplaneModeEnabled) { } @Override public void onSubscriptionsChanged() { update(); } private class CallStateTelephonyCallback extends TelephonyCallback implements TelephonyCallback.CallStateListener { @Override public void onCallStateChanged(int state) { mSwitchBar.setSwitchBarEnabled(state == CALL_STATE_IDLE); } } }