/* * Copyright (C) 2023 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.telephony.CarrierConfigManager import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import android.telephony.TelephonyManager import android.telephony.data.ApnSetting import androidx.preference.Preference import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.core.BasePreferenceController.AVAILABLE import com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE import com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.stub import org.mockito.kotlin.verify @RunWith(AndroidJUnit4::class) class MmsMessagePreferenceControllerTest { private val mockTelephonyManager1: TelephonyManager = mock { on { isDeviceSmsCapable() } doReturn true on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true } private val mockTelephonyManager2: TelephonyManager = mock { on { isDeviceSmsCapable() } doReturn true on { createForSubscriptionId(SUB_1_ID) } doReturn mockTelephonyManager1 on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true } private val mockTelephonyManager: TelephonyManager = mock { on { isDeviceSmsCapable() } doReturn true on { createForSubscriptionId(SUB_1_ID) } doReturn mockTelephonyManager1 on { createForSubscriptionId(SUB_2_ID) } doReturn mockTelephonyManager2 on { createForSubscriptionId(INVALID_SUBSCRIPTION_ID) } doReturn mock } private var context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager } private var defaultDataSubId = SUB_1_ID private val controller = MmsMessagePreferenceController( context = context, key = KEY, getDefaultDataSubId = { defaultDataSubId }, ) @Before fun setUp() { CarrierConfigRepository.resetForTest() CarrierConfigRepository.setBooleanForTest( subId = SUB_1_ID, key = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL, value = true, ) CarrierConfigRepository.setBooleanForTest( subId = SUB_2_ID, key = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL, value = true, ) } @Test fun getAvailabilityStatus_noMessagingCapability_unavailable() { mockTelephonyManager.stub { on { isDeviceSmsCapable() } doReturn false } controller.init(SUB_1_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(UNSUPPORTED_ON_DEVICE) } @Test fun getAvailabilityStatus_invalidSubscription_unavailable() { controller.init(INVALID_SUBSCRIPTION_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun getAvailabilityStatus_mobileDataOn_unavailable() { mockTelephonyManager2.stub { on { isDataEnabled } doReturn true } controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun getAvailabilityStatus_meteredOff_unavailable() { mockTelephonyManager2.stub { on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn false } controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun getAvailabilityStatus_isDefaultDataAndDataOnAndAutoDataSwitchOn_unavailable() { defaultDataSubId = SUB_2_ID mockTelephonyManager2.stub { on { isDataEnabled } doReturn true on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun getAvailabilityStatus_isDefaultDataAndDataOffAndAutoDataSwitchOn_available() { defaultDataSubId = SUB_2_ID mockTelephonyManager2.stub { on { isDataEnabled } doReturn false on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(AVAILABLE) } @Test fun notifyAirplaneModeChanged_isAirplaneModeOn_setEnableFalse() { val testPreference = mock() controller.notifyAirplaneModeChanged(true) controller.updateState(testPreference) assertThat(controller.isAirplaneModeOn).isTrue() verify(testPreference).isEnabled = false } @Test fun notifyAirplaneModeChanged_isAirplaneModeOff_setEnableTrue() { val testPreference = mock() controller.notifyAirplaneModeChanged(false) controller.updateState(testPreference) assertThat(controller.isAirplaneModeOn).isFalse() verify(testPreference).isEnabled = true } @Test fun getAvailabilityStatus_notDefaultDataAndDataOnAndAutoDataSwitchOn_unavailable() { defaultDataSubId = SUB_1_ID mockTelephonyManager1.stub { on { isDataEnabled } doReturn true } mockTelephonyManager2.stub { on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun getAvailabilityStatus_notDefaultDataAndDataOffAndAutoDataSwitchOn_available() { defaultDataSubId = SUB_1_ID mockTelephonyManager1.stub { on { isDataEnabled } doReturn false } mockTelephonyManager2.stub { on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(AVAILABLE) } @Test fun getAvailabilityStatus_carrierConfigEnabledMmsFalse_unavailable() { defaultDataSubId = SUB_2_ID mockTelephonyManager2.stub { on { isDataEnabled } doReturn false on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } CarrierConfigRepository.setBooleanForTest( subId = SUB_2_ID, key = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL, value = false, ) controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun searchIsAvailable_notDefaultDataAndDataOnAndAutoDataSwitchOn_unavailable() { mockTelephonyManager1.stub { on { isDataEnabled } doReturn true } mockTelephonyManager2.stub { on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } val mmsMessageSearchItem = MmsMessageSearchItem(context) { SUB_1_ID } val isAvailable = mmsMessageSearchItem.isAvailable(SUB_2_ID) assertThat(isAvailable).isFalse() } @Test fun searchIsAvailable_notDefaultDataAndDataOffAndAutoDataSwitchOn_available() { mockTelephonyManager1.stub { on { isDataEnabled } doReturn false } mockTelephonyManager2.stub { on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } val mmsMessageSearchItem = MmsMessageSearchItem(context) { SUB_1_ID } val isAvailable = mmsMessageSearchItem.isAvailable(SUB_2_ID) assertThat(isAvailable).isTrue() } @Test fun searchIsAvailable_carrierConfigEnabledMmsFalse_unavailable() { defaultDataSubId = SUB_2_ID mockTelephonyManager2.stub { on { isDataEnabled } doReturn false on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) } doReturn true } CarrierConfigRepository.setBooleanForTest( subId = SUB_2_ID, key = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL, value = false, ) controller.init(SUB_2_ID) val availabilityStatus = controller.getAvailabilityStatus() assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE) } @Test fun isChecked_whenMmsNotAlwaysAllowed_returnFalse() { mockTelephonyManager2.stub { on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED) } doReturn false } controller.init(SUB_2_ID) val isChecked = controller.isChecked() assertThat(isChecked).isFalse() } @Test fun isChecked_whenMmsAlwaysAllowed_returnTrue() { mockTelephonyManager2.stub { on { isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED) } doReturn true } controller.init(SUB_2_ID) val isChecked = controller.isChecked() assertThat(isChecked).isTrue() } @Test fun setChecked_setTrue_setDataIntoSubscriptionManager() { controller.init(SUB_2_ID) controller.setChecked(true) verify(mockTelephonyManager2) .setMobileDataPolicyEnabled( TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, true, ) } @Test fun setChecked_setFalse_setDataIntoSubscriptionManager() { controller.init(SUB_2_ID) controller.setChecked(false) verify(mockTelephonyManager2) .setMobileDataPolicyEnabled( TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, false, ) } private companion object { const val KEY = "mms_message" const val SUB_1_ID = 1 const val SUB_2_ID = 2 } }