Merge "[Sb refactor] Check groupUuid in subscription filtering" into tm-qpr-dev
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.pipeline.mobile.data.model
|
package com.android.systemui.statusbar.pipeline.mobile.data.model
|
||||||
|
|
||||||
|
import android.os.ParcelUuid
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SystemUI representation of [SubscriptionInfo]. Currently we only use two fields on the
|
* SystemUI representation of [SubscriptionInfo]. Currently we only use two fields on the
|
||||||
* subscriptions themselves: subscriptionId and isOpportunistic. Any new fields that we need can be
|
* subscriptions themselves: subscriptionId and isOpportunistic. Any new fields that we need can be
|
||||||
@@ -29,4 +31,7 @@ data class SubscriptionModel(
|
|||||||
* filtering in certain cases. See [MobileIconsInteractor] for the filtering logic
|
* filtering in certain cases. See [MobileIconsInteractor] for the filtering logic
|
||||||
*/
|
*/
|
||||||
val isOpportunistic: Boolean = false,
|
val isOpportunistic: Boolean = false,
|
||||||
|
|
||||||
|
/** Subscriptions in the same group may be filtered or treated as a single subscription */
|
||||||
|
val groupUuid: ParcelUuid? = null,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -376,6 +376,7 @@ constructor(
|
|||||||
SubscriptionModel(
|
SubscriptionModel(
|
||||||
subscriptionId = subscriptionId,
|
subscriptionId = subscriptionId,
|
||||||
isOpportunistic = isOpportunistic,
|
isOpportunistic = isOpportunistic,
|
||||||
|
groupUuid = groupUuid,
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -150,6 +150,12 @@ constructor(
|
|||||||
|
|
||||||
val info1 = unfilteredSubs[0]
|
val info1 = unfilteredSubs[0]
|
||||||
val info2 = unfilteredSubs[1]
|
val info2 = unfilteredSubs[1]
|
||||||
|
|
||||||
|
// Filtering only applies to subscriptions in the same group
|
||||||
|
if (info1.groupUuid == null || info1.groupUuid != info2.groupUuid) {
|
||||||
|
return@combine unfilteredSubs
|
||||||
|
}
|
||||||
|
|
||||||
// If both subscriptions are primary, show both
|
// If both subscriptions are primary, show both
|
||||||
if (!info1.isOpportunistic && !info2.isOpportunistic) {
|
if (!info1.isOpportunistic && !info2.isOpportunistic) {
|
||||||
return@combine unfilteredSubs
|
return@combine unfilteredSubs
|
||||||
@@ -186,7 +192,7 @@ constructor(
|
|||||||
* validated bit from the old active network (A) while data is changing to the new one (B).
|
* validated bit from the old active network (A) while data is changing to the new one (B).
|
||||||
*
|
*
|
||||||
* This condition only applies if
|
* This condition only applies if
|
||||||
* 1. A and B are in the same subscription group (e.c. for CBRS data switching) and
|
* 1. A and B are in the same subscription group (e.g. for CBRS data switching) and
|
||||||
* 2. A was validated before the switch
|
* 2. A was validated before the switch
|
||||||
*
|
*
|
||||||
* The goal of this is to minimize the flickering in the UI of the cellular indicator
|
* The goal of this is to minimize the flickering in the UI of the cellular indicator
|
||||||
|
|||||||
@@ -896,21 +896,31 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
|
|||||||
|
|
||||||
// Subscription 1
|
// Subscription 1
|
||||||
private const val SUB_1_ID = 1
|
private const val SUB_1_ID = 1
|
||||||
|
private val GROUP_1 = ParcelUuid(UUID.randomUUID())
|
||||||
private val SUB_1 =
|
private val SUB_1 =
|
||||||
mock<SubscriptionInfo>().also {
|
mock<SubscriptionInfo>().also {
|
||||||
whenever(it.subscriptionId).thenReturn(SUB_1_ID)
|
whenever(it.subscriptionId).thenReturn(SUB_1_ID)
|
||||||
whenever(it.groupUuid).thenReturn(ParcelUuid(UUID.randomUUID()))
|
whenever(it.groupUuid).thenReturn(GROUP_1)
|
||||||
}
|
}
|
||||||
private val MODEL_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
|
private val MODEL_1 =
|
||||||
|
SubscriptionModel(
|
||||||
|
subscriptionId = SUB_1_ID,
|
||||||
|
groupUuid = GROUP_1,
|
||||||
|
)
|
||||||
|
|
||||||
// Subscription 2
|
// Subscription 2
|
||||||
private const val SUB_2_ID = 2
|
private const val SUB_2_ID = 2
|
||||||
|
private val GROUP_2 = ParcelUuid(UUID.randomUUID())
|
||||||
private val SUB_2 =
|
private val SUB_2 =
|
||||||
mock<SubscriptionInfo>().also {
|
mock<SubscriptionInfo>().also {
|
||||||
whenever(it.subscriptionId).thenReturn(SUB_2_ID)
|
whenever(it.subscriptionId).thenReturn(SUB_2_ID)
|
||||||
whenever(it.groupUuid).thenReturn(ParcelUuid(UUID.randomUUID()))
|
whenever(it.groupUuid).thenReturn(GROUP_2)
|
||||||
}
|
}
|
||||||
private val MODEL_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
|
private val MODEL_2 =
|
||||||
|
SubscriptionModel(
|
||||||
|
subscriptionId = SUB_2_ID,
|
||||||
|
groupUuid = GROUP_2,
|
||||||
|
)
|
||||||
|
|
||||||
// Subs 3 and 4 are considered to be in the same group ------------------------------------
|
// Subs 3 and 4 are considered to be in the same group ------------------------------------
|
||||||
private val GROUP_ID_3_4 = ParcelUuid(UUID.randomUUID())
|
private val GROUP_ID_3_4 = ParcelUuid(UUID.randomUUID())
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
||||||
|
|
||||||
|
import android.os.ParcelUuid
|
||||||
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.settingslib.mobile.MobileMappings
|
import com.android.settingslib.mobile.MobileMappings
|
||||||
@@ -34,6 +35,7 @@ import com.android.systemui.util.mockito.mock
|
|||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import java.util.UUID
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@@ -104,6 +106,21 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Based on the logic from the old pipeline, we'll never filter subs when there are more than 2
|
||||||
|
@Test
|
||||||
|
fun filteredSubscriptions_moreThanTwo_doesNotFilter() =
|
||||||
|
testScope.runTest {
|
||||||
|
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP, SUB_4_OPP))
|
||||||
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID)
|
||||||
|
|
||||||
|
var latest: List<SubscriptionModel>? = null
|
||||||
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(listOf(SUB_1, SUB_3_OPP, SUB_4_OPP))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_nonOpportunistic_updatesWithMultipleSubs() =
|
fun filteredSubscriptions_nonOpportunistic_updatesWithMultipleSubs() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
@@ -118,10 +135,50 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_3() =
|
fun filteredSubscriptions_opportunistic_differentGroups_doesNotFilter() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
||||||
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
|
|
||||||
|
var latest: List<SubscriptionModel>? = null
|
||||||
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(listOf(SUB_3_OPP, SUB_4_OPP))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun filteredSubscriptions_opportunistic_nonGrouped_doesNotFilter() =
|
||||||
|
testScope.runTest {
|
||||||
|
val (sub1, sub2) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_1_ID, SUB_2_ID),
|
||||||
|
opportunistic = Pair(true, true),
|
||||||
|
grouped = false,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub1, sub2))
|
||||||
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
|
||||||
|
|
||||||
|
var latest: List<SubscriptionModel>? = null
|
||||||
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(listOf(sub1, sub2))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun filteredSubscriptions_opportunistic_grouped_configFalse_showsActive_3() =
|
||||||
|
testScope.runTest {
|
||||||
|
val (sub3, sub4) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_3_ID, SUB_4_ID),
|
||||||
|
opportunistic = Pair(true, true),
|
||||||
|
grouped = true,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub3, sub4))
|
||||||
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
|
|
||||||
@@ -129,15 +186,21 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
// Filtered subscriptions should show the active one when the config is false
|
// Filtered subscriptions should show the active one when the config is false
|
||||||
assertThat(latest).isEqualTo(listOf(SUB_3_OPP))
|
assertThat(latest).isEqualTo(listOf(sub3))
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_4() =
|
fun filteredSubscriptions_opportunistic_grouped_configFalse_showsActive_4() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
val (sub3, sub4) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_3_ID, SUB_4_ID),
|
||||||
|
opportunistic = Pair(true, true),
|
||||||
|
grouped = true,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub3, sub4))
|
||||||
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
@@ -146,15 +209,21 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
// Filtered subscriptions should show the active one when the config is false
|
// Filtered subscriptions should show the active one when the config is false
|
||||||
assertThat(latest).isEqualTo(listOf(SUB_4_OPP))
|
assertThat(latest).isEqualTo(listOf(sub4))
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_active_1() =
|
fun filteredSubscriptions_oneOpportunistic_grouped_configTrue_showsPrimary_active_1() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
|
val (sub1, sub3) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_1_ID, SUB_3_ID),
|
||||||
|
opportunistic = Pair(false, true),
|
||||||
|
grouped = true,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub1, sub3))
|
||||||
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
@@ -164,15 +233,21 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
|
|
||||||
// Filtered subscriptions should show the primary (non-opportunistic) if the config is
|
// Filtered subscriptions should show the primary (non-opportunistic) if the config is
|
||||||
// true
|
// true
|
||||||
assertThat(latest).isEqualTo(listOf(SUB_1))
|
assertThat(latest).isEqualTo(listOf(sub1))
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_nonActive_1() =
|
fun filteredSubscriptions_oneOpportunistic_grouped_configTrue_showsPrimary_nonActive_1() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
|
val (sub1, sub3) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_1_ID, SUB_3_ID),
|
||||||
|
opportunistic = Pair(false, true),
|
||||||
|
grouped = true,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub1, sub3))
|
||||||
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
@@ -182,7 +257,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
|
|
||||||
// Filtered subscriptions should show the primary (non-opportunistic) if the config is
|
// Filtered subscriptions should show the primary (non-opportunistic) if the config is
|
||||||
// true
|
// true
|
||||||
assertThat(latest).isEqualTo(listOf(SUB_1))
|
assertThat(latest).isEqualTo(listOf(sub1))
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
@@ -642,6 +717,33 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method for creating a pair of subscriptions to test the filteredSubscriptions
|
||||||
|
* flow.
|
||||||
|
*/
|
||||||
|
private fun createSubscriptionPair(
|
||||||
|
subscriptionIds: Pair<Int, Int>,
|
||||||
|
opportunistic: Pair<Boolean, Boolean> = Pair(false, false),
|
||||||
|
grouped: Boolean = false,
|
||||||
|
): Pair<SubscriptionModel, SubscriptionModel> {
|
||||||
|
val groupUuid = if (grouped) ParcelUuid(UUID.randomUUID()) else null
|
||||||
|
val sub1 =
|
||||||
|
SubscriptionModel(
|
||||||
|
subscriptionId = subscriptionIds.first,
|
||||||
|
isOpportunistic = opportunistic.first,
|
||||||
|
groupUuid = groupUuid,
|
||||||
|
)
|
||||||
|
|
||||||
|
val sub2 =
|
||||||
|
SubscriptionModel(
|
||||||
|
subscriptionId = subscriptionIds.second,
|
||||||
|
isOpportunistic = opportunistic.second,
|
||||||
|
groupUuid = groupUuid,
|
||||||
|
)
|
||||||
|
|
||||||
|
return Pair(sub1, sub2)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val tableLogBuffer =
|
private val tableLogBuffer =
|
||||||
TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock())
|
TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock())
|
||||||
@@ -655,11 +757,21 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, tableLogBuffer)
|
private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, tableLogBuffer)
|
||||||
|
|
||||||
private const val SUB_3_ID = 3
|
private const val SUB_3_ID = 3
|
||||||
private val SUB_3_OPP = SubscriptionModel(subscriptionId = SUB_3_ID, isOpportunistic = true)
|
private val SUB_3_OPP =
|
||||||
|
SubscriptionModel(
|
||||||
|
subscriptionId = SUB_3_ID,
|
||||||
|
isOpportunistic = true,
|
||||||
|
groupUuid = ParcelUuid(UUID.randomUUID()),
|
||||||
|
)
|
||||||
private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, tableLogBuffer)
|
private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, tableLogBuffer)
|
||||||
|
|
||||||
private const val SUB_4_ID = 4
|
private const val SUB_4_ID = 4
|
||||||
private val SUB_4_OPP = SubscriptionModel(subscriptionId = SUB_4_ID, isOpportunistic = true)
|
private val SUB_4_OPP =
|
||||||
|
SubscriptionModel(
|
||||||
|
subscriptionId = SUB_4_ID,
|
||||||
|
isOpportunistic = true,
|
||||||
|
groupUuid = ParcelUuid(UUID.randomUUID()),
|
||||||
|
)
|
||||||
private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, tableLogBuffer)
|
private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, tableLogBuffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user