Merge "Finish moving NetworkStats tests to tests/net" am: e1a0562a3f am: cd821b231a
am: 544bcbe78e Change-Id: I5d9a01a5804a7cc6289253db09078ede00fc0dc5
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.server.net;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.Manifest;
|
||||
import android.Manifest.permission;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.admin.DeviceAdminInfo;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
public class NetworkStatsAccessTest extends TestCase {
|
||||
private static final String TEST_PKG = "com.example.test";
|
||||
private static final int TEST_UID = 12345;
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private DevicePolicyManagerInternal mDpmi;
|
||||
@Mock private TelephonyManager mTm;
|
||||
@Mock private AppOpsManager mAppOps;
|
||||
|
||||
// Hold the real service so we can restore it when tearing down the test.
|
||||
private DevicePolicyManagerInternal mSystemDpmi;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mSystemDpmi = LocalServices.getService(DevicePolicyManagerInternal.class);
|
||||
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
|
||||
LocalServices.addService(DevicePolicyManagerInternal.class, mDpmi);
|
||||
|
||||
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTm);
|
||||
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
|
||||
LocalServices.addService(DevicePolicyManagerInternal.class, mSystemDpmi);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_hasCarrierPrivileges() throws Exception {
|
||||
setHasCarrierPrivileges(true);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(false);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.DEVICE,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_isDeviceOwner() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(true);
|
||||
setIsProfileOwner(false);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.DEVICE,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_isProfileOwner() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(true);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.USER,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_hasAppOpsBitAllowed() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(true);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_ALLOWED, false);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.USER,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_hasAppOpsBitDefault_grantedPermission() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(true);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, true);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.USER,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_hasReadHistoryPermission() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(true);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
|
||||
setHasReadHistoryPermission(true);
|
||||
assertEquals(NetworkStatsAccess.Level.USER,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_deniedAppOpsBit() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(false);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_ERRORED, true);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.DEFAULT,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
public void testCheckAccessLevel_deniedAppOpsBit_deniedPermission() throws Exception {
|
||||
setHasCarrierPrivileges(false);
|
||||
setIsDeviceOwner(false);
|
||||
setIsProfileOwner(false);
|
||||
setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false);
|
||||
setHasReadHistoryPermission(false);
|
||||
assertEquals(NetworkStatsAccess.Level.DEFAULT,
|
||||
NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG));
|
||||
}
|
||||
|
||||
private void setHasCarrierPrivileges(boolean hasPrivileges) {
|
||||
when(mTm.checkCarrierPrivilegesForPackage(TEST_PKG)).thenReturn(
|
||||
hasPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
|
||||
: TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
|
||||
}
|
||||
|
||||
private void setIsDeviceOwner(boolean isOwner) {
|
||||
when(mDpmi.isActiveAdminWithPolicy(TEST_UID, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER))
|
||||
.thenReturn(isOwner);
|
||||
}
|
||||
|
||||
private void setIsProfileOwner(boolean isOwner) {
|
||||
when(mDpmi.isActiveAdminWithPolicy(TEST_UID, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))
|
||||
.thenReturn(isOwner);
|
||||
}
|
||||
|
||||
private void setHasAppOpsPermission(int appOpsMode, boolean hasPermission) {
|
||||
when(mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, TEST_UID, TEST_PKG))
|
||||
.thenReturn(appOpsMode);
|
||||
when(mContext.checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)).thenReturn(
|
||||
hasPermission ? PackageManager.PERMISSION_GRANTED
|
||||
: PackageManager.PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
private void setHasReadHistoryPermission(boolean hasPermission) {
|
||||
when(mContext.checkCallingOrSelfPermission(permission.READ_NETWORK_USAGE_HISTORY))
|
||||
.thenReturn(hasPermission ? PackageManager.PERMISSION_GRANTED
|
||||
: PackageManager.PERMISSION_DENIED);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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 com.android.server.net;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkStats.UID_ALL;
|
||||
import static android.net.NetworkTemplate.buildTemplateMobileAll;
|
||||
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.net.NetworkIdentity;
|
||||
import android.net.NetworkStats;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.MoreAsserts;
|
||||
|
||||
import com.android.frameworks.tests.net.R;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
import libcore.io.Streams;
|
||||
|
||||
/**
|
||||
* Tests for {@link NetworkStatsCollection}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class NetworkStatsCollectionTest extends AndroidTestCase {
|
||||
|
||||
private static final String TEST_FILE = "test.bin";
|
||||
private static final String TEST_IMSI = "310260000000000";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// ignore any device overlay while testing
|
||||
NetworkTemplate.forceAllNetworkTypes();
|
||||
}
|
||||
|
||||
public void testReadLegacyNetwork() throws Exception {
|
||||
final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
|
||||
stageFile(R.raw.netstats_v1, testFile);
|
||||
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
|
||||
collection.readLegacyNetwork(testFile);
|
||||
|
||||
// verify that history read correctly
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE);
|
||||
|
||||
// now export into a unified format
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
collection.write(new DataOutputStream(bos));
|
||||
|
||||
// clear structure completely
|
||||
collection.reset();
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
0L, 0L, 0L, 0L, NetworkStatsAccess.Level.DEVICE);
|
||||
|
||||
// and read back into structure, verifying that totals are same
|
||||
collection.read(new ByteArrayInputStream(bos.toByteArray()));
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE);
|
||||
}
|
||||
|
||||
public void testReadLegacyUid() throws Exception {
|
||||
final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
|
||||
stageFile(R.raw.netstats_uid_v4, testFile);
|
||||
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
|
||||
collection.readLegacyUid(testFile, false);
|
||||
|
||||
// verify that history read correctly
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE);
|
||||
|
||||
// now export into a unified format
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
collection.write(new DataOutputStream(bos));
|
||||
|
||||
// clear structure completely
|
||||
collection.reset();
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
0L, 0L, 0L, 0L, NetworkStatsAccess.Level.DEVICE);
|
||||
|
||||
// and read back into structure, verifying that totals are same
|
||||
collection.read(new ByteArrayInputStream(bos.toByteArray()));
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE);
|
||||
}
|
||||
|
||||
public void testReadLegacyUidTags() throws Exception {
|
||||
final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
|
||||
stageFile(R.raw.netstats_uid_v4, testFile);
|
||||
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
|
||||
collection.readLegacyUid(testFile, true);
|
||||
|
||||
// verify that history read correctly
|
||||
assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
77017831L, 100995L, 35436758L, 92344L);
|
||||
|
||||
// now export into a unified format
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
collection.write(new DataOutputStream(bos));
|
||||
|
||||
// clear structure completely
|
||||
collection.reset();
|
||||
assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
0L, 0L, 0L, 0L);
|
||||
|
||||
// and read back into structure, verifying that totals are same
|
||||
collection.read(new ByteArrayInputStream(bos.toByteArray()));
|
||||
assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
|
||||
77017831L, 100995L, 35436758L, 92344L);
|
||||
}
|
||||
|
||||
public void testStartEndAtomicBuckets() throws Exception {
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
|
||||
|
||||
// record empty data straddling between buckets
|
||||
final NetworkStats.Entry entry = new NetworkStats.Entry();
|
||||
entry.rxBytes = 32;
|
||||
collection.recordData(null, UID_ALL, SET_DEFAULT, TAG_NONE, 30 * MINUTE_IN_MILLIS,
|
||||
90 * MINUTE_IN_MILLIS, entry);
|
||||
|
||||
// assert that we report boundary in atomic buckets
|
||||
assertEquals(0, collection.getStartMillis());
|
||||
assertEquals(2 * HOUR_IN_MILLIS, collection.getEndMillis());
|
||||
}
|
||||
|
||||
public void testAccessLevels() throws Exception {
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
|
||||
final NetworkStats.Entry entry = new NetworkStats.Entry();
|
||||
final NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TEST_IMSI, null, false, true));
|
||||
|
||||
int myUid = Process.myUid();
|
||||
int otherUidInSameUser = Process.myUid() + 1;
|
||||
int uidInDifferentUser = Process.myUid() + UserHandle.PER_USER_RANGE;
|
||||
|
||||
// Record one entry for the current UID.
|
||||
entry.rxBytes = 32;
|
||||
collection.recordData(identSet, myUid, SET_DEFAULT, TAG_NONE, 0, 60 * MINUTE_IN_MILLIS,
|
||||
entry);
|
||||
|
||||
// Record one entry for another UID in this user.
|
||||
entry.rxBytes = 64;
|
||||
collection.recordData(identSet, otherUidInSameUser, SET_DEFAULT, TAG_NONE, 0,
|
||||
60 * MINUTE_IN_MILLIS, entry);
|
||||
|
||||
// Record one entry for the system UID.
|
||||
entry.rxBytes = 128;
|
||||
collection.recordData(identSet, Process.SYSTEM_UID, SET_DEFAULT, TAG_NONE, 0,
|
||||
60 * MINUTE_IN_MILLIS, entry);
|
||||
|
||||
// Record one entry for a UID in a different user.
|
||||
entry.rxBytes = 256;
|
||||
collection.recordData(identSet, uidInDifferentUser, SET_DEFAULT, TAG_NONE, 0,
|
||||
60 * MINUTE_IN_MILLIS, entry);
|
||||
|
||||
// Verify the set of relevant UIDs for each access level.
|
||||
MoreAsserts.assertEquals(new int[] { myUid },
|
||||
collection.getRelevantUids(NetworkStatsAccess.Level.DEFAULT));
|
||||
MoreAsserts.assertEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser },
|
||||
collection.getRelevantUids(NetworkStatsAccess.Level.USER));
|
||||
MoreAsserts.assertEquals(
|
||||
new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser, uidInDifferentUser },
|
||||
collection.getRelevantUids(NetworkStatsAccess.Level.DEVICE));
|
||||
|
||||
// Verify security check in getHistory.
|
||||
assertNotNull(collection.getHistory(buildTemplateMobileAll(TEST_IMSI), myUid, SET_DEFAULT,
|
||||
TAG_NONE, 0, NetworkStatsAccess.Level.DEFAULT));
|
||||
try {
|
||||
collection.getHistory(buildTemplateMobileAll(TEST_IMSI), otherUidInSameUser,
|
||||
SET_DEFAULT, TAG_NONE, 0, NetworkStatsAccess.Level.DEFAULT);
|
||||
fail("Should have thrown SecurityException for accessing different UID");
|
||||
} catch (SecurityException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// Verify appropriate aggregation in getSummary.
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32, 0, 0, 0,
|
||||
NetworkStatsAccess.Level.DEFAULT);
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32 + 64 + 128, 0, 0, 0,
|
||||
NetworkStatsAccess.Level.USER);
|
||||
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32 + 64 + 128 + 256, 0, 0,
|
||||
0, NetworkStatsAccess.Level.DEVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a {@link Resources#openRawResource(int)} into {@link File} for
|
||||
* testing purposes.
|
||||
*/
|
||||
private void stageFile(int rawId, File file) throws Exception {
|
||||
new File(file.getParent()).mkdirs();
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
in = getContext().getResources().openRawResource(rawId);
|
||||
out = new FileOutputStream(file);
|
||||
Streams.copy(in, out);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(in);
|
||||
IoUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertSummaryTotal(NetworkStatsCollection collection,
|
||||
NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets,
|
||||
@NetworkStatsAccess.Level int accessLevel) {
|
||||
final NetworkStats.Entry entry = collection.getSummary(
|
||||
template, Long.MIN_VALUE, Long.MAX_VALUE, accessLevel)
|
||||
.getTotal(null);
|
||||
assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
|
||||
}
|
||||
|
||||
private static void assertSummaryTotalIncludingTags(NetworkStatsCollection collection,
|
||||
NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
|
||||
final NetworkStats.Entry entry = collection.getSummary(
|
||||
template, Long.MIN_VALUE, Long.MAX_VALUE, NetworkStatsAccess.Level.DEVICE)
|
||||
.getTotalIncludingTags(null);
|
||||
assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
|
||||
}
|
||||
|
||||
private static void assertEntry(
|
||||
NetworkStats.Entry entry, long rxBytes, long rxPackets, long txBytes, long txPackets) {
|
||||
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
|
||||
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
|
||||
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
|
||||
assertEquals("unexpected txPackets", txPackets, entry.txPackets);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 com.android.server.net;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
import static android.net.NetworkStats.METERED_NO;
|
||||
import static android.net.NetworkStats.ROAMING_NO;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkTemplate.buildTemplateMobileAll;
|
||||
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
|
||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.net.DataUsageRequest;
|
||||
import android.net.NetworkIdentity;
|
||||
import android.net.NetworkStats;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import com.android.internal.net.VpnInfo;
|
||||
import com.android.server.net.NetworkStatsService;
|
||||
import com.android.server.net.NetworkStatsServiceTest.IdleableHandlerThread;
|
||||
import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* Tests for {@link NetworkStatsObservers}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class NetworkStatsObserversTest extends TestCase {
|
||||
private static final String TEST_IFACE = "test0";
|
||||
private static final String TEST_IFACE2 = "test1";
|
||||
private static final long TEST_START = 1194220800000L;
|
||||
|
||||
private static final String IMSI_1 = "310004";
|
||||
private static final String IMSI_2 = "310260";
|
||||
private static final String TEST_SSID = "AndroidAP";
|
||||
|
||||
private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard();
|
||||
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
|
||||
private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
|
||||
|
||||
private static final int UID_RED = UserHandle.PER_USER_RANGE + 1;
|
||||
private static final int UID_BLUE = UserHandle.PER_USER_RANGE + 2;
|
||||
private static final int UID_GREEN = UserHandle.PER_USER_RANGE + 3;
|
||||
private static final int UID_ANOTHER_USER = 2 * UserHandle.PER_USER_RANGE + 4;
|
||||
|
||||
private static final long WAIT_TIMEOUT = 500; // 1/2 sec
|
||||
private static final long THRESHOLD_BYTES = 2 * MB_IN_BYTES;
|
||||
private static final long BASE_BYTES = 7 * MB_IN_BYTES;
|
||||
private static final int INVALID_TYPE = -1;
|
||||
|
||||
private static final VpnInfo[] VPN_INFO = new VpnInfo[0];
|
||||
|
||||
private long mElapsedRealtime;
|
||||
|
||||
private IdleableHandlerThread mObserverHandlerThread;
|
||||
private Handler mObserverNoopHandler;
|
||||
|
||||
private LatchedHandler mHandler;
|
||||
private ConditionVariable mCv;
|
||||
|
||||
private NetworkStatsObservers mStatsObservers;
|
||||
private Messenger mMessenger;
|
||||
private ArrayMap<String, NetworkIdentitySet> mActiveIfaces;
|
||||
private ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces;
|
||||
|
||||
@Mock private IBinder mockBinder;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mObserverHandlerThread = new IdleableHandlerThread("HandlerThread");
|
||||
mObserverHandlerThread.start();
|
||||
final Looper observerLooper = mObserverHandlerThread.getLooper();
|
||||
mStatsObservers = new NetworkStatsObservers() {
|
||||
@Override
|
||||
protected Looper getHandlerLooperLocked() {
|
||||
return observerLooper;
|
||||
}
|
||||
};
|
||||
|
||||
mCv = new ConditionVariable();
|
||||
mHandler = new LatchedHandler(Looper.getMainLooper(), mCv);
|
||||
mMessenger = new Messenger(mHandler);
|
||||
|
||||
mActiveIfaces = new ArrayMap<>();
|
||||
mActiveUidIfaces = new ArrayMap<>();
|
||||
}
|
||||
|
||||
public void testRegister_thresholdTooLow_setsDefaultThreshold() throws Exception {
|
||||
long thresholdTooLowBytes = 1L;
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdTooLowBytes);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateWifi, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
}
|
||||
|
||||
public void testRegister_highThreshold_accepted() throws Exception {
|
||||
long highThresholdBytes = 2 * THRESHOLD_BYTES;
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, highThresholdBytes);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateWifi, request.template));
|
||||
assertEquals(highThresholdBytes, request.thresholdInBytes);
|
||||
}
|
||||
|
||||
public void testRegister_twoRequests_twoIds() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request1 = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request1.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateWifi, request1.template));
|
||||
assertEquals(THRESHOLD_BYTES, request1.thresholdInBytes);
|
||||
|
||||
DataUsageRequest request2 = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request2.requestId > request1.requestId);
|
||||
assertTrue(Objects.equals(sTemplateWifi, request2.template));
|
||||
assertEquals(THRESHOLD_BYTES, request2.thresholdInBytes);
|
||||
}
|
||||
|
||||
public void testUnregister_unknownRequest_noop() throws Exception {
|
||||
DataUsageRequest unknownRequest = new DataUsageRequest(
|
||||
123456 /* id */, sTemplateWifi, THRESHOLD_BYTES);
|
||||
|
||||
mStatsObservers.unregister(unknownRequest, UID_RED);
|
||||
}
|
||||
|
||||
public void testUnregister_knownRequest_releasesCaller() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
|
||||
|
||||
mStatsObservers.unregister(request, Process.SYSTEM_UID);
|
||||
waitForObserverToIdle();
|
||||
|
||||
Mockito.verify(mockBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
|
||||
}
|
||||
|
||||
public void testUnregister_knownRequest_invalidUid_doesNotUnregister() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
UID_RED, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
|
||||
|
||||
mStatsObservers.unregister(request, UID_BLUE);
|
||||
waitForObserverToIdle();
|
||||
|
||||
Mockito.verifyZeroInteractions(mockBinder);
|
||||
}
|
||||
|
||||
public void testUpdateStats_initialSample_doesNotNotify() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
|
||||
.addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
|
||||
NetworkStats uidSnapshot = null;
|
||||
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
assertEquals(INVALID_TYPE, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
public void testUpdateStats_belowThreshold_doesNotNotify() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
|
||||
.addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
|
||||
NetworkStats uidSnapshot = null;
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
|
||||
.addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
mCv.block(WAIT_TIMEOUT);
|
||||
assertEquals(INVALID_TYPE, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
public void testUpdateStats_deviceAccess_notifies() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
|
||||
.addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
|
||||
NetworkStats uidSnapshot = null;
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */)
|
||||
.addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 22L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
public void testUpdateStats_defaultAccess_notifiesSameUid() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
UID_RED, NetworkStatsAccess.Level.DEFAULT);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveUidIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
public void testUpdateStats_defaultAccess_usageOtherUid_doesNotNotify() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
UID_BLUE, NetworkStatsAccess.Level.DEFAULT);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveUidIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
assertEquals(INVALID_TYPE, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
public void testUpdateStats_userAccess_usageSameUser_notifies() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
UID_BLUE, NetworkStatsAccess.Level.USER);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveUidIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
public void testUpdateStats_userAccess_usageAnotherUser_doesNotNotify() throws Exception {
|
||||
DataUsageRequest inputRequest = new DataUsageRequest(
|
||||
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
|
||||
|
||||
DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder,
|
||||
UID_RED, NetworkStatsAccess.Level.USER);
|
||||
assertTrue(request.requestId > 0);
|
||||
assertTrue(Objects.equals(sTemplateImsi1, request.template));
|
||||
assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
|
||||
|
||||
NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity(
|
||||
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */));
|
||||
mActiveUidIfaces.put(TEST_IFACE, identSet);
|
||||
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES,
|
||||
2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
|
||||
assertTrue(mCv.block(WAIT_TIMEOUT));
|
||||
assertEquals(INVALID_TYPE, mHandler.mLastMessageType);
|
||||
}
|
||||
|
||||
private void waitForObserverToIdle() {
|
||||
// Send dummy message to make sure that any previous message has been handled
|
||||
mHandler.sendMessage(mHandler.obtainMessage(-1));
|
||||
mObserverHandlerThread.waitForIdle(WAIT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
1265
tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
Normal file
1265
tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user