Phone number only available for admin users

The phone number is hidden to non-admin users, following the same
reasoning that exists for other telephony-specific fields like the
baseband IMEI.

Bug: 392808943
Flag: EXEMPT bugfix
Test: atest PhoneNumberPreferenceControllerTest
Test: atest MobileNetworkPhoneNumberPreferenceControllerTest

Change-Id: I4e612219d0c7439930e91b3e1d6e368a0dfd073e
This commit is contained in:
Aleksander Morgado
2025-02-06 17:49:40 +00:00
parent 035a15ac37
commit 571103b891
4 changed files with 59 additions and 17 deletions

View File

@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import android.content.Context; import android.content.Context;
import android.os.UserManager;
import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
@@ -51,8 +52,13 @@ public class PhoneNumberPreferenceController extends BasePreferenceController {
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
return SubscriptionUtil.isSimHardwareVisible(mContext) ? if (!SubscriptionUtil.isSimHardwareVisible(mContext)) {
AVAILABLE : UNSUPPORTED_ON_DEVICE; return UNSUPPORTED_ON_DEVICE;
}
if (!mContext.getSystemService(UserManager.class).isAdminUser()) {
return DISABLED_FOR_USER;
}
return AVAILABLE;
} }
@Override @Override

View File

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

View File

@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo package com.android.settings.deviceinfo
import android.content.Context import android.content.Context
import android.os.UserManager
import android.telephony.SubscriptionInfo import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
@@ -39,6 +40,7 @@ import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock import org.mockito.kotlin.mock
import org.mockito.kotlin.spy import org.mockito.kotlin.spy
import org.mockito.kotlin.stub
import org.mockito.kotlin.verify import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness import org.mockito.quality.Strictness
@@ -47,15 +49,15 @@ import org.mockito.quality.Strictness
class PhoneNumberPreferenceControllerTest { class PhoneNumberPreferenceControllerTest {
private lateinit var mockSession: MockitoSession private lateinit var mockSession: MockitoSession
private val mockUserManager = mock<UserManager>()
private val mockTelephonyManager = mock<TelephonyManager>() private val mockTelephonyManager = mock<TelephonyManager>()
private val mockSubscriptionManager = mock<SubscriptionManager>() private val mockSubscriptionManager = mock<SubscriptionManager>()
private val context: Context = private val context: Context =
spy(ApplicationProvider.getApplicationContext()) { spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(SubscriptionManager::class.java) } doReturn on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager
mockSubscriptionManager
on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
on { getSystemService(UserManager::class.java) } doReturn mockUserManager
} }
private val subscriptionInfo = mock<SubscriptionInfo>() private val subscriptionInfo = mock<SubscriptionInfo>()
@@ -76,6 +78,9 @@ class PhoneNumberPreferenceControllerTest {
// By default, available // By default, available
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
mockUserManager.stub {
on { isAdminUser } doReturn true
}
preference.setKey(controller.preferenceKey) preference.setKey(controller.preferenceKey)
preference.isVisible = true preference.isVisible = true
@@ -155,17 +160,27 @@ class PhoneNumberPreferenceControllerTest {
} }
@Test @Test
fun getAvailabilityStatus_simHardwareVisible_displayed() { fun getAvailabilityStatus_simHardwareVisible_userAdmin_displayed() {
// Use defaults from setup() // Use defaults from setup()
val availabilityStatus = controller.availabilityStatus val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE) assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE)
} }
@Test @Test
fun getAvailabilityStatus_notSimHardwareVisible_notDisplayed() { fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notDisplayed() {
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false) whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
val availabilityStatus = controller.availabilityStatus val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE) assertThat(availabilityStatus).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE)
} }
@Test
fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notDisplayed() {
mockUserManager.stub {
on { isAdminUser } doReturn false
}
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER)
}
} }

View File

@@ -17,6 +17,7 @@
package com.android.settings.network.telephony package com.android.settings.network.telephony
import android.content.Context import android.content.Context
import android.os.UserManager
import androidx.lifecycle.testing.TestLifecycleOwner import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
@@ -37,6 +38,7 @@ import org.junit.runner.RunWith
import org.mockito.MockitoSession import org.mockito.MockitoSession
import org.mockito.kotlin.doReturn import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.stub import org.mockito.kotlin.stub
import org.mockito.kotlin.whenever import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness import org.mockito.quality.Strictness
@@ -45,9 +47,14 @@ import org.mockito.quality.Strictness
class MobileNetworkPhoneNumberPreferenceControllerTest { class MobileNetworkPhoneNumberPreferenceControllerTest {
private lateinit var mockSession: MockitoSession private lateinit var mockSession: MockitoSession
private val context: Context = ApplicationProvider.getApplicationContext() private val mockUserManager = mock<UserManager>()
private val mockSubscriptionRepository = mock<SubscriptionRepository>() private val mockSubscriptionRepository = mock<SubscriptionRepository>()
private val context: Context =
spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(UserManager::class.java) } doReturn mockUserManager
}
private val controller = private val controller =
MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository) MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository)
private val preference = Preference(context).apply { key = TEST_KEY } private val preference = Preference(context).apply { key = TEST_KEY }
@@ -63,6 +70,9 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
// By default, available // By default, available
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
mockUserManager.stub {
on { isAdminUser } doReturn true
}
preferenceScreen.addPreference(preference) preferenceScreen.addPreference(preference)
controller.init(SUB_ID) controller.init(SUB_ID)
@@ -99,20 +109,30 @@ class MobileNetworkPhoneNumberPreferenceControllerTest {
} }
@Test @Test
fun getAvailabilityStatus_simHardwareVisible_displayed() { fun getAvailabilityStatus_simHardwareVisible_userAdmin_displayed() {
// Use defaults from setup() // Use defaults from setup()
val availabilityStatus = controller.availabilityStatus val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE) assertThat(availabilityStatus).isEqualTo(BasePreferenceController.AVAILABLE)
} }
@Test @Test
fun getAvailabilityStatus_notSimHardwareVisible_notDisplayed() { fun getAvailabilityStatus_notSimHardwareVisible_userAdmin_notDisplayed() {
whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false) whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
val availabilityStatus = controller.availabilityStatus val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE) assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
} }
@Test
fun getAvailabilityStatus_simHardwareVisible_notUserAdmin_notDisplayed() {
mockUserManager.stub {
on { isAdminUser } doReturn false
}
val availabilityStatus = controller.availabilityStatus
assertThat(availabilityStatus).isEqualTo(BasePreferenceController.DISABLED_FOR_USER)
}
private companion object { private companion object {
const val TEST_KEY = "test_key" const val TEST_KEY = "test_key"
const val SUB_ID = 10 const val SUB_ID = 10