Loading src/com/android/settings/network/MobileDataEnabledFlow.kt +2 −2 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ import kotlinx.coroutines.flow.merge * * Note: This flow can only notify enabled status changes, cannot provide the latest status. */ fun Context.mobileDataEnabledFlow(subId: Int): Flow<Unit> { val flow = settingsGlobalChangeFlow(Settings.Global.MOBILE_DATA) fun Context.mobileDataEnabledFlow(subId: Int, sendInitialValue: Boolean = true): Flow<Unit> { val flow = settingsGlobalChangeFlow(Settings.Global.MOBILE_DATA, sendInitialValue) return when (subId) { SubscriptionManager.INVALID_SUBSCRIPTION_ID -> flow else -> { Loading src/com/android/settings/network/ProxySubscriptionManager.java +0 −10 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import android.telephony.SubscriptionManager; import android.util.Log; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; Loading Loading @@ -242,15 +241,6 @@ public class ProxySubscriptionManager implements LifecycleObserver { return mSubscriptionMonitor.getAccessibleSubscriptionInfo(subId); } /** * Gets a list of active, visible subscription Id(s) of the currently active SIM(s). * * @return the list of subId's that are active and visible; the length may be 0. */ public @NonNull int[] getActiveSubscriptionIdList() { return mSubscriptionMonitor.getActiveSubscriptionIdList(); } /** * Clear data cached within proxy */ Loading src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java +20 −89 Original line number Diff line number Diff line Loading @@ -19,20 +19,14 @@ package com.android.settings.network.telephony; import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.ims.ImsException; import android.telephony.ims.ImsManager; import android.telephony.ims.ImsMmTelManager; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; Loading @@ -40,15 +34,11 @@ import androidx.preference.PreferenceScreen; import androidx.preference.TwoStatePreference; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.datausage.DataUsageUtils; import com.android.settings.flags.Flags; import com.android.settings.network.MobileDataContentObserver; import com.android.settings.network.ProxySubscriptionManager; import com.android.settings.network.SubscriptionsChangeListener; import com.android.settings.network.ims.WifiCallingQueryImsState; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settings.network.telephony.wificalling.CrossSimCallingViewModel; /** * Controls whether switch mobile data to the non-default SIM if the non-default SIM has better Loading @@ -63,25 +53,29 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenceController implements LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient { private static final String LOG_TAG = "AutoDataSwitchPrefCtrl"; @Nullable private TwoStatePreference mPreference; @Nullable private SubscriptionsChangeListener mChangeListener; @Nullable private TelephonyManager mManager; @Nullable private MobileDataContentObserver mMobileDataContentObserver; @Nullable private CrossSimCallingViewModel mCrossSimCallingViewModel; @Nullable private PreferenceScreen mScreen; private final MetricsFeatureProvider mMetricsFeatureProvider; public AutoDataSwitchPreferenceController(Context context, String preferenceKey) { public AutoDataSwitchPreferenceController( @NonNull Context context, @NonNull String preferenceKey) { super(context, preferenceKey); mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } void init(int subId) { void init(int subId, @Nullable CrossSimCallingViewModel crossSimCallingViewModel) { this.mSubId = subId; mManager = mContext.getSystemService(TelephonyManager.class).createForSubscriptionId(subId); mCrossSimCallingViewModel = crossSimCallingViewModel; } @OnLifecycleEvent(ON_RESUME) Loading Loading @@ -121,35 +115,15 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH); } private int getOtherSubId(@NonNull int[] subIds) { if (subIds.length > 1) { for (int subId : subIds) { if (subId != mSubId) { return subId; } } } return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } private boolean isEnabled(int subId) { if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { return false; } TelephonyManager telephonyManager = mContext.getSystemService( TelephonyManager.class).createForSubscriptionId(subId); return telephonyManager != null && telephonyManager.isMobileDataPolicyEnabled( TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH); } @Override public boolean setChecked(boolean isChecked) { if (mManager != null) { mManager.setMobileDataPolicyEnabled( TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, isChecked); if (mContext.getResources().getBoolean( R.bool.config_auto_data_switch_enables_cross_sim_calling)) { trySetCrossSimCalling(mContext, getActiveSubscriptionIdList(), isChecked /* enabled */); } if (mCrossSimCallingViewModel != null) { mCrossSimCallingViewModel.updateCrossSimCalling(); } return true; } Loading @@ -159,40 +133,6 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc return DataUsageUtils.hasMobileData(mContext); } private boolean isCrossSimCallingAllowedByPlatform(Context context, int subId) { if ((new WifiCallingQueryImsState(context, subId)).isWifiCallingSupported()) { PersistableBundle bundle = getCarrierConfigForSubId(subId); return (bundle != null) && bundle.getBoolean( CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false /*default*/); } return false; } protected ImsMmTelManager getImsMmTelManager(Context context, int subId) { ImsManager imsMgr = context.getSystemService(ImsManager.class); return (imsMgr == null) ? null : imsMgr.getImsMmTelManager(subId); } private void trySetCrossSimCallingPerSub(Context context, int subId, boolean enabled) { try { getImsMmTelManager(context, subId).setCrossSimCallingEnabled(enabled); } catch (ImsException | IllegalArgumentException | NullPointerException exception) { Log.w(LOG_TAG, "failed to change cross SIM calling configuration to " + enabled + " for subID " + subId + "with exception: ", exception); } } private void trySetCrossSimCalling(Context context, int[] subIds, boolean enabled) { mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_UPDATE_CROSS_SIM_CALLING_ON_AUTO_DATA_SWITCH_EVENT, enabled); for (int subId : subIds) { if (isCrossSimCallingAllowedByPlatform(context, subId)) { trySetCrossSimCallingPerSub(context, subId, enabled); } } } @Override public int getAvailabilityStatus(int subId) { if (Flags.isDualSimOnboardingEnabled() Loading Loading @@ -221,20 +161,11 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc updateState(mPreference); } private int[] getActiveSubscriptionIdList() { return ProxySubscriptionManager.getInstance(mContext).getActiveSubscriptionIdList(); } /** * Trigger displaying preference when Mobile data content changed. */ @VisibleForTesting public void refreshPreference() { if (mContext.getResources().getBoolean( R.bool.config_auto_data_switch_enables_cross_sim_calling)) { int[] subIds = getActiveSubscriptionIdList(); trySetCrossSimCalling(mContext, subIds, isEnabled(getOtherSubId(subIds))); } if (mScreen != null) { super.displayPreference(mScreen); } Loading src/com/android/settings/network/telephony/MobileNetworkSettings.java +5 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.ViewModelProvider; import androidx.preference.Preference; import com.android.settings.R; Loading @@ -53,6 +54,7 @@ import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceCon import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController; import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController; import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController; import com.android.settings.network.telephony.wificalling.CrossSimCallingViewModel; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.wifi.WifiPickerTrackerHelper; import com.android.settingslib.core.AbstractPreferenceController; Loading Loading @@ -240,7 +242,9 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme use(CarrierSettingsVersionPreferenceController.class).init(mSubId); use(BillingCyclePreferenceController.class).init(mSubId); use(MmsMessagePreferenceController.class).init(mSubId); use(AutoDataSwitchPreferenceController.class).init(mSubId); final var crossSimCallingViewModel = new ViewModelProvider(this).get(CrossSimCallingViewModel.class); use(AutoDataSwitchPreferenceController.class).init(mSubId, crossSimCallingViewModel); use(DisabledSubscriptionController.class).init(mSubId); use(DeleteSimProfilePreferenceController.class).init(mSubId); use(DisableSimFooterPreferenceController.class).init(mSubId); Loading src/com/android/settings/network/telephony/ims/ImsMmTelRepository.kt +14 −2 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ interface ImsMmTelRepository { @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int, @AccessNetworkConstants.TransportType transportType: Int, ): Boolean suspend fun setCrossSimCallingEnabled(enabled: Boolean) } class ImsMmTelRepositoryImpl( Loading Loading @@ -130,6 +132,7 @@ class ImsMmTelRepositoryImpl( @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int, @AccessNetworkConstants.TransportType transportType: Int, ): Boolean = withContext(Dispatchers.Default) { val logName = "isSupported(capability=$capability,transportType=$transportType)" suspendCancellableCoroutine { continuation -> try { imsMmTelManager.isSupported( Loading @@ -140,9 +143,18 @@ class ImsMmTelRepositoryImpl( ) } catch (e: Exception) { continuation.resume(false) Log.w(TAG, "[$subId] isSupported failed", e) Log.w(TAG, "[$subId] $logName failed", e) } }.also { Log.d(TAG, "[$subId] $logName = $it") } } override suspend fun setCrossSimCallingEnabled(enabled: Boolean) { try { imsMmTelManager.setCrossSimCallingEnabled(enabled) Log.d(TAG, "[$subId] setCrossSimCallingEnabled: $enabled") } catch (e: Exception) { Log.e(TAG, "[$subId] failed setCrossSimCallingEnabled to $enabled", e) } }.also { Log.d(TAG, "[$subId] isSupported = $it") } } private companion object { Loading Loading
src/com/android/settings/network/MobileDataEnabledFlow.kt +2 −2 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ import kotlinx.coroutines.flow.merge * * Note: This flow can only notify enabled status changes, cannot provide the latest status. */ fun Context.mobileDataEnabledFlow(subId: Int): Flow<Unit> { val flow = settingsGlobalChangeFlow(Settings.Global.MOBILE_DATA) fun Context.mobileDataEnabledFlow(subId: Int, sendInitialValue: Boolean = true): Flow<Unit> { val flow = settingsGlobalChangeFlow(Settings.Global.MOBILE_DATA, sendInitialValue) return when (subId) { SubscriptionManager.INVALID_SUBSCRIPTION_ID -> flow else -> { Loading
src/com/android/settings/network/ProxySubscriptionManager.java +0 −10 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import android.telephony.SubscriptionManager; import android.util.Log; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; Loading Loading @@ -242,15 +241,6 @@ public class ProxySubscriptionManager implements LifecycleObserver { return mSubscriptionMonitor.getAccessibleSubscriptionInfo(subId); } /** * Gets a list of active, visible subscription Id(s) of the currently active SIM(s). * * @return the list of subId's that are active and visible; the length may be 0. */ public @NonNull int[] getActiveSubscriptionIdList() { return mSubscriptionMonitor.getActiveSubscriptionIdList(); } /** * Clear data cached within proxy */ Loading
src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java +20 −89 Original line number Diff line number Diff line Loading @@ -19,20 +19,14 @@ package com.android.settings.network.telephony; import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.ims.ImsException; import android.telephony.ims.ImsManager; import android.telephony.ims.ImsMmTelManager; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; Loading @@ -40,15 +34,11 @@ import androidx.preference.PreferenceScreen; import androidx.preference.TwoStatePreference; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.datausage.DataUsageUtils; import com.android.settings.flags.Flags; import com.android.settings.network.MobileDataContentObserver; import com.android.settings.network.ProxySubscriptionManager; import com.android.settings.network.SubscriptionsChangeListener; import com.android.settings.network.ims.WifiCallingQueryImsState; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settings.network.telephony.wificalling.CrossSimCallingViewModel; /** * Controls whether switch mobile data to the non-default SIM if the non-default SIM has better Loading @@ -63,25 +53,29 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenceController implements LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient { private static final String LOG_TAG = "AutoDataSwitchPrefCtrl"; @Nullable private TwoStatePreference mPreference; @Nullable private SubscriptionsChangeListener mChangeListener; @Nullable private TelephonyManager mManager; @Nullable private MobileDataContentObserver mMobileDataContentObserver; @Nullable private CrossSimCallingViewModel mCrossSimCallingViewModel; @Nullable private PreferenceScreen mScreen; private final MetricsFeatureProvider mMetricsFeatureProvider; public AutoDataSwitchPreferenceController(Context context, String preferenceKey) { public AutoDataSwitchPreferenceController( @NonNull Context context, @NonNull String preferenceKey) { super(context, preferenceKey); mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } void init(int subId) { void init(int subId, @Nullable CrossSimCallingViewModel crossSimCallingViewModel) { this.mSubId = subId; mManager = mContext.getSystemService(TelephonyManager.class).createForSubscriptionId(subId); mCrossSimCallingViewModel = crossSimCallingViewModel; } @OnLifecycleEvent(ON_RESUME) Loading Loading @@ -121,35 +115,15 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH); } private int getOtherSubId(@NonNull int[] subIds) { if (subIds.length > 1) { for (int subId : subIds) { if (subId != mSubId) { return subId; } } } return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } private boolean isEnabled(int subId) { if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { return false; } TelephonyManager telephonyManager = mContext.getSystemService( TelephonyManager.class).createForSubscriptionId(subId); return telephonyManager != null && telephonyManager.isMobileDataPolicyEnabled( TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH); } @Override public boolean setChecked(boolean isChecked) { if (mManager != null) { mManager.setMobileDataPolicyEnabled( TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, isChecked); if (mContext.getResources().getBoolean( R.bool.config_auto_data_switch_enables_cross_sim_calling)) { trySetCrossSimCalling(mContext, getActiveSubscriptionIdList(), isChecked /* enabled */); } if (mCrossSimCallingViewModel != null) { mCrossSimCallingViewModel.updateCrossSimCalling(); } return true; } Loading @@ -159,40 +133,6 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc return DataUsageUtils.hasMobileData(mContext); } private boolean isCrossSimCallingAllowedByPlatform(Context context, int subId) { if ((new WifiCallingQueryImsState(context, subId)).isWifiCallingSupported()) { PersistableBundle bundle = getCarrierConfigForSubId(subId); return (bundle != null) && bundle.getBoolean( CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false /*default*/); } return false; } protected ImsMmTelManager getImsMmTelManager(Context context, int subId) { ImsManager imsMgr = context.getSystemService(ImsManager.class); return (imsMgr == null) ? null : imsMgr.getImsMmTelManager(subId); } private void trySetCrossSimCallingPerSub(Context context, int subId, boolean enabled) { try { getImsMmTelManager(context, subId).setCrossSimCallingEnabled(enabled); } catch (ImsException | IllegalArgumentException | NullPointerException exception) { Log.w(LOG_TAG, "failed to change cross SIM calling configuration to " + enabled + " for subID " + subId + "with exception: ", exception); } } private void trySetCrossSimCalling(Context context, int[] subIds, boolean enabled) { mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_UPDATE_CROSS_SIM_CALLING_ON_AUTO_DATA_SWITCH_EVENT, enabled); for (int subId : subIds) { if (isCrossSimCallingAllowedByPlatform(context, subId)) { trySetCrossSimCallingPerSub(context, subId, enabled); } } } @Override public int getAvailabilityStatus(int subId) { if (Flags.isDualSimOnboardingEnabled() Loading Loading @@ -221,20 +161,11 @@ public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenc updateState(mPreference); } private int[] getActiveSubscriptionIdList() { return ProxySubscriptionManager.getInstance(mContext).getActiveSubscriptionIdList(); } /** * Trigger displaying preference when Mobile data content changed. */ @VisibleForTesting public void refreshPreference() { if (mContext.getResources().getBoolean( R.bool.config_auto_data_switch_enables_cross_sim_calling)) { int[] subIds = getActiveSubscriptionIdList(); trySetCrossSimCalling(mContext, subIds, isEnabled(getOtherSubId(subIds))); } if (mScreen != null) { super.displayPreference(mScreen); } Loading
src/com/android/settings/network/telephony/MobileNetworkSettings.java +5 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.ViewModelProvider; import androidx.preference.Preference; import com.android.settings.R; Loading @@ -53,6 +54,7 @@ import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceCon import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController; import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController; import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController; import com.android.settings.network.telephony.wificalling.CrossSimCallingViewModel; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.wifi.WifiPickerTrackerHelper; import com.android.settingslib.core.AbstractPreferenceController; Loading Loading @@ -240,7 +242,9 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme use(CarrierSettingsVersionPreferenceController.class).init(mSubId); use(BillingCyclePreferenceController.class).init(mSubId); use(MmsMessagePreferenceController.class).init(mSubId); use(AutoDataSwitchPreferenceController.class).init(mSubId); final var crossSimCallingViewModel = new ViewModelProvider(this).get(CrossSimCallingViewModel.class); use(AutoDataSwitchPreferenceController.class).init(mSubId, crossSimCallingViewModel); use(DisabledSubscriptionController.class).init(mSubId); use(DeleteSimProfilePreferenceController.class).init(mSubId); use(DisableSimFooterPreferenceController.class).init(mSubId); Loading
src/com/android/settings/network/telephony/ims/ImsMmTelRepository.kt +14 −2 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ interface ImsMmTelRepository { @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int, @AccessNetworkConstants.TransportType transportType: Int, ): Boolean suspend fun setCrossSimCallingEnabled(enabled: Boolean) } class ImsMmTelRepositoryImpl( Loading Loading @@ -130,6 +132,7 @@ class ImsMmTelRepositoryImpl( @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int, @AccessNetworkConstants.TransportType transportType: Int, ): Boolean = withContext(Dispatchers.Default) { val logName = "isSupported(capability=$capability,transportType=$transportType)" suspendCancellableCoroutine { continuation -> try { imsMmTelManager.isSupported( Loading @@ -140,9 +143,18 @@ class ImsMmTelRepositoryImpl( ) } catch (e: Exception) { continuation.resume(false) Log.w(TAG, "[$subId] isSupported failed", e) Log.w(TAG, "[$subId] $logName failed", e) } }.also { Log.d(TAG, "[$subId] $logName = $it") } } override suspend fun setCrossSimCallingEnabled(enabled: Boolean) { try { imsMmTelManager.setCrossSimCallingEnabled(enabled) Log.d(TAG, "[$subId] setCrossSimCallingEnabled: $enabled") } catch (e: Exception) { Log.e(TAG, "[$subId] failed setCrossSimCallingEnabled to $enabled", e) } }.also { Log.d(TAG, "[$subId] isSupported = $it") } } private companion object { Loading