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

Commit 502f3c6c authored by jackqdyulei's avatar jackqdyulei
Browse files

Refactor 4gForLTE preference

Bug: 114749736
Test: RunSettingsRoboTests
Change-Id: I6a9d7044e16de2e70fadd97379b2a6de6d18525f
parent c294ce43
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@
        android:key="enhanced_4g_lte"
        android:title="@string/enhanced_4g_lte_mode_title"
        android:persistent="false"
        android:summary="@string/enhanced_4g_lte_mode_summary"/>
        android:summary="@string/enhanced_4g_lte_mode_summary"
        settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>

    <ListPreference
        android:key="preferred_network_mode_key"
+148 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.content.Context;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;

import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;

/**
 * Preference controller for "Enhanced 4G LTE"
 */
public class Enhanced4gLtePreferenceController extends TogglePreferenceController implements
        LifecycleObserver, OnStart, OnStop {

    private Preference mPreference;
    private TelephonyManager mTelephonyManager;
    private CarrierConfigManager mCarrierConfigManager;
    private PersistableBundle mCarrierConfig;
    @VisibleForTesting
    ImsManager mImsManager;
    private PhoneCallStateListener mPhoneStateListener;
    private int mSubId;

    public Enhanced4gLtePreferenceController(Context context, String key) {
        super(context, key);
        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
        mPhoneStateListener = new PhoneCallStateListener();
        mSubId =  SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    }

    @Override
    public int getAvailabilityStatus() {
        final boolean isVisible = mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
                && mImsManager != null && mCarrierConfig != null
                && mImsManager.isVolteEnabledByPlatform()
                && mImsManager.isVolteProvisionedOnDevice()
                && MobileNetworkUtils.isImsServiceStateReady(mImsManager)
                && !mCarrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL);
        return isVisible
                ? (is4gLtePrefEnabled() ? AVAILABLE : AVAILABLE_UNSEARCHABLE)
                : CONDITIONALLY_UNAVAILABLE;
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(getPreferenceKey());
    }

    @Override
    public void onStart() {
        mPhoneStateListener.register(mSubId);
    }

    @Override
    public void onStop() {
        mPhoneStateListener.unregister();
    }

    @Override
    public void updateState(Preference preference) {
        super.updateState(preference);
        final SwitchPreference switchPreference = (SwitchPreference) preference;
        final boolean useVariant4glteTitle = mCarrierConfig.getInt(
                CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT) != 0;
        int enhanced4glteModeTitleId = useVariant4glteTitle ?
                R.string.enhanced_4g_lte_mode_title_variant :
                R.string.enhanced_4g_lte_mode_title;
        switchPreference.setTitle(enhanced4glteModeTitleId);
        switchPreference.setEnabled(is4gLtePrefEnabled());
        switchPreference.setChecked(mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
                && mImsManager.isNonTtyOrTtyOnVolteEnabled());
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        mImsManager.setEnhanced4gLteModeSetting(isChecked);
        return true;
    }

    @Override
    public boolean isChecked() {
        return mImsManager.isEnhanced4gLteModeSettingEnabledByUser();
    }

    public void init(int subId) {
        mSubId = subId;
        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
        mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
        }
    }

    private boolean is4gLtePrefEnabled() {
        return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
                && mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE
                && mImsManager != null
                && mImsManager.isNonTtyOrTtyOnVolteEnabled()
                && mCarrierConfig.getBoolean(
                CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
    }

    private class PhoneCallStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            updateState(mPreference);
        }

        public void register(int subId) {
            mSubId = subId;
            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
        }

        public void unregister() {
            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
        }
    }
}
+3 −56
Original line number Diff line number Diff line
@@ -160,7 +160,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
        public void onCallStateChanged(int state, String incomingNumber) {
            if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);

            updateEnhanced4gLteState();
            updateWiFiCallState();
            updateVideoCallState();
            updatePreferredNetworkType();
