Fix the sorting order for restricted

Set the category for the restricted item to fix.

Fix: 357275199
Flag: EXEMPT bug fix
Test: manual - on DataUsageList
Test: atest AppDataUsageRepositoryTest
Change-Id: I63d3fd2ac85748d67ff6194cd60adeadae2aa984
This commit is contained in:
Chaohui Wang
2024-08-06 16:32:39 +08:00
parent 377939483c
commit e2f0a6b2d3
2 changed files with 105 additions and 66 deletions

View File

@@ -28,6 +28,7 @@ import android.util.SparseArray
import android.util.SparseBooleanArray import android.util.SparseBooleanArray
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.core.util.keyIterator import androidx.core.util.keyIterator
import androidx.core.util.valueIterator
import com.android.settings.R import com.android.settings.R
import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.Bucket import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.Bucket
import com.android.settingslib.AppItem import com.android.settingslib.AppItem
@@ -49,33 +50,30 @@ class AppDataUsageRepository(
@VisibleForTesting @VisibleForTesting
fun getAppPercent(carrierId: Int?, buckets: List<Bucket>): List<Pair<AppItem, Int>> { fun getAppPercent(carrierId: Int?, buckets: List<Bucket>): List<Pair<AppItem, Int>> {
val items = ArrayList<AppItem>()
val knownItems = SparseArray<AppItem>() val knownItems = SparseArray<AppItem>()
val profiles = context.userManager.userProfiles val profiles = context.userManager.userProfiles
val userManager : UserManager = context.getSystemService(Context.USER_SERVICE) as UserManager val userManager : UserManager = context.getSystemService(Context.USER_SERVICE) as UserManager
val userIdToIsHiddenMap = profiles.associate { profile -> val userIdToIsHiddenMap = profiles.associate { profile ->
profile.identifier to shouldSkipProfile(userManager, profile) profile.identifier to shouldSkipProfile(userManager, profile)
} }
bindStats(buckets, userIdToIsHiddenMap, knownItems, items) bindStats(buckets, userIdToIsHiddenMap, knownItems)
val restrictedUids = context.getSystemService(NetworkPolicyManager::class.java)!! val restrictedUids = context.getSystemService(NetworkPolicyManager::class.java)!!
.getUidsWithPolicy(NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND) .getUidsWithPolicy(NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND)
for (uid in restrictedUids) { for (uid in restrictedUids) {
// Only splice in restricted state for current user or managed users // Only splice in restricted state for current user or managed users
if (!profiles.contains(UserHandle.getUserHandleForUid(uid))) { if (UserHandle.getUserHandleForUid(uid) !in profiles) continue
continue val item =
} knownItems[uid]
var item = knownItems[uid] ?: AppItem(uid).apply {
if (item == null) { category = AppItem.CATEGORY_APP
item = AppItem(uid) addUid(uid)
item.total = 0 knownItems.put(uid, this)
item.addUid(uid) }
items.add(item)
knownItems.put(item.key, item)
}
item.restricted = true item.restricted = true
} }
val filteredItems = filterItems(carrierId, items).sorted() val filteredItems =
filterItems(carrierId, knownItems.valueIterator().asSequence().toList()).sorted()
val largest: Long = filteredItems.maxOfOrNull { it.total } ?: 0 val largest: Long = filteredItems.maxOfOrNull { it.total } ?: 0
return filteredItems.map { item -> return filteredItems.map { item ->
val percentTotal = if (largest > 0) (item.total * 100 / largest).toInt() else 0 val percentTotal = if (largest > 0) (item.total * 100 / largest).toInt() else 0
@@ -106,7 +104,6 @@ class AppDataUsageRepository(
buckets: List<Bucket>, buckets: List<Bucket>,
userIdToIsHiddenMap: Map<Int, Boolean>, userIdToIsHiddenMap: Map<Int, Boolean>,
knownItems: SparseArray<AppItem>, knownItems: SparseArray<AppItem>,
items: ArrayList<AppItem>,
) { ) {
for (bucket in buckets) { for (bucket in buckets) {
// Decide how to collapse items together // Decide how to collapse items together
@@ -126,7 +123,6 @@ class AppDataUsageRepository(
knownItems = knownItems, knownItems = knownItems,
bucket = bucket, bucket = bucket,
itemCategory = AppItem.CATEGORY_USER, itemCategory = AppItem.CATEGORY_USER,
items = items,
) )
} }
collapseKey = getAppUid(uid) collapseKey = getAppUid(uid)
@@ -157,7 +153,6 @@ class AppDataUsageRepository(
knownItems = knownItems, knownItems = knownItems,
bucket = bucket, bucket = bucket,
itemCategory = category, itemCategory = category,
items = items,
) )
} }
} }
@@ -187,15 +182,13 @@ class AppDataUsageRepository(
knownItems: SparseArray<AppItem>, knownItems: SparseArray<AppItem>,
bucket: Bucket, bucket: Bucket,
itemCategory: Int, itemCategory: Int,
items: ArrayList<AppItem>,
) { ) {
var item = knownItems[collapseKey] val item =
if (item == null) { knownItems[collapseKey]
item = AppItem(collapseKey) ?: AppItem(collapseKey).apply {
item.category = itemCategory category = itemCategory
items.add(item) knownItems.put(collapseKey, this)
knownItems.put(item.key, item) }
}
item.addUid(bucket.uid) item.addUid(bucket.uid)
item.total += bucket.bytes item.total += bucket.bytes
} }

View File

