Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a54a9756 authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Setup backup calling for new UI" into main

parents 49feaed3 59a28a24
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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 -> {
+0 −10
Original line number Diff line number Diff line
@@ -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;
@@ -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
     */
+20 −89
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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)
@@ -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;
    }
@@ -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()
@@ -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);
        }
+5 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
+14 −2
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ interface ImsMmTelRepository {
        @MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int,
        @AccessNetworkConstants.TransportType transportType: Int,
    ): Boolean

    suspend fun setCrossSimCallingEnabled(enabled: Boolean)
}

class ImsMmTelRepositoryImpl(
@@ -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(
@@ -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