@@ -296,6 +295,7 @@ public class MobileNetworkFragment extends DashboardFragment implements
        use(DataUsagePreferenceController.class).init(mSubId);
        use(PreferredNetworkModePreferenceController.class).init(mSubId);
        use(EnabledNetworkModePreferenceController.class).init(mSubId);
        use(Enhanced4gLtePreferenceController.class).init(mSubId);

        mCdmaSystemSelectPreferenceController = use(CdmaSystemSelectPreferenceController.class);
        mCdmaSystemSelectPreferenceController.init(getPreferenceManager(), mSubId);
@@ -321,7 +321,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
        mCarrierConfigManager = new CarrierConfigManager(getContext());

        mButton4glte = (SwitchPreference)findPreference(BUTTON_4G_LTE_KEY);
        mButton4glte.setOnPreferenceChangeListener(this);

        mCallingCategory = (PreferenceCategory) findPreference(CATEGORY_CALLING_KEY);
        mWiFiCallingPref = findPreference(BUTTON_WIFI_CALLING_KEY);
@@ -410,9 +409,6 @@ public class MobileNetworkFragment extends DashboardFragment implements

        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);

        // NOTE: Buttons will be enabled/disabled in mPhoneStateListener
        updateEnhanced4gLteState();

        // Video calling and WiFi calling state might have changed.
        updateCallingCategory();

@@ -490,7 +486,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
        if (DBG) {
            log("updateBody: isLteOnCdma=" + isLteOnCdma + " phoneSubId=" + phoneSubId);
        }
        prefSet.addPreference(mButton4glte);

        if (MobileNetworkUtils.showEuiccSettings(getContext())) {
            prefSet.addPreference(mEuiccSettingsPref);
@@ -549,7 +544,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
            android.util.Log.d(LOG_TAG, "keep ltePref");
        }

        updateEnhanced4gLteState();
        updatePreferredNetworkType();
        updateCallingCategory();

@@ -565,24 +559,8 @@ public class MobileNetworkFragment extends DashboardFragment implements
            }
        }

        /**
         * Enable/disable depending upon if there are any active subscriptions.
         *
         * I've decided to put this enable/disable code at the bottom as the
         * code above works even when there are no active subscriptions, thus
         * putting it afterwards is a smaller change. This can be refined later,
         * but you do need to remember that this all needs to work when subscriptions
         * change dynamically such as when hot swapping sims.
         */
        boolean useVariant4glteTitle = carrierConfig.getBoolean(
                CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL);
        int enhanced4glteModeTitleId = useVariant4glteTitle ?
                R.string.enhanced_4g_lte_mode_title_variant :
                R.string.enhanced_4g_lte_mode_title;

        mOnlyAutoSelectInHomeNW = carrierConfig.getBoolean(
                CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL);
        mButton4glte.setTitle(enhanced4glteModeTitleId);
        mLteDataServicePref.setEnabled(hasActiveSubscriptions);
        Preference ps;
        ps = findPreference(BUTTON_CELL_BROADCAST_SETTINGS);
