Merge changes from topic "hide-phone-number" into main

* changes:
  Phone number only available if telephony capable
  Phone number only available for admin users
  Added unit test for MobileNetworkPhoneNumberPreferenceController visibility
  Added unit tests for PhoneNumberPreferenceController visibility
This commit is contained in:
Aleksander Morgado
2025-02-13 00:06:32 -08:00
committed by Android (Google) Code Review
4 changed files with 126 additions and 16 deletions

View File

@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo;
import android.content.Context;
import android.os.UserManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -30,6 +31,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.SubscriptionUtil;
import com.android.settingslib.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -51,8 +53,13 @@ public class PhoneNumberPreferenceController extends BasePreferenceController {
@Override
public int getAvailabilityStatus() {
return SubscriptionUtil.isSimHardwareVisible(mContext) ?
AVAILABLE : UNSUPPORTED_ON_DEVICE;
if (!SubscriptionUtil.isSimHardwareVisible(mContext) || Utils.isWifiOnly(mContext)) {
return UNSUPPORTED_ON_DEVICE;
}
if (!mContext.getSystemService(UserManager.class).isAdminUser()) {
return DISABLED_FOR_USER;
}
return AVAILABLE;
}
@Override

View File

@@ -25,6 +25,8 @@ import com.android.settings.R
import com.android.settings.flags.Flags
import com.android.settings.network.SubscriptionUtil
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.android.settingslib.Utils
/** Preference controller for "Phone number" */
class MobileNetworkPhoneNumberPreferenceController
@@ -41,13 +43,14 @@ constructor(
mSubId = subId
}
override fun getAvailabilityStatus(subId: Int): Int =
when {
!Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE
SubscriptionManager.isValidSubscriptionId(subId) &&
SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE
else -> CONDITIONALLY_UNAVAILABLE
}
override fun getAvailabilityStatus(subId: Int): Int = when {
!Flags.isDualSimOnboardingEnabled()
|| !SubscriptionManager.isValidSubscriptionId(subId)
|| !SubscriptionUtil.isSimHardwareVisible(mContext)
|| Utils.isWifiOnly(mContext) -> CONDITIONALLY_UNAVAILABLE
!mContext.userManager.isAdminUser -> DISABLED_FOR_USER
else -> AVAILABLE
}
override fun displayPreference(screen: PreferenceScreen) {
super.displayPreference(screen)

View File

@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo
import android.content.Context
import android.os.UserManager
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
@@ -25,30 +26,39 @@ import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.settings.R
import com.android.settings.core.BasePreferenceController
import com.android.settings.network.SubscriptionUtil
import com.android.settingslib.Utils
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.MockitoSession
import org.mockito.kotlin.any
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
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
@RunWith(AndroidJUnit4::class)
class PhoneNumberPreferenceControllerTest {
private lateinit var mockSession: MockitoSession
private val mockUserManager = mock<UserManager>()
private val mockTelephonyManager = mock<TelephonyManager>()
private val mockSubscriptionManager = mock<SubscriptionManager>()
private val context: Context =
spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(SubscriptionManager::class.java) } doReturn
mockSubscriptionManager
on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager
on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
on { getSystemService(UserManager::class.java) } doReturn mockUserManager
}
private val subscriptionInfo = mock<SubscriptionInfo>()
@@ -61,6 +71,20 @@ class PhoneNumberPreferenceControllerTest {
@Before
fun setup() {
mockSession =
ExtendedMockito.mockitoSession()
.mockStatic(SubscriptionUtil::class.java)
.mockStatic(Utils::class.java)
.strictness(Strictness.LENIENT)
.startMocking()
// By default, available
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
whenever(Utils.isWifiOnly(context)).thenReturn(false)
mockUserManager.stub {
on { isAdminUser } doReturn true
}
preference.setKey(controller.preferenceKey)
preference.isVisible = true
preferenceScreen.addPreference(preference)
@@ -70,6 +94,11 @@ class PhoneNumberPreferenceControllerTest {
doReturn(secondPreference).whenever(controller).createNewPreference(context)
}
@After
fun teardown() {
mockSession.finishMocking()
}
@Test
fun displayPreference_multiSim_shouldAddSecondPreference() {
whenever(mockTelephonyManager.phoneCount).thenReturn(2)
@@ -132,4 +161,37 @@ class PhoneNumberPreferenceControllerTest {
verify(preference).summary = context.getString(R.string.device_info_not_available)
}
@Test
fun getAvailabilityStatus_simHardwareVisible_userAdmin_notWifiOnly_displayed() {
// Use defaults from setup()
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE)
}
@Test
fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notWifiOnly_notDisplayed() {
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE)
}
@Test
fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notWifiOnly_notDisplayed() {
mockUserManager.stub {
on { isAdminUser } doReturn false
}
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER)
}
@Test
fun getAvailabilityStatus_simHardwareVisible_userAdmin_wifiOnly_notDisplayed() {
whenever(Utils.isWifiOnly(context)).thenReturn(true)
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE)
}
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.network.telephony
import android.content.Context
import android.os.UserManager
import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.preference.Preference
import androidx.preference.PreferenceManager
@@ -26,6 +27,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.settings.R
import com.android.settings.core.BasePreferenceController
import com.android.settings.network.SubscriptionUtil
import com.android.settingslib.Utils
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flowOf
@@ -37,6 +39,7 @@ import org.junit.runner.RunWith
import org.mockito.MockitoSession
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.stub
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
@@ -45,9 +48,14 @@ import org.mockito.quality.Strictness
class MobileNetworkPhoneNumberPreferenceControllerTest {
private lateinit var mockSession: MockitoSession
private val context: Context = ApplicationProvider.getApplicationContext()
private val mockUserManager = mock<UserManager>()
private val mockSubscriptionRepository = mock<SubscriptionRepository>()
private val context: Context =
spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(UserManager::class.java) } doReturn mockUserManager
}
private val controller =
MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository)
private val preference = Preference(context).apply { key = TEST_KEY }
@@ -58,9 +66,17 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
mockSession =
ExtendedMockito.mockitoSession()
.mockStatic(SubscriptionUtil::class.java)
.mockStatic(Utils::class.java)
.strictness(Strictness.LENIENT)
.startMocking()
// By default, available
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
whenever(Utils.isWifiOnly(context)).thenReturn(false)
mockUserManager.stub {
on { isAdminUser } doReturn true
}
preferenceScreen.addPreference(preference)
controller.init(SUB_ID)
controller.displayPreference(preferenceScreen)
@@ -73,7 +89,6 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
@Test
fun onViewCreated_cannotGetPhoneNumber_displayUnknown() = runBlocking {
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
mockSubscriptionRepository.stub {
on { phoneNumberFlow(SUB_ID) } doReturn flowOf(null)
}
@@ -86,7 +101,6 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
@Test
fun onViewCreated_canGetPhoneNumber_displayPhoneNumber() = runBlocking {
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
mockSubscriptionRepository.stub {
on { phoneNumberFlow(SUB_ID) } doReturn flowOf(PHONE_NUMBER)
}
@@ -98,11 +112,35 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
}
@Test
fun getAvailabilityStatus_notSimHardwareVisible() {
fun getAvailabilityStatus_simHardwareVisible_userAdmin_notWifiOnly_displayed() {
// Use defaults from setup()
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE)
}
@Test
fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notWifiOnly_notDisplayed() {
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
}
@Test
fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notWifiOnly_notDisplayed() {
mockUserManager.stub {
on { isAdminUser } doReturn false
}
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER)
}
@Test
fun getAvailabilityStatus_simHardwareVisible_userAdmin_wifiOnly_notDisplayed() {
whenever(Utils.isWifiOnly(context)).thenReturn(true)
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
}