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

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

Merge "Use wifiCallingReadyFlow in WifiCallingSettingsForSub" into main

parents f1d17b00 562f56bb
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -21,14 +21,16 @@ import android.telephony.AccessNetworkConstants
import android.telephony.CarrierConfigManager
import android.telephony.CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.telephony.ims.ImsMmTelManager.WiFiCallingMode
import android.telephony.ims.feature.MmTelFeature
import android.telephony.ims.stub.ImsRegistrationImplBase
import androidx.lifecycle.LifecycleOwner
import com.android.settings.network.telephony.ims.ImsMmTelRepository
import com.android.settings.network.telephony.ims.ImsMmTelRepositoryImpl
import com.android.settings.network.telephony.ims.imsFeatureProvisionedFlow
import com.android.settings.network.telephony.subscriptionsChangedFlow
import com.android.settings.network.telephony.telephonyManager
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -38,13 +40,19 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

class WifiCallingRepository(
interface IWifiCallingRepository {
    /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
    fun collectIsWifiCallingReadyFlow(lifecycleOwner: LifecycleOwner, action: (Boolean) -> Unit)
}

class WifiCallingRepository
@JvmOverloads
constructor(
    private val context: Context,
    private val subId: Int,
    private val imsMmTelRepository: ImsMmTelRepository = ImsMmTelRepositoryImpl(context, subId)
) {
    private val telephonyManager = context.getSystemService(TelephonyManager::class.java)!!
        .createForSubscriptionId(subId)
) : IWifiCallingRepository {
    private val telephonyManager = context.telephonyManager(subId)

    private val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java)!!

@@ -59,6 +67,14 @@ class WifiCallingRepository(
            .getConfigForSubId(subId, KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL)
            .getBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL)

    /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
    override fun collectIsWifiCallingReadyFlow(
        lifecycleOwner: LifecycleOwner,
        action: (Boolean) -> Unit,
    ) {
        wifiCallingReadyFlow().collectLatestWithLifecycle(lifecycleOwner, action = action)
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    fun wifiCallingReadyFlow(): Flow<Boolean> {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false)
+30 −59
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ProvisioningManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -42,12 +41,14 @@ import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceScreen;

import com.android.ims.ImsConfig;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.flags.Flags;
@@ -57,8 +58,12 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.network.telephony.wificalling.IWifiCallingRepository;
import com.android.settings.network.telephony.wificalling.WifiCallingRepository;
import com.android.settings.widget.SettingsMainSwitchPreference;

import kotlin.Unit;

import java.util.List;

/**
@@ -103,7 +108,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment

    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private ImsMmTelManager mImsMmTelManager;
    private ProvisioningManager mProvisioningManager;
    private TelephonyManager mTelephonyManager;

    private PhoneTelephonyCallback mTelephonyCallback;
@@ -188,19 +192,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
                return true;
            };

    private final ProvisioningManager.Callback mProvisioningCallback =
            new ProvisioningManager.Callback() {
                @Override
                public void onProvisioningIntChanged(int item, int value) {
                    if (item == ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED
                            || item == ImsConfig.ConfigConstants.VLT_SETTING_ENABLED) {
                        // The provisioning policy might have changed. Update the body to make sure
                        // this change takes effect if needed.
                        updateBody();
                    }
                }
            };

    @VisibleForTesting
    void showAlert(Intent intent) {
        final Context context = getActivity();
@@ -263,14 +254,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
        return new WifiCallingQueryImsState(getContext(), subId);
    }

    @VisibleForTesting
    ProvisioningManager getImsProvisioningManager() {
        if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
            return null;
        }
        return ProvisioningManager.createForSubscriptionId(mSubId);
    }

    @VisibleForTesting
    ImsMmTelManager getImsMmTelManager() {
        if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
@@ -294,7 +277,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
                    FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        }

        mProvisioningManager = getImsProvisioningManager();
        mImsMmTelManager = getImsMmTelManager();

        mSwitchBar = (SettingsMainSwitchPreference) findPreference(SWITCH_BAR);
@@ -336,19 +318,33 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        getWifiCallingRepository().collectIsWifiCallingReadyFlow(
                getLifecycleOwner(), (isWifiWifiCallingReadyFlow) -> {
                    if (!isWifiWifiCallingReadyFlow) {
                        // This screen is not allowed to be shown due to provisioning policy and
                        // should therefore be closed.
                        finish();
                    }
                    return Unit.INSTANCE;
                });
    }

    @VisibleForTesting
    boolean isWfcProvisionedOnDevice() {
        return queryImsState(mSubId).isWifiCallingProvisioned();
    @NonNull
    IWifiCallingRepository getWifiCallingRepository() {
        return new WifiCallingRepository(requireContext(), mSubId);
    }

    private void updateBody() {
        if (!isWfcProvisionedOnDevice()) {
            // This screen is not allowed to be shown due to provisioning policy and should
            // therefore be closed.
            finish();
            return;
    @VisibleForTesting
    @NonNull
    LifecycleOwner getLifecycleOwner() {
        return getViewLifecycleOwner();
    }

    private void updateBody() {
        final CarrierConfigManager configManager = (CarrierConfigManager)
                getSystemService(Context.CARRIER_CONFIG_SERVICE);
        boolean isWifiOnlySupported = true;
@@ -448,8 +444,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
        if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) {
            showAlert(intent);
        }
        // Register callback for provisioning changes.
        registerProvisioningChangedCallback();
    }

    @Override
@@ -462,8 +456,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
            mSwitchBar.removeOnSwitchChangeListener(this);
        }
        context.unregisterReceiver(mIntentReceiver);
        // Remove callback for provisioning changes.
        unregisterProvisioningChangedCallback();
    }

    /**
@@ -699,27 +691,6 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
        return SubscriptionManager.getResourcesForSubId(getContext(), mSubId);
    }

    @VisibleForTesting
    void registerProvisioningChangedCallback() {
        if (mProvisioningManager == null) {
            return;
        }
        try {
            mProvisioningManager.registerProvisioningChangedCallback(getContext().getMainExecutor(),
                    mProvisioningCallback);
        } catch (Exception ex) {
            Log.w(TAG, "onResume: Unable to register callback for provisioning changes.");
        }
    }

    @VisibleForTesting
    void unregisterProvisioningChangedCallback() {
        if (mProvisioningManager == null) {
            return;
        }
        mProvisioningManager.unregisterProvisioningChangedCallback(mProvisioningCallback);
    }

    /**
     * Determine whether to override roaming Wi-Fi calling preference when device is connected to
     * non-terrestrial network.
+33 −18
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ import android.telephony.TelephonyManager;
import android.telephony.ims.ImsMmTelManager;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

@@ -56,10 +58,14 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.network.ims.MockWifiCallingQueryImsState;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.network.telephony.wificalling.IWifiCallingRepository;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settings.widget.SettingsMainSwitchPreference;

import kotlin.Unit;
import kotlin.jvm.functions.Function1;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -183,35 +189,24 @@ public class WifiCallingSettingsForSubTest {
    }

    @Test
    public void onResume_provisioningAllowed_shouldNotFinish() {
        // Call onResume while provisioning is allowed.
        mFragment.onResume();
    public void onViewCreated_provisioningAllowed_shouldNotFinish() {
        // Call onViewCreated while provisioning is allowed.
        mFragment.onViewCreated(mView, null);

        // Verify that finish() is not called.
        verify(mFragment, never()).finish();
    }

    @Test
    public void onResume_provisioningDisallowed_shouldFinish() {
        // Call onResume while provisioning is disallowed.
        mQueryImsState.setIsProvisionedOnDevice(false);
        mFragment.onResume();
    public void onViewCreated_provisioningDisallowed_shouldFinish() {
        // Call onViewCreated while provisioning is disallowed.
        mFragment.mIsWifiCallingReady = false;
        mFragment.onViewCreated(mView, null);

        // Verify that finish() is called
        verify(mFragment).finish();
    }

    @Test
    public void onResumeOnPause_provisioningCallbackRegistration() throws Exception {
        // Verify that provisioning callback is registered after call to onResume().
        mFragment.onResume();
        verify(mFragment).registerProvisioningChangedCallback();

        // Verify that provisioning callback is unregistered after call to onPause.
        mFragment.onPause();
        verify(mFragment).unregisterProvisioningChangedCallback();
    }

    @Test
    public void onResume_useWfcHomeModeConfigFalseAndEditable_shouldShowWfcRoaming() {
        // Call onResume to update the WFC roaming preference.
@@ -377,6 +372,7 @@ public class WifiCallingSettingsForSubTest {

    protected class TestFragment extends WifiCallingSettingsForSub {
        private SettingsMainSwitchPreference mSwitchPref;
        protected boolean mIsWifiCallingReady = true;

        protected void setSwitchBar(SettingsMainSwitchPreference switchPref) {
            mSwitchPref = switchPref;
@@ -421,6 +417,25 @@ public class WifiCallingSettingsForSubTest {
            return mQueryImsState;
        }

        @Override
        @NonNull
        IWifiCallingRepository getWifiCallingRepository() {
            return new IWifiCallingRepository() {
                @Override
                public void collectIsWifiCallingReadyFlow(
                        @NonNull LifecycleOwner lifecycleOwner,
                        @NonNull Function1<? super Boolean, Unit> action) {
                    action.invoke(mIsWifiCallingReady);
                }
            };
        }

        @NonNull
        @Override
        LifecycleOwner getLifecycleOwner() {
            return this;
        }

        @Override
        void showAlert(Intent intent) {
        }