| /* |
| * 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.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.Handler; |
| import android.os.HandlerThread; |
| import android.os.IBinder; |
| import android.os.Process; |
| |
| import android.os.ConditionVariable; |
| import android.os.Looper; |
| import android.os.Messenger; |
| import android.os.Message; |
| import android.os.UserHandle; |
| 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.Arrays; |
| import java.util.List; |
| |
| import junit.framework.TestCase; |
| |
| import org.mockito.Mock; |
| import org.mockito.Mockito; |
| import org.mockito.MockitoAnnotations; |
| |
| /** |
| * Tests for {@link NetworkStatsObservers}. |
| */ |
| 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 int[] NO_UIDS = null; |
| 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; |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateWifi }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, thresholdTooLowBytes); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); |
| } |
| |
| public void testRegister_highThreshold_accepted() throws Exception { |
| long highThresholdBytes = 2 * THRESHOLD_BYTES; |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateWifi }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, highThresholdBytes); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| assertEquals(highThresholdBytes, request.thresholdInBytes); |
| } |
| |
| public void testRegister_twoRequests_twoIds() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateWifi }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request1 = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request1.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request1.templates)); |
| assertNull(request1.uids); |
| assertEquals(THRESHOLD_BYTES, request1.thresholdInBytes); |
| |
| DataUsageRequest request2 = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request2.requestId > request1.requestId); |
| assertTrue(Arrays.deepEquals(templates, request2.templates)); |
| assertNull(request2.uids); |
| assertEquals(THRESHOLD_BYTES, request2.thresholdInBytes); |
| } |
| |
| public void testRegister_defaultAccess_otherUids_securityException() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| int[] uids = new int[] { UID_RED, UID_BLUE, UID_GREEN }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, uids, THRESHOLD_BYTES); |
| |
| try { |
| mStatsObservers.register(inputRequest, mMessenger, mockBinder, UID_RED, |
| NetworkStatsAccess.Level.DEFAULT); |
| fail("Should have denied access"); |
| } catch (SecurityException expected) {} |
| } |
| |
| public void testRegister_userAccess_otherUidsSameUser() |
| throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| int[] uids = new int[] { UID_RED, UID_BLUE, UID_GREEN }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, uids, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_RED, NetworkStatsAccess.Level.USER); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertTrue(Arrays.equals(uids, request.uids)); |
| assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); |
| } |
| |
| public void testRegister_defaultAccess_sameUid() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| int[] uids = new int[] { UID_RED }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, uids, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_RED, NetworkStatsAccess.Level.DEFAULT); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertTrue(Arrays.equals(uids, request.uids)); |
| assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); |
| } |
| |
| public void testUnregister_unknownRequest_noop() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateWifi }; |
| DataUsageRequest unknownRequest = new DataUsageRequest( |
| 123456 /* id */, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| mStatsObservers.unregister(unknownRequest, UID_RED); |
| } |
| |
| public void testUnregister_knownRequest_releasesCaller() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_RED, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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 { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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_aboveThresholdNetwork_notifies() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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_aboveThresholdMultipleNetwork_notifies() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1, sTemplateImsi2 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_RED, NetworkStatsAccess.Level.DEVICESUMMARY); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); |
| |
| NetworkIdentitySet identSet1 = new NetworkIdentitySet(); |
| identSet1.add(new NetworkIdentity( |
| TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, |
| IMSI_1, null /* networkId */, false /* roaming */)); |
| mActiveIfaces.put(TEST_IFACE, identSet1); |
| |
| NetworkIdentitySet identSet2 = new NetworkIdentitySet(); |
| identSet2.add(new NetworkIdentity( |
| TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, |
| IMSI_2, null /* networkId */, false /* roaming */)); |
| mActiveIfaces.put(TEST_IFACE2, identSet2); |
| |
| // Baseline |
| NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) |
| .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L) |
| .addIfaceValues(TEST_IFACE2, BASE_BYTES + 1234L, 18L, BASE_BYTES, 12L); |
| NetworkStats uidSnapshot = null; |
| mStatsObservers.updateStats( |
| xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, |
| VPN_INFO, TEST_START); |
| |
| // Delta - traffic on IMSI2 |
| xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */) |
| .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L) |
| .addIfaceValues(TEST_IFACE2, BASE_BYTES + THRESHOLD_BYTES, 22L, |
| BASE_BYTES + THRESHOLD_BYTES, 24L); |
| 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_aboveThresholdUid_notifies() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| int[] uids = new int[] { UID_RED, UID_BLUE, UID_GREEN }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, uids, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertTrue(Arrays.equals(uids,request.uids)); |
| 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 */)); |
| 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, 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, 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_noUid_notifiesSameUid() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_RED, NetworkStatsAccess.Level.DEFAULT); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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, 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, 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_noUid_usageOtherUid_doesNotNotify() throws Exception { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_BLUE, NetworkStatsAccess.Level.DEFAULT); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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, 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, 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 { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_BLUE, NetworkStatsAccess.Level.USER); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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, 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, 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 { |
| NetworkTemplate[] templates = new NetworkTemplate[] { sTemplateImsi1 }; |
| DataUsageRequest inputRequest = new DataUsageRequest( |
| DataUsageRequest.REQUEST_ID_UNSET, templates, NO_UIDS, THRESHOLD_BYTES); |
| |
| DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, |
| UID_RED, NetworkStatsAccess.Level.USER); |
| assertTrue(request.requestId > 0); |
| assertTrue(Arrays.deepEquals(templates, request.templates)); |
| assertNull(request.uids); |
| 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 */)); |
| 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, 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, 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); |
| } |
| } |