@@ -38,48 +38,55 @@ import org.mockito.junit.MockitoRule
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
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class AppDataUsageRepositoryTest { class AppDataUsageRepositoryTest {
@get:Rule @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
val mockito: MockitoRule = MockitoJUnit.rule()
private val mockUserManager = mock<UserManager> { private val mockUserManager =
on { userProfiles } doReturn listOf(UserHandle.of(USER_ID)) mock<UserManager> {
on { getUserInfo(USER_ID) } doReturn UserInfo(USER_ID, "", 0) on { userProfiles } doReturn listOf(UserHandle.of(USER_ID))
} on { getUserInfo(USER_ID) } doReturn UserInfo(USER_ID, "", 0)
}
private val mockNetworkPolicyManager = mock<NetworkPolicyManager> { private val mockNetworkPolicyManager =
on { getUidsWithPolicy(NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND) } doReturn mock<NetworkPolicyManager> {
intArrayOf() on { getUidsWithPolicy(NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND) } doReturn
} intArrayOf()
}
private val mockResources = mock<Resources> { private val mockResources =
on { getIntArray(R.array.datausage_hiding_carrier_service_carrier_id) } doReturn mock<Resources> {
intArrayOf(HIDING_CARRIER_ID) on { getIntArray(R.array.datausage_hiding_carrier_service_carrier_id) } doReturn
intArrayOf(HIDING_CARRIER_ID)
on { getStringArray(R.array.datausage_hiding_carrier_service_package_names) } doReturn on { getStringArray(R.array.datausage_hiding_carrier_service_package_names) } doReturn
arrayOf(HIDING_PACKAGE_NAME) arrayOf(HIDING_PACKAGE_NAME)
} }
private val context: Context = spy(ApplicationProvider.getApplicationContext()) { private val context: Context =
on { userManager } doReturn mockUserManager spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(NetworkPolicyManager::class.java) } doReturn mockNetworkPolicyManager on { userManager } doReturn mockUserManager
on { resources } doReturn mockResources on { getSystemService(NetworkPolicyManager::class.java) } doReturn
} mockNetworkPolicyManager
on { resources } doReturn mockResources
}
@Test @Test
fun getAppPercent_noAppToHide() { fun getAppPercent_noAppToHide() {
val repository = AppDataUsageRepository( val repository =
context = context, AppDataUsageRepository(
currentUserId = USER_ID, context = context,
template = Template, currentUserId = USER_ID,
getPackageName = { null }, template = Template,
) getPackageName = { null },
val buckets = listOf( )
Bucket(uid = APP_ID_1, bytes = 1, startTimeStamp = 0, endTimeStamp = 0), val buckets =
Bucket(uid = APP_ID_2, bytes = 2, startTimeStamp = 0, endTimeStamp = 0), listOf(
) Bucket(uid = APP_ID_1, bytes = 1, startTimeStamp = 0, endTimeStamp = 0),
Bucket(uid = APP_ID_2, bytes = 2, startTimeStamp = 0, endTimeStamp = 0),
)
val appPercentList = repository.getAppPercent(null, buckets) val appPercentList = repository.getAppPercent(null, buckets)
@@ -100,16 +107,18 @@ class AppDataUsageRepositoryTest {
@Test @Test
fun getAppPercent_hasAppToHide() { fun getAppPercent_hasAppToHide() {
val repository = AppDataUsageRepository( val repository =
context = context, AppDataUsageRepository(
currentUserId = USER_ID, context = context,
template = Template, currentUserId = USER_ID,
getPackageName = { if (it.key == APP_ID_1) HIDING_PACKAGE_NAME else null }, template = Template,
) getPackageName = { if (it.key == APP_ID_1) HIDING_PACKAGE_NAME else null },
val buckets = listOf( )
Bucket(uid = APP_ID_1, bytes = 1, startTimeStamp = 0, endTimeStamp = 0), val buckets =
Bucket(uid = APP_ID_2, bytes = 2, startTimeStamp = 0, endTimeStamp = 0), listOf(
) Bucket(uid = APP_ID_1, bytes = 1, startTimeStamp = 0, endTimeStamp = 0),
Bucket(uid = APP_ID_2, bytes = 2, startTimeStamp = 0, endTimeStamp = 0),
)
val appPercentList = repository.getAppPercent(HIDING_CARRIER_ID, buckets) val appPercentList = repository.getAppPercent(HIDING_CARRIER_ID, buckets)
@@ -122,6 +131,43 @@ class AppDataUsageRepositoryTest {
assertThat(appPercentList[0].second).isEqualTo(100) assertThat(appPercentList[0].second).isEqualTo(100)
} }
@Test
fun getAppPercent_restricted() {
mockNetworkPolicyManager.stub {
on { getUidsWithPolicy(NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND) } doReturn
intArrayOf(APP_ID_1)
}
val repository =
AppDataUsageRepository(
context = context,
currentUserId = USER_ID,
template = Template,
getPackageName = { null },
)
val buckets =
listOf(
Bucket(uid = APP_ID_2, bytes = 2, startTimeStamp = 0, endTimeStamp = 0),
)
val appPercentList = repository.getAppPercent(null, buckets)
assertThat(appPercentList).hasSize(2)
appPercentList[0].first.apply {
assertThat(key).isEqualTo(APP_ID_2)
assertThat(category).isEqualTo(AppItem.CATEGORY_APP)
assertThat(total).isEqualTo(2)
assertThat(restricted).isFalse()
}
assertThat(appPercentList[0].second).isEqualTo(100)
appPercentList[1].first.apply {
assertThat(key).isEqualTo(APP_ID_1)
assertThat(category).isEqualTo(AppItem.CATEGORY_APP)
assertThat(total).isEqualTo(0)
assertThat(restricted).isTrue()
}
assertThat(appPercentList[1].second).isEqualTo(0)
}
private companion object { private companion object {
const val USER_ID = 1 const val USER_ID = 1
const val APP_ID_1 = 110001 const val APP_ID_1 = 110001