Refactor SimStatusDialogRepository

- Move data logic into repository for better testing
- Check carrier config first, if not shows some items, we don't need to
  load data
- Tests in SimStatusDialogControllerTest will be fixed in later cls

Bug: 337417520
Test: manual - on SIM status
Test: unit test
Change-Id: Ia0c32882f0b35ec9154b3da58ac6a7b98c879efc
This commit is contained in:
Chaohui Wang
2024-05-27 18:24:52 +08:00
parent 659e512b1c
commit 3b925a0cfe
5 changed files with 113 additions and 64 deletions

View File

@@ -227,7 +227,6 @@ public class SimStatusDialogController implements DefaultLifecycleObserver {
updateNetworkType(); updateNetworkType();
updateRoamingStatus(serviceState); updateRoamingStatus(serviceState);
updateIccidNumber(); updateIccidNumber();
updateImsRegistrationState();
} }
/** /**
@@ -257,7 +256,7 @@ public class SimStatusDialogController implements DefaultLifecycleObserver {
.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback); .registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback);
mSubscriptionManager.addOnSubscriptionsChangedListener( mSubscriptionManager.addOnSubscriptionsChangedListener(
mContext.getMainExecutor(), mOnSubscriptionsChangedListener); mContext.getMainExecutor(), mOnSubscriptionsChangedListener);
collectImsRegistered(owner); collectSimStatusDialogInfo(owner);
if (mShowLatestAreaInfo) { if (mShowLatestAreaInfo) {
updateAreaInfoText(); updateAreaInfoText();
@@ -581,39 +580,20 @@ public class SimStatusDialogController implements DefaultLifecycleObserver {
} }
} }
private boolean isImsRegistrationStateShowUp() { private void updateImsRegistrationState(@Nullable Boolean imsRegistered) {
if (mSubscriptionInfo == null) { boolean isVisible = imsRegistered != null;
return false; mDialog.setSettingVisibility(IMS_REGISTRATION_STATE_LABEL_ID, isVisible);
} mDialog.setSettingVisibility(IMS_REGISTRATION_STATE_VALUE_ID, isVisible);
final int subscriptionId = mSubscriptionInfo.getSubscriptionId(); int stringId = Boolean.TRUE.equals(imsRegistered)
final PersistableBundle carrierConfig = ? com.android.settingslib.R.string.ims_reg_status_registered
mCarrierConfigManager.getConfigForSubId(subscriptionId); : com.android.settingslib.R.string.ims_reg_status_not_registered;
return carrierConfig == null ? false : mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(stringId));
carrierConfig.getBoolean(
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL);
} }
private void updateImsRegistrationState() { private void collectSimStatusDialogInfo(@NonNull LifecycleOwner owner) {
if (isImsRegistrationStateShowUp()) { new SimStatusDialogRepository(mContext).collectSimStatusDialogInfo(
return; owner, mSlotIndex, (simStatusDialogInfo) -> {
} updateImsRegistrationState(simStatusDialogInfo.getImsRegistered());
mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID);
mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
}
private void collectImsRegistered(@NonNull LifecycleOwner owner) {
if (!isImsRegistrationStateShowUp()) {
return;
}
new ImsRegistrationStateController(mContext).collectImsRegistered(
owner, mSlotIndex, (Boolean imsRegistered) -> {
if (imsRegistered) {
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
com.android.settingslib.R.string.ims_reg_status_registered));
} else {
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
com.android.settingslib.R.string.ims_reg_status_not_registered));
}
return Unit.INSTANCE; return Unit.INSTANCE;
} }
); );

View File

@@ -91,6 +91,13 @@ public class SimStatusDialogFragment extends InstrumentedDialogFragment {
super.onDestroy(); super.onDestroy();
} }
public void setSettingVisibility(int viewId, boolean isVisible) {
final View view = mRootView.findViewById(viewId);
if (view != null) {
view.setVisibility(isVisible ? View.VISIBLE : View.GONE);
}
}
public void removeSettingFromScreen(int viewId) { public void removeSettingFromScreen(int viewId) {
final View view = mRootView.findViewById(viewId); final View view = mRootView.findViewById(viewId);
if (view != null) { if (view != null) {

View File

@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo.simstatus package com.android.settings.deviceinfo.simstatus
import android.content.Context import android.content.Context
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
@@ -25,44 +26,82 @@ import androidx.lifecycle.repeatOnLifecycle
import com.android.settings.network.telephony.SimSlotRepository import com.android.settings.network.telephony.SimSlotRepository
import com.android.settings.network.telephony.ims.ImsMmTelRepository import com.android.settings.network.telephony.ims.ImsMmTelRepository
import com.android.settings.network.telephony.ims.ImsMmTelRepositoryImpl import com.android.settings.network.telephony.ims.ImsMmTelRepositoryImpl
import com.android.settings.network.telephony.safeGetConfig
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class ImsRegistrationStateController @JvmOverloads constructor( class SimStatusDialogRepository @JvmOverloads constructor(
private val context: Context, private val context: Context,
private val simSlotRepository: SimSlotRepository = SimSlotRepository(context), private val simSlotRepository: SimSlotRepository = SimSlotRepository(context),
private val imsMmTelRepositoryFactory: (subId: Int) -> ImsMmTelRepository = { subId -> private val imsMmTelRepositoryFactory: (subId: Int) -> ImsMmTelRepository = { subId ->
ImsMmTelRepositoryImpl(context, subId) ImsMmTelRepositoryImpl(context, subId)
}, },
) { ) {
fun collectImsRegistered( private val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java)!!
data class SimStatusDialogInfo(
val imsRegistered: Boolean? = null,
)
private data class SimStatusDialogVisibility(
val imsRegisteredShowUp: Boolean,
)
fun collectSimStatusDialogInfo(
lifecycleOwner: LifecycleOwner, lifecycleOwner: LifecycleOwner,
simSlotIndex: Int, simSlotIndex: Int,
action: (imsRegistered: Boolean) -> Unit, action: (info: SimStatusDialogInfo) -> Unit,
) { ) {
lifecycleOwner.lifecycleScope.launch { lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
imsRegisteredFlow(simSlotIndex).collect(action) simStatusDialogInfoBySlotFlow(simSlotIndex).collect(action)
} }
} }
} }
private fun imsRegisteredFlow(simSlotIndex: Int): Flow<Boolean> = private fun simStatusDialogInfoBySlotFlow(simSlotIndex: Int): Flow<SimStatusDialogInfo> =
simSlotRepository.subIdInSimSlotFlow(simSlotIndex) simSlotRepository.subIdInSimSlotFlow(simSlotIndex)
.flatMapLatest { subId -> .flatMapLatest { subId ->
if (SubscriptionManager.isValidSubscriptionId(subId)) { if (SubscriptionManager.isValidSubscriptionId(subId)) {
imsMmTelRepositoryFactory(subId).imsRegisteredFlow() simStatusDialogInfoFlow(subId)
} else { } else {
flowOf(false) flowOf(SimStatusDialogInfo())
} }
} }
.conflate() .conflate()
.flowOn(Dispatchers.Default) .flowOn(Dispatchers.Default)
private fun simStatusDialogInfoFlow(subId: Int): Flow<SimStatusDialogInfo> =
showUpFlow(subId).flatMapLatest { visibility ->
combine(
if (visibility.imsRegisteredShowUp) {
imsMmTelRepositoryFactory(subId).imsRegisteredFlow()
} else flowOf(null),
) { (imsRegistered) ->
SimStatusDialogInfo(imsRegistered = imsRegistered)
}
}
private fun showUpFlow(subId: Int) = flow {
val config = carrierConfigManager.safeGetConfig(
keys = listOf(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL),
subId = subId,
)
emit(
SimStatusDialogVisibility(
imsRegisteredShowUp = config.getBoolean(
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL
),
)
)
}
} }

View File

@@ -17,9 +17,12 @@
package com.android.settings.deviceinfo.simstatus package com.android.settings.deviceinfo.simstatus
import android.content.Context import android.content.Context
import android.os.PersistableBundle
import android.telephony.CarrierConfigManager
import androidx.lifecycle.testing.TestLifecycleOwner import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.deviceinfo.simstatus.SimStatusDialogRepository.SimStatusDialogInfo
import com.android.settings.network.telephony.SimSlotRepository import com.android.settings.network.telephony.SimSlotRepository
import com.android.settings.network.telephony.ims.ImsMmTelRepository import com.android.settings.network.telephony.ims.ImsMmTelRepository
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -30,11 +33,27 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
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
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class ImsRegistrationStateControllerTest { class SimStatusDialogRepositoryTest {
private val context: Context = ApplicationProvider.getApplicationContext() private val carrierConfig = PersistableBundle().apply {
putBoolean(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true)
}
private val mockCarrierConfigManager = mock<CarrierConfigManager> {
on {
getConfigForSubId(
SUB_ID,
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL,
)
} doReturn carrierConfig
}
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(CarrierConfigManager::class.java) } doReturn mockCarrierConfigManager
}
private val mockSimSlotRepository = mock<SimSlotRepository> { private val mockSimSlotRepository = mock<SimSlotRepository> {
on { subIdInSimSlotFlow(SIM_SLOT_INDEX) } doReturn flowOf(SUB_ID) on { subIdInSimSlotFlow(SIM_SLOT_INDEX) } doReturn flowOf(SUB_ID)
@@ -44,7 +63,7 @@ class ImsRegistrationStateControllerTest {
on { imsRegisteredFlow() } doReturn flowOf(true) on { imsRegisteredFlow() } doReturn flowOf(true)
} }
private val controller = ImsRegistrationStateController( private val controller = SimStatusDialogRepository(
context = context, context = context,
simSlotRepository = mockSimSlotRepository, simSlotRepository = mockSimSlotRepository,
imsMmTelRepositoryFactory = { subId -> imsMmTelRepositoryFactory = { subId ->
@@ -54,15 +73,28 @@ class ImsRegistrationStateControllerTest {
) )
@Test @Test
fun collectImsRegistered() = runBlocking { fun collectSimStatusDialogInfo() = runBlocking {
var imsRegistered = false var simStatusDialogInfo = SimStatusDialogInfo()
controller.collectImsRegistered(TestLifecycleOwner(), SIM_SLOT_INDEX) { controller.collectSimStatusDialogInfo(TestLifecycleOwner(), SIM_SLOT_INDEX) {
imsRegistered = it simStatusDialogInfo = it
} }
delay(100) delay(100)
assertThat(imsRegistered).isTrue() assertThat(simStatusDialogInfo).isEqualTo(SimStatusDialogInfo(imsRegistered = true))
}
@Test
fun collectSimStatusDialogInfo_doNotShowImsRegistration() = runBlocking {
carrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false)
var simStatusDialogInfo = SimStatusDialogInfo()
controller.collectSimStatusDialogInfo(TestLifecycleOwner(), SIM_SLOT_INDEX) {
simStatusDialogInfo = it
}
delay(100)
assertThat(simStatusDialogInfo.imsRegistered).isNull()
} }
private companion object { private companion object {

View File

@@ -36,7 +36,6 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -394,8 +393,6 @@ public class SimStatusDialogControllerTest {
@Test @Test
@Ignore @Ignore
public void initialize_imsRegistered_shouldSetImsRegistrationStateSummaryToRegisterd() { public void initialize_imsRegistered_shouldSetImsRegistrationStateSummaryToRegisterd() {
mPersistableBundle.putBoolean(
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
when(mTelephonyManager.isImsRegistered(anyInt())).thenReturn(true); when(mTelephonyManager.isImsRegistered(anyInt())).thenReturn(true);
mController.initialize(); mController.initialize();
@@ -407,8 +404,6 @@ public class SimStatusDialogControllerTest {
@Test @Test
@Ignore @Ignore
public void initialize_imsNotRegistered_shouldSetImsRegistrationStateSummaryToNotRegisterd() { public void initialize_imsNotRegistered_shouldSetImsRegistrationStateSummaryToNotRegisterd() {
mPersistableBundle.putBoolean(
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
when(mTelephonyManager.isImsRegistered(anyInt())).thenReturn(false); when(mTelephonyManager.isImsRegistered(anyInt())).thenReturn(false);
mController.initialize(); mController.initialize();
@@ -418,24 +413,20 @@ public class SimStatusDialogControllerTest {
} }
@Test @Test
public void initialize_showImsRegistration_shouldNotRemoveImsRegistrationStateSetting() { @Ignore("b/337417520")
mPersistableBundle.putBoolean( public void initialize_showImsRegistration_shouldShowImsRegistrationStateSetting() {
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
mController.initialize(); mController.initialize();
verify(mDialog, never()).removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID); verify(mDialog).setSettingVisibility(IMS_REGISTRATION_STATE_VALUE_ID, true);
} }
@Test @Test
public void initialize_doNotShowImsRegistration_shouldRemoveImsRegistrationStateSetting() { @Ignore("b/337417520")
mPersistableBundle.putBoolean( public void initialize_doNotShowImsRegistration_shouldHideImsRegistrationStateSetting() {
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
mController.initialize(); mController.initialize();
verify(mDialog).removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID); verify(mDialog).setSettingVisibility(IMS_REGISTRATION_STATE_LABEL_ID, false);
verify(mDialog).removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID); verify(mDialog).setSettingVisibility(IMS_REGISTRATION_STATE_VALUE_ID, false);
} }
@Test @Test