android_packages_modules_Co.../tests/unit/java/android/net/TrafficStatsTest.kt
Junyu Lai e51bae6bdc Fix system caller cannot query stats for other uids
Follow-up from aosp/3249945. If the system caller queries stats
for other UIDs, the caller would get UNSUPPORTED.
This follows the official documentation, where the API would
not return stats for all other UIDs.

However, partners or other legacy callers might already depend
on this undocumented behavior. Changing this behavior might
damage existing apps.

Thus, this change reverts the behavior change introduced at
aosp/3249945 and allows a system caller to query stats for
other UIDs.

Test: atest ConnectivityCoverageTests:android.net.connectivity.android.net.TrafficStatsTest
Bug: 372851500
Change-Id: Ia7ea051f7b0b6349ffcb890c300362bbfbdee3dc
2024-10-30 23:02:55 +08:00

92 lines
3.6 KiB
Kotlin

/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net
import android.net.NetworkStats.UID_ALL
import android.net.TrafficStats.UNSUPPORTED
import android.net.netstats.StatsResult
import android.os.Build
import android.os.Process.SYSTEM_UID
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
class TrafficStatsTest {
private val binder = mock(INetworkStatsService::class.java)
private val myUid = android.os.Process.myUid()
private val notMyUid = myUid + 1
private val mockSystemUidStatsResult = StatsResult(1L, 2L, 3L, 4L)
private val mockMyUidStatsResult = StatsResult(5L, 6L, 7L, 8L)
private val mockNotMyUidStatsResult = StatsResult(9L, 10L, 11L, 12L)
private val unsupportedStatsResult =
StatsResult(UNSUPPORTED.toLong(), UNSUPPORTED.toLong(),
UNSUPPORTED.toLong(), UNSUPPORTED.toLong())
@Before
fun setUp() {
TrafficStats.setServiceForTest(binder)
doReturn(mockSystemUidStatsResult).`when`(binder).getUidStats(SYSTEM_UID)
doReturn(mockMyUidStatsResult).`when`(binder).getUidStats(myUid)
doReturn(mockNotMyUidStatsResult).`when`(binder).getUidStats(notMyUid)
}
@After
fun tearDown() {
TrafficStats.setServiceForTest(null)
TrafficStats.setMyUidForTest(UID_ALL)
}
private fun assertUidStats(uid: Int, stats: StatsResult) {
assertEquals(stats.rxBytes, TrafficStats.getUidRxBytes(uid))
assertEquals(stats.rxPackets, TrafficStats.getUidRxPackets(uid))
assertEquals(stats.txBytes, TrafficStats.getUidTxBytes(uid))
assertEquals(stats.txPackets, TrafficStats.getUidTxPackets(uid))
}
// Verify a normal caller could get a quick UNSUPPORTED result in the TrafficStats
// without accessing the service if query stats other than itself.
@Test
fun testGetUidStats_appCaller() {
assertUidStats(SYSTEM_UID, unsupportedStatsResult)
assertUidStats(notMyUid, unsupportedStatsResult)
verify(binder, never()).getUidStats(anyInt())
assertUidStats(myUid, mockMyUidStatsResult)
}
// Verify that callers with SYSTEM_UID can access network
// stats for other UIDs. While this behavior is not officially documented
// in the API, it exists for compatibility with existing callers that may
// rely on it.
@Test
fun testGetUidStats_systemCaller() {
TrafficStats.setMyUidForTest(SYSTEM_UID)
assertUidStats(SYSTEM_UID, mockSystemUidStatsResult)
assertUidStats(myUid, mockMyUidStatsResult)
assertUidStats(notMyUid, mockNotMyUidStatsResult)
}
}