Merge "Fix settings show data usage with the uid of a removed package"
This commit is contained in:
@@ -296,6 +296,16 @@ public class NetworkStatsFactory {
|
|||||||
return mTunAnd464xlatAdjustedStats.clone();
|
return mTunAnd464xlatAdjustedStats.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove stats from {@code mPersistSnapshot} and {@code mTunAnd464xlatAdjustedStats} for the
|
||||||
|
* given uids.
|
||||||
|
*/
|
||||||
|
public void removeUidsLocked(int[] uids) {
|
||||||
|
synchronized (mPersistentDataLock) {
|
||||||
|
mPersistSnapshot.removeUids(uids);
|
||||||
|
mTunAnd464xlatAdjustedStats.removeUids(uids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void assertEquals(NetworkStats expected, NetworkStats actual) {
|
public void assertEquals(NetworkStats expected, NetworkStats actual) {
|
||||||
if (expected.size() != actual.size()) {
|
if (expected.size() != actual.size()) {
|
||||||
|
|||||||
@@ -2469,13 +2469,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
mUidRecorder.removeUidsLocked(uids);
|
mUidRecorder.removeUidsLocked(uids);
|
||||||
mUidTagRecorder.removeUidsLocked(uids);
|
mUidTagRecorder.removeUidsLocked(uids);
|
||||||
|
|
||||||
|
mStatsFactory.removeUidsLocked(uids);
|
||||||
// Clear kernel stats associated with UID
|
// Clear kernel stats associated with UID
|
||||||
for (int uid : uids) {
|
for (int uid : uids) {
|
||||||
deleteKernelTagData(uid);
|
deleteKernelTagData(uid);
|
||||||
}
|
}
|
||||||
|
// TODO: Remove the UID's entries from mOpenSessionCallsPerUid and
|
||||||
// TODO: Remove the UID's entries from mOpenSessionCallsPerUid and
|
// mOpenSessionCallsPerCaller
|
||||||
// mOpenSessionCallsPerCaller
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static android.net.NetworkStats.ROAMING_NO;
|
|||||||
import static android.net.NetworkStats.SET_ALL;
|
import static android.net.NetworkStats.SET_ALL;
|
||||||
import static android.net.NetworkStats.SET_DEFAULT;
|
import static android.net.NetworkStats.SET_DEFAULT;
|
||||||
import static android.net.NetworkStats.SET_FOREGROUND;
|
import static android.net.NetworkStats.SET_FOREGROUND;
|
||||||
|
import static android.net.NetworkStats.TAG_ALL;
|
||||||
import static android.net.NetworkStats.TAG_NONE;
|
import static android.net.NetworkStats.TAG_NONE;
|
||||||
import static android.net.NetworkStats.UID_ALL;
|
import static android.net.NetworkStats.UID_ALL;
|
||||||
|
|
||||||
@@ -89,6 +90,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
|
|||||||
// related to networkStatsFactory is compiled to a minimal native library and loaded here.
|
// related to networkStatsFactory is compiled to a minimal native library and loaded here.
|
||||||
System.loadLibrary("networkstatsfactorytestjni");
|
System.loadLibrary("networkstatsfactorytestjni");
|
||||||
doReturn(mBpfNetMaps).when(mDeps).createBpfNetMaps(any());
|
doReturn(mBpfNetMaps).when(mDeps).createBpfNetMaps(any());
|
||||||
|
|
||||||
mFactory = new NetworkStatsFactory(mContext, mDeps);
|
mFactory = new NetworkStatsFactory(mContext, mDeps);
|
||||||
mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
|
mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
|
||||||
}
|
}
|
||||||
@@ -462,6 +464,46 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
|
|||||||
assertNoStatsEntry(stats, "wlan0", 1029, SET_DEFAULT, 0x0);
|
assertNoStatsEntry(stats, "wlan0", 1029, SET_DEFAULT, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveUidsStats() throws Exception {
|
||||||
|
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1)
|
||||||
|
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
|
||||||
|
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
|
||||||
|
256L, 16L, 512L, 32L, 0L)
|
||||||
|
.insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 64L, 3L, 1024L, 8L, 0L);
|
||||||
|
|
||||||
|
doReturn(stats).when(mDeps).getNetworkStatsDetail(anyInt(), any(),
|
||||||
|
anyInt());
|
||||||
|
|
||||||
|
final String[] ifaces = new String[]{TEST_IFACE};
|
||||||
|
final NetworkStats res = mFactory.readNetworkStatsDetail(UID_ALL, ifaces, TAG_ALL);
|
||||||
|
|
||||||
|
// Verify that the result of the mocked stats are expected.
|
||||||
|
assertValues(res, TEST_IFACE, UID_RED, 16L, 1L, 16L, 1L);
|
||||||
|
assertValues(res, TEST_IFACE, UID_BLUE, 256L, 16L, 512L, 32L);
|
||||||
|
assertValues(res, TEST_IFACE, UID_GREEN, 64L, 3L, 1024L, 8L);
|
||||||
|
|
||||||
|
// Assume the apps were removed.
|
||||||
|
final int[] removedUids = new int[]{UID_RED, UID_BLUE};
|
||||||
|
mFactory.removeUidsLocked(removedUids);
|
||||||
|
|
||||||
|
// Return empty stats for reading the result of removing uids stats later.
|
||||||
|
doReturn(buildEmptyStats()).when(mDeps).getNetworkStatsDetail(anyInt(), any(),
|
||||||
|
anyInt());
|
||||||
|
|
||||||
|
final NetworkStats removedUidsStats =
|
||||||
|
mFactory.readNetworkStatsDetail(UID_ALL, ifaces, TAG_ALL);
|
||||||
|
|
||||||
|
// Verify that the stats of the removed uids were removed.
|
||||||
|
assertValues(removedUidsStats, TEST_IFACE, UID_RED, 0L, 0L, 0L, 0L);
|
||||||
|
assertValues(removedUidsStats, TEST_IFACE, UID_BLUE, 0L, 0L, 0L, 0L);
|
||||||
|
assertValues(removedUidsStats, TEST_IFACE, UID_GREEN, 64L, 3L, 1024L, 8L);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkStats buildEmptyStats() {
|
||||||
|
return new NetworkStats(SystemClock.elapsedRealtime(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkStats parseNetworkStatsFromGoldenSample(int resourceId, int initialSize,
|
private NetworkStats parseNetworkStatsFromGoldenSample(int resourceId, int initialSize,
|
||||||
boolean consumeHeader, boolean checkActive, boolean isUidData) throws IOException {
|
boolean consumeHeader, boolean checkActive, boolean isUidData) throws IOException {
|
||||||
final NetworkStats stats =
|
final NetworkStats stats =
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -176,6 +177,7 @@ import java.time.ZoneOffset;
|
|||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -2071,6 +2073,59 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStatsFactoryRemoveUids() throws Exception {
|
||||||
|
// pretend that network comes online
|
||||||
|
mockDefaultSettings();
|
||||||
|
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
|
||||||
|
mockNetworkStatsSummary(buildEmptyStats());
|
||||||
|
mockNetworkStatsUidDetail(buildEmptyStats());
|
||||||
|
|
||||||
|
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
|
||||||
|
new UnderlyingNetworkInfo[0]);
|
||||||
|
|
||||||
|
// Create some traffic
|
||||||
|
incrementCurrentTime(HOUR_IN_MILLIS);
|
||||||
|
mockDefaultSettings();
|
||||||
|
final NetworkStats stats = new NetworkStats(getElapsedRealtime(), 1)
|
||||||
|
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
|
||||||
|
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
|
||||||
|
4096L, 258L, 512L, 32L, 0L)
|
||||||
|
.insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 64L, 3L, 1024L, 8L, 0L);
|
||||||
|
mockNetworkStatsUidDetail(stats);
|
||||||
|
|
||||||
|
forcePollAndWaitForIdle();
|
||||||
|
|
||||||
|
// Verify service recorded history
|
||||||
|
assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 0);
|
||||||
|
assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
|
||||||
|
assertUidTotal(sTemplateWifi, UID_GREEN, 64L, 3L, 1024L, 8L, 0);
|
||||||
|
|
||||||
|
// Simulate that the apps are removed.
|
||||||
|
final Intent intentBlue = new Intent(ACTION_UID_REMOVED);
|
||||||
|
intentBlue.putExtra(EXTRA_UID, UID_BLUE);
|
||||||
|
mServiceContext.sendBroadcast(intentBlue);
|
||||||
|
|
||||||
|
final Intent intentRed = new Intent(ACTION_UID_REMOVED);
|
||||||
|
intentRed.putExtra(EXTRA_UID, UID_RED);
|
||||||
|
mServiceContext.sendBroadcast(intentRed);
|
||||||
|
|
||||||
|
final int[] removedUids = {UID_BLUE, UID_RED};
|
||||||
|
|
||||||
|
final ArgumentCaptor<int[]> removedUidsCaptor = ArgumentCaptor.forClass(int[].class);
|
||||||
|
verify(mStatsFactory, times(2)).removeUidsLocked(removedUidsCaptor.capture());
|
||||||
|
final List<int[]> captureRemovedUids = removedUidsCaptor.getAllValues();
|
||||||
|
// Simulate that the stats are removed in NetworkStatsFactory.
|
||||||
|
if (captureRemovedUids.contains(removedUids)) {
|
||||||
|
stats.removeUids(removedUids);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the stats of the removed uid is removed.
|
||||||
|
assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
|
||||||
|
assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
|
||||||
|
assertUidTotal(sTemplateWifi, UID_GREEN, 64L, 3L, 1024L, 8L, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertShouldRunComparison(boolean expected, boolean isDebuggable) {
|
private void assertShouldRunComparison(boolean expected, boolean isDebuggable) {
|
||||||
assertEquals("shouldRunComparison (debuggable=" + isDebuggable + "): ",
|
assertEquals("shouldRunComparison (debuggable=" + isDebuggable + "): ",
|
||||||
expected, mService.shouldRunComparison());
|
expected, mService.shouldRunComparison());
|
||||||
|
|||||||
Reference in New Issue
Block a user