@@ -651,13 +629,7 @@ public class MobileNetworkFragment extends DashboardFragment implements
     */
    public boolean onPreferenceChange(Preference preference, Object objValue) {
        sendMetricsEventPreferenceChanged(getPreferenceScreen(), preference, objValue);

        final int phoneSubId = mSubId;
        if (preference == mButton4glte) {
            boolean enhanced4gMode = !mButton4glte.isChecked();
            mButton4glte.setChecked(enhanced4gMode);
            mImsMgr.setEnhanced4gLteModeSetting(mButton4glte.isChecked());
        } else if (preference == mVideoCallingPref) {
        if (preference == mVideoCallingPref) {
            // If mButton4glte is not checked, mVideoCallingPref should be disabled.
            // So it only makes sense to call phoneMgr.enableVideoCalling if it's checked.
            if (mButton4glte.isChecked()) {
@@ -761,29 +733,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
                == TelephonyManager.CALL_STATE_IDLE && hasActiveSubscriptions());
    }

    private void updateEnhanced4gLteState() {
        if (mButton4glte == null) {
            return;
        }

        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);

        if ((mImsMgr == null
                || !mImsMgr.isVolteEnabledByPlatform()
                || !mImsMgr.isVolteProvisionedOnDevice()
                || !MobileNetworkUtils.isImsServiceStateReady(mImsMgr)
                || carrierConfig.getBoolean(
                CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL))) {
            getPreferenceScreen().removePreference(mButton4glte);
        } else {
            mButton4glte.setEnabled(is4gLtePrefEnabled(carrierConfig)
                    && hasActiveSubscriptions());
            boolean enh4glteMode = mImsMgr.isEnhanced4gLteModeSettingEnabledByUser()
                    && mImsMgr.isNonTtyOrTtyOnVolteEnabled();
            mButton4glte.setChecked(enh4glteMode);
        }
    }

    private void updateVideoCallState() {
        if (mVideoCallingPref == null || mCallingCategory == null) {
            return;
@@ -978,7 +927,7 @@ public class MobileNetworkFragment extends DashboardFragment implements
        }

        // MetricsEvent logging with new value, for SwitchPreferences and ListPreferences.
        if (preference == mButton4glte || preference == mVideoCallingPref) {
        if (preference == mVideoCallingPref) {
            MetricsLogger.action(getContext(), category, (Boolean) newValue);
        } else if (preference == preferenceScreen
                .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)
@@ -996,8 +945,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
            return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
        } else if (preference == mLteDataServicePref) {
            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_SET_UP_DATA_SERVICE;
        } else if (preference == mButton4glte) {
            return MetricsProto.MetricsEvent.ACTION_MOBILE_ENHANCED_4G_LTE_MODE_TOGGLE;
        } else if (preference == mEuiccSettingsPref) {
            return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_EUICC_SETTING;
        } else if (preference == mWiFiCallingPref) {
+138 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

import android.content.Context;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;

import androidx.preference.SwitchPreference;

import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedSwitchPreference;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;

@RunWith(SettingsRobolectricTestRunner.class)
public class Enhanced4gLtePreferenceControllerTest {
    private static final int SUB_ID = 2;

    @Mock
    private TelephonyManager mTelephonyManager;
    @Mock
    private TelephonyManager mInvalidTelephonyManager;
    @Mock
    private SubscriptionManager mSubscriptionManager;
    @Mock
    private CarrierConfigManager mCarrierConfigManager;
    @Mock
    private ImsManager mImsManager;

    private Enhanced4gLtePreferenceController mController;
    private SwitchPreference mPreference;
    private PersistableBundle mCarrierConfig;
    private Context mContext;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mContext = spy(RuntimeEnvironment.application);
        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
        doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
        doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
                SubscriptionManager.INVALID_SUBSCRIPTION_ID);

        mCarrierConfig = new PersistableBundle();
        doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);

        mPreference = new RestrictedSwitchPreference(mContext);
        mController = new Enhanced4gLtePreferenceController(mContext, "roaming");
        mController.mImsManager = mImsManager;
        mController.init(SUB_ID);
        mPreference.setKey(mController.getPreferenceKey());
    }

    @Test
    public void getAvailabilityStatus_invalidSubId_returnUnavailable() {
        mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);

        assertThat(mController.getAvailabilityStatus()).isEqualTo(
                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
    }

    @Test
    public void getAvailabilityStatus_volteDisabled_returnUnavailable() {
        doReturn(false).when(mImsManager).isVolteEnabledByPlatform();
        doReturn(true).when(mImsManager).isVolteProvisionedOnDevice();

        assertThat(mController.getAvailabilityStatus()).isEqualTo(
                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
    }

    @Test
    public void updateState_variant4gLte_useVariantTitle() {
        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);

        mController.updateState(mPreference);

        assertThat(mPreference.getTitle()).isEqualTo(
                mContext.getString(R.string.enhanced_4g_lte_mode_title_variant));
    }

    @Test
    public void updateState_configEnabled_prefEnabled() {
        mPreference.setEnabled(false);
        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
        doReturn(TelephonyManager.CALL_STATE_IDLE).when(mTelephonyManager).getCallState(SUB_ID);
        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);

        mController.updateState(mPreference);

        assertThat(mPreference.isEnabled()).isTrue();
    }

    @Test
    public void updateState_configOn_prefChecked() {
        mPreference.setChecked(false);
        doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();

        mController.updateState(mPreference);

        assertThat(mPreference.isChecked()).isTrue();
    }

}