• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.net;
18 
19 import static android.Manifest.permission.DUMP;
20 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
21 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
22 import static android.app.usage.NetworkStatsManager.PREFIX_DEV;
23 import static android.content.Intent.ACTION_UID_REMOVED;
24 import static android.content.Intent.EXTRA_UID;
25 import static android.content.pm.PackageManager.PERMISSION_DENIED;
26 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
27 import static android.net.ConnectivityManager.TYPE_MOBILE;
28 import static android.net.ConnectivityManager.TYPE_TEST;
29 import static android.net.ConnectivityManager.TYPE_WIFI;
30 import static android.net.NetworkIdentity.OEM_PAID;
31 import static android.net.NetworkIdentity.OEM_PRIVATE;
32 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
33 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
34 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
35 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
36 import static android.net.NetworkStats.IFACE_ALL;
37 import static android.net.NetworkStats.INTERFACES_ALL;
38 import static android.net.NetworkStats.METERED_ALL;
39 import static android.net.NetworkStats.METERED_NO;
40 import static android.net.NetworkStats.METERED_YES;
41 import static android.net.NetworkStats.ROAMING_ALL;
42 import static android.net.NetworkStats.ROAMING_NO;
43 import static android.net.NetworkStats.ROAMING_YES;
44 import static android.net.NetworkStats.SET_ALL;
45 import static android.net.NetworkStats.SET_DEFAULT;
46 import static android.net.NetworkStats.SET_FOREGROUND;
47 import static android.net.NetworkStats.TAG_ALL;
48 import static android.net.NetworkStats.TAG_NONE;
49 import static android.net.NetworkStats.UID_ALL;
50 import static android.net.NetworkStatsHistory.FIELD_ALL;
51 import static android.net.NetworkTemplate.MATCH_MOBILE;
52 import static android.net.NetworkTemplate.MATCH_TEST;
53 import static android.net.NetworkTemplate.MATCH_WIFI;
54 import static android.net.NetworkTemplate.OEM_MANAGED_NO;
55 import static android.net.NetworkTemplate.OEM_MANAGED_YES;
56 import static android.net.TrafficStats.MB_IN_BYTES;
57 import static android.net.TrafficStats.UID_REMOVED;
58 import static android.net.TrafficStats.UID_TETHERING;
59 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE;
60 import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
61 import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
62 import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
63 import static android.text.format.DateUtils.DAY_IN_MILLIS;
64 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
65 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
66 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
67 
68 import static com.android.server.net.NetworkStatsEventLogger.POLL_REASON_RAT_CHANGED;
69 import static com.android.server.net.NetworkStatsEventLogger.PollEvent.pollReasonNameOf;
70 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
71 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
72 import static com.android.server.net.NetworkStatsService.BROADCAST_NETWORK_STATS_UPDATED_RATE_LIMIT_ENABLED_FLAG;
73 import static com.android.server.net.NetworkStatsService.DEFAULT_TRAFFIC_STATS_CACHE_EXPIRY_DURATION_MS;
74 import static com.android.server.net.NetworkStatsService.DEFAULT_TRAFFIC_STATS_SERVICE_CACHE_MAX_ENTRIES;
75 import static com.android.server.net.NetworkStatsService.NETSTATS_FASTDATAINPUT_FALLBACKS_COUNTER_NAME;
76 import static com.android.server.net.NetworkStatsService.NETSTATS_FASTDATAINPUT_SUCCESSES_COUNTER_NAME;
77 import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME;
78 import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME;
79 import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME;
80 import static com.android.server.net.NetworkStatsService.TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG;
81 import static com.android.server.net.NetworkStatsService.TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG;
82 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
83 
84 import static org.junit.Assert.assertEquals;
85 import static org.junit.Assert.assertFalse;
86 import static org.junit.Assert.assertNotNull;
87 import static org.junit.Assert.assertNull;
88 import static org.junit.Assert.assertThrows;
89 import static org.junit.Assert.assertTrue;
90 import static org.mockito.AdditionalMatchers.aryEq;
91 import static org.mockito.ArgumentMatchers.any;
92 import static org.mockito.ArgumentMatchers.anyBoolean;
93 import static org.mockito.ArgumentMatchers.anyInt;
94 import static org.mockito.ArgumentMatchers.anyString;
95 import static org.mockito.ArgumentMatchers.eq;
96 import static org.mockito.Mockito.doAnswer;
97 import static org.mockito.Mockito.doReturn;
98 import static org.mockito.Mockito.doThrow;
99 import static org.mockito.Mockito.mock;
100 import static org.mockito.Mockito.never;
101 import static org.mockito.Mockito.reset;
102 import static org.mockito.Mockito.spy;
103 import static org.mockito.Mockito.times;
104 import static org.mockito.Mockito.verify;
105 
106 import android.annotation.NonNull;
107 import android.app.AlarmManager;
108 import android.content.BroadcastReceiver;
109 import android.content.Context;
110 import android.content.Intent;
111 import android.content.IntentFilter;
112 import android.content.pm.PackageManager;
113 import android.content.res.Resources;
114 import android.database.ContentObserver;
115 import android.net.DataUsageRequest;
116 import android.net.INetd;
117 import android.net.INetworkStatsSession;
118 import android.net.LinkProperties;
119 import android.net.Network;
120 import android.net.NetworkCapabilities;
121 import android.net.NetworkIdentity;
122 import android.net.NetworkStateSnapshot;
123 import android.net.NetworkStats;
124 import android.net.NetworkStatsCollection;
125 import android.net.NetworkStatsHistory;
126 import android.net.NetworkTemplate;
127 import android.net.TelephonyNetworkSpecifier;
128 import android.net.TestNetworkSpecifier;
129 import android.net.TetherStatsParcel;
130 import android.net.TetheringManager;
131 import android.net.UnderlyingNetworkInfo;
132 import android.net.netstats.StatsResult;
133 import android.net.netstats.TrafficStatsRateLimitCacheConfig;
134 import android.net.netstats.provider.INetworkStatsProviderCallback;
135 import android.net.wifi.WifiInfo;
136 import android.os.Build;
137 import android.os.DropBoxManager;
138 import android.os.Handler;
139 import android.os.HandlerThread;
140 import android.os.IBinder;
141 import android.os.Looper;
142 import android.os.PowerManager;
143 import android.os.Process;
144 import android.os.SimpleClock;
145 import android.os.UserHandle;
146 import android.provider.Settings;
147 import android.system.ErrnoException;
148 import android.telephony.TelephonyManager;
149 import android.testing.TestableLooper;
150 import android.text.TextUtils;
151 import android.util.ArrayMap;
152 import android.util.IndentingPrintWriter;
153 import android.util.Pair;
154 
155 import androidx.annotation.Nullable;
156 import androidx.test.InstrumentationRegistry;
157 import androidx.test.filters.SmallTest;
158 
159 import com.android.connectivity.resources.R;
160 import com.android.internal.util.FileRotator;
161 import com.android.internal.util.test.BroadcastInterceptingContext;
162 import com.android.net.module.util.ArrayTrackRecord;
163 import com.android.net.module.util.BpfDump;
164 import com.android.net.module.util.IBpfMap;
165 import com.android.net.module.util.LocationPermissionChecker;
166 import com.android.net.module.util.SkDestroyListener;
167 import com.android.net.module.util.Struct;
168 import com.android.net.module.util.Struct.S32;
169 import com.android.net.module.util.Struct.U8;
170 import com.android.net.module.util.bpf.CookieTagMapKey;
171 import com.android.net.module.util.bpf.CookieTagMapValue;
172 import com.android.net.module.util.netlink.InetDiagMessage;
173 import com.android.server.connectivity.ConnectivityResources;
174 import com.android.server.net.NetworkStatsService.AlertObserver;
175 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
176 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
177 import com.android.testutils.DevSdkIgnoreRule;
178 import com.android.testutils.DevSdkIgnoreRunner;
179 import com.android.testutils.HandlerUtils;
180 import com.android.testutils.TestBpfMap;
181 import com.android.testutils.TestableNetworkStatsProviderBinder;
182 import com.android.testutils.com.android.testutils.SetFeatureFlagsRule;
183 import com.android.testutils.com.android.testutils.SetFeatureFlagsRule.FeatureFlag;
184 
185 import libcore.testing.io.TestIoUtils;
186 
187 import org.junit.After;
188 import org.junit.Before;
189 import org.junit.Ignore;
190 import org.junit.Rule;
191 import org.junit.Test;
192 import org.junit.runner.RunWith;
193 import org.mockito.ArgumentCaptor;
194 import org.mockito.Mock;
195 import org.mockito.MockitoAnnotations;
196 
197 import java.io.File;
198 import java.io.FileDescriptor;
199 import java.io.PrintWriter;
200 import java.io.StringWriter;
201 import java.nio.file.Files;
202 import java.nio.file.Path;
203 import java.time.Clock;
204 import java.time.ZoneId;
205 import java.time.ZoneOffset;
206 import java.time.ZonedDateTime;
207 import java.time.temporal.ChronoUnit;
208 import java.util.HashMap;
209 import java.util.List;
210 import java.util.Map;
211 import java.util.Objects;
212 import java.util.Set;
213 import java.util.concurrent.Executor;
214 import java.util.concurrent.atomic.AtomicBoolean;
215 import java.util.function.Consumer;
216 
217 /**
218  * Tests for {@link NetworkStatsService}.
219  *
220  * TODO: This test used to be really brittle because it used Easymock - it uses Mockito now, but
221  * still uses the Easymock structure, which could be simplified.
222  */
223 @DevSdkIgnoreRunner.MonitorThreadLeak
224 @RunWith(DevSdkIgnoreRunner.class)
225 @SmallTest
226 // NetworkStatsService is not updatable before T, so tests do not need to be backwards compatible
227 @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
228 public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
229     @Rule
230     public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
231 
232     private static final String TAG = "NetworkStatsServiceTest";
233 
234     private static final long TEST_START = 1194220800000L;
235 
236     private static final String IMSI_1 = "310004";
237     private static final String IMSI_2 = "310260";
238     private static final String TEST_WIFI_NETWORK_KEY = "WifiNetworkKey";
239 
240     private static NetworkTemplate sTemplateWifi = new NetworkTemplate.Builder(MATCH_WIFI)
241             .setWifiNetworkKeys(Set.of(TEST_WIFI_NETWORK_KEY)).build();
242     private static NetworkTemplate sTemplateCarrierWifi1 = new NetworkTemplate.Builder(MATCH_WIFI)
243             .setSubscriberIds(Set.of(IMSI_1)).build();
244     private static NetworkTemplate sTemplateImsi1 = new NetworkTemplate.Builder(MATCH_MOBILE)
245             .setMeteredness(METERED_YES).setSubscriberIds(Set.of(IMSI_1)).build();
246     private static NetworkTemplate sTemplateImsi2 = new NetworkTemplate.Builder(MATCH_MOBILE)
247             .setMeteredness(METERED_YES).setSubscriberIds(Set.of(IMSI_2)).build();
248 
249     private static final Network WIFI_NETWORK =  new Network(100);
250     private static final Network MOBILE_NETWORK =  new Network(101);
251     private static final Network VPN_NETWORK = new Network(102);
252     private static final Network TEST_NETWORK = new Network(103);
253 
254     private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK };
255     private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK };
256     private static final Network[] NETWORKS_TEST = new Network[]{ TEST_NETWORK };
257 
258     private static final long WAIT_TIMEOUT = 2 * 1000;  // 2 secs
259     private static final int INVALID_TYPE = -1;
260 
261     private static final String DUMPSYS_BPF_RAW_MAP = "--bpfRawMap";
262     private static final String DUMPSYS_COOKIE_TAG_MAP = "--cookieTagMap";
263     private static final String LINE_DELIMITER = "\\n";
264 
265 
266     private long mElapsedRealtime;
267 
268     private File mStatsDir;
269     private File mLegacyStatsDir;
270     private MockContext mServiceContext;
271     private @Mock TelephonyManager mTelephonyManager;
272     private static @Mock WifiInfo sWifiInfo;
273     private @Mock INetd mNetd;
274     private @Mock TetheringManager mTetheringManager;
275     private @Mock PackageManager mPm;
276     private @Mock NetworkStatsFactory mStatsFactory;
277     @NonNull
278     private final TestNetworkStatsSettings mSettings =
279             new TestNetworkStatsSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
280     private @Mock IBinder mUsageCallbackBinder;
281     private TestableUsageCallback mUsageCallback;
282     private @Mock AlarmManager mAlarmManager;
283     @Mock
284     private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
285     private @Mock BpfInterfaceMapHelper mBpfInterfaceMapHelper;
286     private HandlerThread mHandlerThread;
287     @Mock
288     private LocationPermissionChecker mLocationPermissionChecker;
289     private TestBpfMap<S32, U8> mUidCounterSetMap = spy(new TestBpfMap<>(S32.class, U8.class));
290     @Mock
291     private SkDestroyListener mSkDestroyListener;
292 
293     private TestBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap = new TestBpfMap<>(
294             CookieTagMapKey.class, CookieTagMapValue.class);
295     private TestBpfMap<StatsMapKey, StatsMapValue> mStatsMapA = new TestBpfMap<>(StatsMapKey.class,
296             StatsMapValue.class);
297     private TestBpfMap<StatsMapKey, StatsMapValue> mStatsMapB = new TestBpfMap<>(StatsMapKey.class,
298             StatsMapValue.class);
299     private TestBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap = new TestBpfMap<>(
300             UidStatsMapKey.class, StatsMapValue.class);
301     private TestBpfMap<S32, StatsMapValue> mIfaceStatsMap = new TestBpfMap<>(
302             S32.class, StatsMapValue.class);
303     private NetworkStatsService mService;
304     private INetworkStatsSession mSession;
305     private AlertObserver mAlertObserver;
306     private ContentObserver mContentObserver;
307     private Handler mHandler;
308     private TetheringManager.TetheringEventCallback mTetheringEventCallback;
309     private Map<String, NetworkStatsCollection> mPlatformNetworkStatsCollection =
310             new ArrayMap<String, NetworkStatsCollection>();
311     private boolean mStoreFilesInApexData = false;
312     private int mImportLegacyTargetAttempts = 0;
313     private @Mock PersistentInt mImportLegacyAttemptsCounter;
314     private @Mock PersistentInt mImportLegacySuccessesCounter;
315     private @Mock PersistentInt mImportLegacyFallbacksCounter;
316     private int mFastDataInputTargetAttempts = 0;
317     private @Mock PersistentInt mFastDataInputSuccessesCounter;
318     private @Mock PersistentInt mFastDataInputFallbacksCounter;
319     private String mCompareStatsResult = null;
320     private @Mock Resources mResources;
321     private Boolean mIsDebuggable;
322     private HandlerThread mObserverHandlerThread;
323     final TestDependencies mDeps = new TestDependencies();
324     final HashMap<String, Boolean> mFeatureFlags = new HashMap<>();
325     final HashMap<Long, Boolean> mCompatChanges = new HashMap<>();
326 
327     // This will set feature flags from @FeatureFlag annotations
328     // into the map before setUp() runs.
329     @Rule
330     public final SetFeatureFlagsRule mSetFeatureFlagsRule =
331             new SetFeatureFlagsRule((name, enabled) -> {
332                 mFeatureFlags.put(name, enabled);
333                 return null;
334             }, (name) -> mFeatureFlags.getOrDefault(name, false));
335 
336     private class MockContext extends BroadcastInterceptingContext {
337         private final Context mBaseContext;
338 
MockContext(Context base)339         MockContext(Context base) {
340             super(base);
341             mBaseContext = base;
342         }
343 
344         @Override
getPackageManager()345         public PackageManager getPackageManager() {
346             return mPm;
347         }
348 
349         @Override
createContextAsUser(UserHandle user, int flags)350         public Context createContextAsUser(UserHandle user, int flags) {
351             return this;
352         }
353 
354         @Override
getSystemService(String name)355         public Object getSystemService(String name) {
356             if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
357             if (Context.TETHERING_SERVICE.equals(name)) return mTetheringManager;
358             return mBaseContext.getSystemService(name);
359         }
360 
361         @Override
enforceCallingOrSelfPermission(String permission, @Nullable String message)362         public void enforceCallingOrSelfPermission(String permission, @Nullable String message) {
363             if (checkCallingOrSelfPermission(permission) != PERMISSION_GRANTED) {
364                 throw new SecurityException("Test does not have mocked permission " + permission);
365             }
366         }
367 
368         @Override
checkCallingOrSelfPermission(String permission)369         public int checkCallingOrSelfPermission(String permission) {
370             switch (permission) {
371                 case PERMISSION_MAINLINE_NETWORK_STACK:
372                 case READ_NETWORK_USAGE_HISTORY:
373                 case UPDATE_DEVICE_STATS:
374                 case DUMP:
375                     return PERMISSION_GRANTED;
376                 default:
377                     return PERMISSION_DENIED;
378             }
379 
380         }
381     }
382 
383     private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
384         @Override
385         public long millis() {
386             return currentTimeMillis();
387         }
388     };
389 
390     @NonNull
buildTetherStatsParcel(String iface, long rxBytes, long rxPackets, long txBytes, long txPackets, int ifIndex)391     private static TetherStatsParcel buildTetherStatsParcel(String iface, long rxBytes,
392             long rxPackets, long txBytes, long txPackets, int ifIndex) {
393         TetherStatsParcel parcel = new TetherStatsParcel();
394         parcel.iface = iface;
395         parcel.rxBytes = rxBytes;
396         parcel.rxPackets = rxPackets;
397         parcel.txBytes = txBytes;
398         parcel.txPackets = txPackets;
399         parcel.ifIndex = ifIndex;
400         return parcel;
401     }
402 
403     @Before
setUp()404     public void setUp() throws Exception {
405         MockitoAnnotations.initMocks(this);
406 
407         // Setup mock resources.
408         final Context mockResContext = mock(Context.class);
409         doReturn(mResources).when(mockResContext).getResources();
410         ConnectivityResources.setResourcesContextForTest(mockResContext);
411 
412         final Context context = InstrumentationRegistry.getContext();
413         mServiceContext = new MockContext(context);
414         doReturn(true).when(mLocationPermissionChecker).checkCallersLocationPermission(
415                 any(), any(), anyInt(), anyBoolean(), any());
416         doReturn(TEST_WIFI_NETWORK_KEY).when(sWifiInfo).getNetworkKey();
417         mStatsDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
418         mLegacyStatsDir = TestIoUtils.createTemporaryDirectory(
419                 getClass().getSimpleName() + "-legacy");
420 
421         PowerManager powerManager = (PowerManager) mServiceContext.getSystemService(
422                 Context.POWER_SERVICE);
423         PowerManager.WakeLock wakeLock =
424                 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
425 
426         mHandlerThread = new HandlerThread("NetworkStatsServiceTest-HandlerThread");
427         // Create a separate thread for observers to run on. This thread cannot be the same
428         // as the handler thread, because the observer callback is fired on this thread, and
429         // it should not be blocked by client code. Additionally, creating the observers
430         // object requires a looper, which can only be obtained after a thread has been started.
431         mObserverHandlerThread = new HandlerThread("NetworkStatsServiceTest-ObserversThread");
432         mObserverHandlerThread.start();
433         final Looper observerLooper = mObserverHandlerThread.getLooper();
434         final NetworkStatsObservers statsObservers = new NetworkStatsObservers() {
435             @Override
436             protected Looper getHandlerLooperLocked() {
437                 return observerLooper;
438             }
439         };
440         mService = new NetworkStatsService(mServiceContext, mNetd, mAlarmManager, wakeLock,
441                 mClock, mSettings, mStatsFactory, statsObservers, mDeps);
442 
443         mElapsedRealtime = 0L;
444 
445         prepareForSystemReady();
446         mService.systemReady();
447         // Verify that system ready fetches realtime stats
448         verify(mStatsFactory).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
449         // Wait for posting onChange() event to handler thread and verify that when system ready,
450         // start monitoring data usage per RAT type because the settings value is mock as false
451         // by default in expectSettings().
452         waitForIdle();
453         verify(mNetworkStatsSubscriptionsMonitor).start();
454         reset(mNetworkStatsSubscriptionsMonitor);
455 
456         doReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS).when(mTelephonyManager)
457                 .checkCarrierPrivilegesForPackageAnyPhone(anyString());
458 
459         mSession = mService.openSession();
460         assertNotNull("openSession() failed", mSession);
461 
462         // Catch AlertObserver during systemReady().
463         final ArgumentCaptor<AlertObserver> alertObserver =
464                 ArgumentCaptor.forClass(AlertObserver.class);
465         verify(mNetd).registerUnsolicitedEventListener(alertObserver.capture());
466         mAlertObserver = alertObserver.getValue();
467 
468         // Catch TetheringEventCallback during systemReady().
469         ArgumentCaptor<TetheringManager.TetheringEventCallback> tetheringEventCbCaptor =
470                 ArgumentCaptor.forClass(TetheringManager.TetheringEventCallback.class);
471         verify(mTetheringManager).registerTetheringEventCallback(
472                 any(), tetheringEventCbCaptor.capture());
473         mTetheringEventCallback = tetheringEventCbCaptor.getValue();
474 
475         doReturn(Process.myUid()).when(mPm)
476                 .getPackageUid(eq(mServiceContext.getPackageName()), anyInt());
477 
478         mUsageCallback = new TestableUsageCallback(mUsageCallbackBinder);
479     }
480 
481     class TestDependencies extends NetworkStatsService.Dependencies {
482         private int mCompareStatsInvocation = 0;
483         private NetworkStats.Entry mMockedTrafficStatsNativeStat = null;
484 
485         @Override
getLegacyStatsDir()486         public File getLegacyStatsDir() {
487             return mLegacyStatsDir;
488         }
489 
490         @Override
getOrCreateStatsDir()491         public File getOrCreateStatsDir() {
492             return mStatsDir;
493         }
494 
495         @Override
getStoreFilesInApexData()496         public boolean getStoreFilesInApexData() {
497             return mStoreFilesInApexData;
498         }
499 
500         @Override
getImportLegacyTargetAttempts()501         public int getImportLegacyTargetAttempts() {
502             return mImportLegacyTargetAttempts;
503         }
504 
505         @Override
getUseFastDataInputTargetAttempts()506         public int getUseFastDataInputTargetAttempts() {
507             return mFastDataInputTargetAttempts;
508         }
509 
510         @Override
compareStats(NetworkStatsCollection a, NetworkStatsCollection b, boolean allowKeyChange)511         public String compareStats(NetworkStatsCollection a, NetworkStatsCollection b,
512                  boolean allowKeyChange) {
513             mCompareStatsInvocation++;
514             return mCompareStatsResult;
515         }
516 
getCompareStatsInvocation()517         int getCompareStatsInvocation() {
518             return mCompareStatsInvocation;
519         }
520 
521         @Override
createPersistentCounter(@onNull Path dir, @NonNull String name)522         public PersistentInt createPersistentCounter(@NonNull Path dir, @NonNull String name) {
523             switch (name) {
524                 case NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME:
525                     return mImportLegacyAttemptsCounter;
526                 case NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME:
527                     return mImportLegacySuccessesCounter;
528                 case NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME:
529                     return mImportLegacyFallbacksCounter;
530                 case NETSTATS_FASTDATAINPUT_SUCCESSES_COUNTER_NAME:
531                     return mFastDataInputSuccessesCounter;
532                 case NETSTATS_FASTDATAINPUT_FALLBACKS_COUNTER_NAME:
533                     return mFastDataInputFallbacksCounter;
534                 default:
535                     throw new IllegalArgumentException("Unknown counter name: " + name);
536             }
537         }
538 
539         @Override
readPlatformCollection( @onNull String prefix, long bucketDuration)540         public NetworkStatsCollection readPlatformCollection(
541                 @NonNull String prefix, long bucketDuration) {
542             return mPlatformNetworkStatsCollection.get(prefix);
543         }
544 
545         @Override
makeHandlerThread()546         public HandlerThread makeHandlerThread() {
547             return mHandlerThread;
548         }
549 
550         @Override
makeSubscriptionsMonitor( @onNull Context context, @NonNull Executor executor, @NonNull NetworkStatsService service)551         public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(
552                 @NonNull Context context, @NonNull Executor executor,
553                 @NonNull NetworkStatsService service) {
554 
555             return mNetworkStatsSubscriptionsMonitor;
556         }
557 
558         @Override
makeContentObserver(Handler handler, NetworkStatsSettings settings, NetworkStatsSubscriptionsMonitor monitor)559         public ContentObserver makeContentObserver(Handler handler,
560                 NetworkStatsSettings settings, NetworkStatsSubscriptionsMonitor monitor) {
561             mHandler = handler;
562             return mContentObserver = super.makeContentObserver(handler, settings, monitor);
563         }
564 
565         @Override
makeLocationPermissionChecker(final Context context)566         public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
567             return mLocationPermissionChecker;
568         }
569 
570         @Override
makeBpfInterfaceMapHelper()571         public BpfInterfaceMapHelper makeBpfInterfaceMapHelper() {
572             return mBpfInterfaceMapHelper;
573         }
574 
575         @Override
getUidCounterSetMap()576         public IBpfMap<S32, U8> getUidCounterSetMap() {
577             return mUidCounterSetMap;
578         }
579 
580         @Override
getCookieTagMap()581         public IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
582             return mCookieTagMap;
583         }
584 
585         @Override
getStatsMapA()586         public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapA() {
587             return mStatsMapA;
588         }
589 
590         @Override
getStatsMapB()591         public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapB() {
592             return mStatsMapB;
593         }
594 
595         @Override
getAppUidStatsMap()596         public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() {
597             return mAppUidStatsMap;
598         }
599 
600         @Override
getIfaceStatsMap()601         public IBpfMap<S32, StatsMapValue> getIfaceStatsMap() {
602             return mIfaceStatsMap;
603         }
604 
605         @Override
isDebuggable()606         public boolean isDebuggable() {
607             return mIsDebuggable == Boolean.TRUE;
608         }
609 
610         @Override
makeSkDestroyListener(Consumer<InetDiagMessage> consumer, Handler handler)611         public SkDestroyListener makeSkDestroyListener(Consumer<InetDiagMessage> consumer,
612                 Handler handler) {
613             return mSkDestroyListener;
614         }
615 
616         @Override
supportEventLogger(@onNull Context cts)617         public boolean supportEventLogger(@NonNull Context cts) {
618             return true;
619         }
620 
621         @Override
isTrafficStatsServiceRateLimitCacheEnabled(Context ctx, boolean isClientCacheEnabled)622         public boolean isTrafficStatsServiceRateLimitCacheEnabled(Context ctx,
623                 boolean isClientCacheEnabled) {
624             return !isClientCacheEnabled && mFeatureFlags.getOrDefault(
625                     TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG, false);
626         }
627 
628         @Override
enabledBroadcastNetworkStatsUpdatedRateLimiting(Context ctx)629         public boolean enabledBroadcastNetworkStatsUpdatedRateLimiting(Context ctx) {
630             return mFeatureFlags.getOrDefault(
631                     BROADCAST_NETWORK_STATS_UPDATED_RATE_LIMIT_ENABLED_FLAG, true);
632         }
633 
634         @Override
getTrafficStatsRateLimitCacheExpiryDuration()635         public int getTrafficStatsRateLimitCacheExpiryDuration() {
636             return DEFAULT_TRAFFIC_STATS_CACHE_EXPIRY_DURATION_MS;
637         }
638 
639         @Override
getTrafficStatsServiceRateLimitCacheMaxEntries()640         public int getTrafficStatsServiceRateLimitCacheMaxEntries() {
641             return DEFAULT_TRAFFIC_STATS_SERVICE_CACHE_MAX_ENTRIES;
642         }
643 
644         @Override
getTrafficStatsRateLimitCacheClientSideConfig( @onNull Context ctx)645         public TrafficStatsRateLimitCacheConfig getTrafficStatsRateLimitCacheClientSideConfig(
646                 @NonNull Context ctx) {
647             final TrafficStatsRateLimitCacheConfig config =
648                     new TrafficStatsRateLimitCacheConfig.Builder()
649                             .setIsCacheEnabled(mFeatureFlags.getOrDefault(
650                                     TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG, false))
651                             .setExpiryDurationMs(DEFAULT_TRAFFIC_STATS_CACHE_EXPIRY_DURATION_MS)
652                             .setMaxEntries(DEFAULT_TRAFFIC_STATS_SERVICE_CACHE_MAX_ENTRIES)
653                             .build();
654             return config;
655         }
656 
657         @Override
isChangeEnabled(long changeId, int uid)658         public boolean isChangeEnabled(long changeId, int uid) {
659             return mCompatChanges.getOrDefault(changeId, true);
660         }
661 
setChangeEnabled(long changeId, boolean enabled)662         public void setChangeEnabled(long changeId, boolean enabled) {
663             mCompatChanges.put(changeId, enabled);
664         }
665         @Nullable
666         @Override
nativeGetTotalStat()667         public NetworkStats.Entry nativeGetTotalStat() {
668             return mMockedTrafficStatsNativeStat;
669         }
670 
671         @Nullable
672         @Override
nativeGetIfaceStat(String iface)673         public NetworkStats.Entry nativeGetIfaceStat(String iface) {
674             return mMockedTrafficStatsNativeStat;
675         }
676 
677         @Nullable
678         @Override
nativeGetUidStat(int uid)679         public NetworkStats.Entry nativeGetUidStat(int uid) {
680             return mMockedTrafficStatsNativeStat;
681         }
682 
setNativeStat(NetworkStats.Entry entry)683         public void setNativeStat(NetworkStats.Entry entry) {
684             mMockedTrafficStatsNativeStat = entry;
685         }
686     }
687 
688     @After
tearDown()689     public void tearDown() throws Exception {
690         mServiceContext = null;
691         mStatsDir = null;
692 
693         mNetd = null;
694 
695         mSession.close();
696         mService = null;
697 
698         if (mHandlerThread != null) {
699             mHandlerThread.quitSafely();
700             mHandlerThread.join();
701         }
702         if (mObserverHandlerThread != null) {
703             mObserverHandlerThread.quitSafely();
704             mObserverHandlerThread.join();
705         }
706     }
707 
initWifiStats(NetworkStateSnapshot snapshot)708     private void initWifiStats(NetworkStateSnapshot snapshot) throws Exception {
709         // pretend that wifi network comes online; service should ask about full
710         // network state, and poll any existing interfaces before updating.
711         mockDefaultSettings();
712         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {snapshot};
713         mockNetworkStatsSummary(buildEmptyStats());
714         mockNetworkStatsUidDetail(buildEmptyStats());
715 
716         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
717                 new UnderlyingNetworkInfo[0]);
718     }
719 
incrementWifiStats(long durationMillis, String iface, long rxb, long rxp, long txb, long txp)720     private void incrementWifiStats(long durationMillis, String iface,
721             long rxb, long rxp, long txb, long txp) throws Exception {
722         incrementCurrentTime(durationMillis);
723         mockDefaultSettings();
724         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
725                 .insertEntry(iface, rxb, rxp, txb, txp));
726         mockNetworkStatsUidDetail(buildEmptyStats());
727         forcePollAndWaitForIdle();
728     }
729 
730     @Test
testNetworkStatsCarrierWifi()731     public void testNetworkStatsCarrierWifi() throws Exception {
732         initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
733         // verify service has empty history for carrier merged wifi and non-carrier wifi
734         assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
735         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
736 
737         // modify some number on wifi, and trigger poll event
738         incrementWifiStats(HOUR_IN_MILLIS, TEST_IFACE, 1024L, 1L, 2048L, 2L);
739 
740         // verify service recorded history
741         assertNetworkTotal(sTemplateCarrierWifi1, 1024L, 1L, 2048L, 2L, 0);
742 
743         // verify service recorded history for wifi with WiFi Network Key filter
744         assertNetworkTotal(sTemplateWifi,  1024L, 1L, 2048L, 2L, 0);
745 
746 
747         // and bump forward again, with counters going higher. this is
748         // important, since polling should correctly subtract last snapshot.
749         incrementWifiStats(DAY_IN_MILLIS, TEST_IFACE, 4096L, 4L, 8192L, 8L);
750 
751         // verify service recorded history
752         assertNetworkTotal(sTemplateCarrierWifi1, 4096L, 4L, 8192L, 8L, 0);
753         // verify service recorded history for wifi with WiFi Network Key filter
754         assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
755     }
756 
757     @Test
testNetworkStatsNonCarrierWifi()758     public void testNetworkStatsNonCarrierWifi() throws Exception {
759         initWifiStats(buildWifiState());
760 
761         // verify service has empty history for wifi
762         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
763         // verify service has empty history for carrier merged wifi
764         assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
765 
766         // modify some number on wifi, and trigger poll event
767         incrementWifiStats(HOUR_IN_MILLIS, TEST_IFACE, 1024L, 1L, 2048L, 2L);
768 
769         // verify service recorded history
770         assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
771         // verify service has empty history for carrier wifi since current network is non carrier
772         // wifi
773         assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
774 
775         // and bump forward again, with counters going higher. this is
776         // important, since polling should correctly subtract last snapshot.
777         incrementWifiStats(DAY_IN_MILLIS, TEST_IFACE, 4096L, 4L, 8192L, 8L);
778 
779         // verify service recorded history
780         assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
781         // verify service has empty history for carrier wifi since current network is non carrier
782         // wifi
783         assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
784     }
785 
786     @Test
testStatsRebootPersist()787     public void testStatsRebootPersist() throws Exception {
788         assertStatsFilesExist(false);
789 
790         // pretend that wifi network comes online; service should ask about full
791         // network state, and poll any existing interfaces before updating.
792         mockDefaultSettings();
793         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
794         mockNetworkStatsSummary(buildEmptyStats());
795         mockNetworkStatsUidDetail(buildEmptyStats());
796 
797         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
798                 new UnderlyingNetworkInfo[0]);
799 
800         // verify service has empty history for wifi
801         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
802 
803 
804         // modify some number on wifi, and trigger poll event
805         incrementCurrentTime(HOUR_IN_MILLIS);
806         mockDefaultSettings();
807         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
808                 .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
809         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
810                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
811                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
812                 .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
813                 .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
814                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
815         mService.noteUidForeground(UID_RED, false);
816         verify(mUidCounterSetMap, never()).deleteEntry(any());
817         mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
818         mService.noteUidForeground(UID_RED, true);
819         verify(mUidCounterSetMap).updateEntry(
820                 eq(new S32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
821         mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
822 
823         forcePollAndWaitForIdle();
824 
825         // verify service recorded history
826         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
827         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
828         assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO,
829                 DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 4);
830         assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO,
831                 DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 6);
832         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
833 
834 
835         // graceful shutdown system, which should trigger persist of stats, and
836         // clear any values in memory.
837         mockDefaultSettings();
838         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
839         assertStatsFilesExist(true);
840 
841         // boot through serviceReady() again
842         prepareForSystemReady();
843 
844         mService.systemReady();
845 
846         // after systemReady(), we should have historical stats loaded again
847         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
848         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
849         assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO,
850                 DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 4);
851         assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO,
852                 DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 6);
853         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
854 
855     }
856 
857     // TODO: simulate reboot to test bucket resize
858     @Test
859     @Ignore
testStatsBucketResize()860     public void testStatsBucketResize() throws Exception {
861         NetworkStatsHistory history = null;
862 
863         assertStatsFilesExist(false);
864 
865         // pretend that wifi network comes online; service should ask about full
866         // network state, and poll any existing interfaces before updating.
867         mockSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
868         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
869         mockNetworkStatsSummary(buildEmptyStats());
870         mockNetworkStatsUidDetail(buildEmptyStats());
871 
872         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
873                 new UnderlyingNetworkInfo[0]);
874 
875         // modify some number on wifi, and trigger poll event
876         incrementCurrentTime(2 * HOUR_IN_MILLIS);
877         mockSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
878         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
879                 .insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L));
880         mockNetworkStatsUidDetail(buildEmptyStats());
881         forcePollAndWaitForIdle();
882 
883         // verify service recorded history
884         history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
885         assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
886         assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
887         assertEquals(2, history.size());
888 
889 
890         // now change bucket duration setting and trigger another poll with
891         // exact same values, which should resize existing buckets.
892         mockSettings(30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
893         mockNetworkStatsSummary(buildEmptyStats());
894         mockNetworkStatsUidDetail(buildEmptyStats());
895         forcePollAndWaitForIdle();
896 
897         // verify identical stats, but spread across 4 buckets now
898         history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
899         assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
900         assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
901         assertEquals(4, history.size());
902 
903     }
904 
905     @Test
testUidStatsAcrossNetworks()906     public void testUidStatsAcrossNetworks() throws Exception {
907         // pretend first mobile network comes online
908         mockDefaultSettings();
909         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobileState(IMSI_1)};
910         mockNetworkStatsSummary(buildEmptyStats());
911         mockNetworkStatsUidDetail(buildEmptyStats());
912 
913         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
914                 new UnderlyingNetworkInfo[0]);
915 
916         // create some traffic on first network
917         incrementCurrentTime(HOUR_IN_MILLIS);
918         mockDefaultSettings();
919         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
920                 .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
921         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
922                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
923                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
924                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
925         mService.incrementOperationCount(UID_RED, 0xF00D, 10);
926 
927         forcePollAndWaitForIdle();
928 
929         // verify service recorded history
930         assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
931         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
932         assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
933         assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
934 
935 
936         // now switch networks; this also tests that we're okay with interfaces
937         // disappearing, to verify we don't count backwards.
938         incrementCurrentTime(HOUR_IN_MILLIS);
939         mockDefaultSettings();
940         states = new NetworkStateSnapshot[] {buildMobileState(IMSI_2)};
941         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
942                 .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
943         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
944                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
945                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
946                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
947 
948         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
949                 new UnderlyingNetworkInfo[0]);
950         forcePollAndWaitForIdle();
951 
952 
953         // create traffic on second network
954         incrementCurrentTime(HOUR_IN_MILLIS);
955         mockDefaultSettings();
956         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
957                 .insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L));
958         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
959                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
960                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
961                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
962                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
963         mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
964 
965         forcePollAndWaitForIdle();
966 
967         // verify original history still intact
968         assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
969         assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
970         assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
971 
972         // and verify new history also recorded under different template, which
973         // verifies that we didn't cross the streams.
974         assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
975         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
976         assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
977 
978     }
979 
980     @Test
testUidRemovedIsMoved()981     public void testUidRemovedIsMoved() throws Exception {
982         // pretend that network comes online
983         mockDefaultSettings();
984         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
985         mockNetworkStatsSummary(buildEmptyStats());
986         mockNetworkStatsUidDetail(buildEmptyStats());
987 
988         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
989                 new UnderlyingNetworkInfo[0]);
990 
991         // create some traffic
992         incrementCurrentTime(HOUR_IN_MILLIS);
993         mockDefaultSettings();
994         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
995                 .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
996         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
997                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
998                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
999                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
1000                         4096L, 258L, 512L, 32L, 0L)
1001                 .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
1002         mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
1003 
1004         forcePollAndWaitForIdle();
1005 
1006         // verify service recorded history
1007         assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
1008         assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
1009         assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
1010         assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
1011 
1012         // now pretend two UIDs are uninstalled, which should migrate stats to
1013         // special "removed" bucket.
1014         mockDefaultSettings();
1015         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
1016                 .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
1017         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1018                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
1019                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
1020                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
1021                         4096L, 258L, 512L, 32L, 0L)
1022                 .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
1023         final Intent intent = new Intent(ACTION_UID_REMOVED);
1024         intent.putExtra(EXTRA_UID, UID_BLUE);
1025         mServiceContext.sendBroadcast(intent);
1026         intent.putExtra(EXTRA_UID, UID_RED);
1027         mServiceContext.sendBroadcast(intent);
1028 
1029         // existing uid and total should remain unchanged; but removed UID
1030         // should be gone completely.
1031         assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
1032         assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
1033         assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
1034         assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
1035         assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10);
1036 
1037     }
1038 
1039     @Test
testMobileStatsByRatTypeForSatellite()1040     public void testMobileStatsByRatTypeForSatellite() throws Exception {
1041         doTestMobileStatsByRatType(new NetworkStateSnapshot[]{buildSatelliteMobileState(IMSI_1)});
1042     }
1043 
1044     @Test
testMobileStatsByRatTypeForCellular()1045     public void testMobileStatsByRatTypeForCellular() throws Exception {
1046         doTestMobileStatsByRatType(new NetworkStateSnapshot[]{buildMobileState(IMSI_1)});
1047     }
1048 
doTestMobileStatsByRatType(NetworkStateSnapshot[] states)1049     private void doTestMobileStatsByRatType(NetworkStateSnapshot[] states) throws Exception {
1050         final NetworkTemplate template3g = new NetworkTemplate.Builder(MATCH_MOBILE)
1051                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
1052                 .setMeteredness(METERED_YES).build();
1053         final NetworkTemplate template4g = new NetworkTemplate.Builder(MATCH_MOBILE)
1054                 .setRatType(TelephonyManager.NETWORK_TYPE_LTE)
1055                 .setMeteredness(METERED_YES).build();
1056         final NetworkTemplate template5g = new NetworkTemplate.Builder(MATCH_MOBILE)
1057                 .setRatType(TelephonyManager.NETWORK_TYPE_NR)
1058                 .setMeteredness(METERED_YES).build();
1059 
1060         // 3G network comes online.
1061         mockNetworkStatsSummary(buildEmptyStats());
1062         mockNetworkStatsUidDetail(buildEmptyStats());
1063 
1064         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
1065         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1066                 new UnderlyingNetworkInfo[0]);
1067 
1068         // Create some traffic.
1069         incrementCurrentTime(MINUTE_IN_MILLIS);
1070         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1071                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1072                          METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L)));
1073         forcePollAndWaitForIdle();
1074 
1075         // Verify 3g templates gets stats.
1076         assertUidTotal(sTemplateImsi1, UID_RED, 12L, 18L, 14L, 1L, 0);
1077         assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
1078         assertUidTotal(template4g, UID_RED, 0L, 0L, 0L, 0L, 0);
1079         assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0);
1080 
1081         // 4G network comes online.
1082         incrementCurrentTime(MINUTE_IN_MILLIS);
1083         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
1084         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1085                 // Append more traffic on existing 3g stats entry.
1086                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1087                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16L, 22L, 17L, 2L, 0L))
1088                 // Add entry that is new on 4g.
1089                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
1090                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 33L, 27L, 8L, 10L, 1L)));
1091         forcePollAndWaitForIdle();
1092 
1093         // Verify ALL_MOBILE template gets all. 3g template counters do not increase.
1094         assertUidTotal(sTemplateImsi1, UID_RED, 49L, 49L, 25L, 12L, 1);
1095         assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
1096         // Verify 4g template counts appended stats on existing entry and newly created entry.
1097         assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1);
1098         // Verify 5g template doesn't get anything since no traffic is generated on 5g.
1099         assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0);
1100 
1101         // 5g network comes online.
1102         incrementCurrentTime(MINUTE_IN_MILLIS);
1103         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
1104         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1105                 // Existing stats remains.
1106                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1107                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16L, 22L, 17L, 2L, 0L))
1108                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
1109                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 33L, 27L, 8L, 10L, 1L))
1110                 // Add some traffic on 5g.
1111                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1112                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 5L, 13L, 31L, 9L, 2L)));
1113         forcePollAndWaitForIdle();
1114 
1115         // Verify ALL_MOBILE template gets all.
1116         assertUidTotal(sTemplateImsi1, UID_RED, 54L, 62L, 56L, 21L, 3);
1117         // 3g/4g template counters do not increase.
1118         assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
1119         assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1);
1120         // Verify 5g template gets the 5g count.
1121         assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2);
1122     }
1123 
1124     @Test
testMobileStatsMeteredness()1125     public void testMobileStatsMeteredness() throws Exception {
1126         // Create metered 5g template.
1127         final NetworkTemplate templateMetered5g = new NetworkTemplate.Builder(MATCH_MOBILE)
1128                 .setRatType(TelephonyManager.NETWORK_TYPE_NR)
1129                 .setMeteredness(METERED_YES).build();
1130         // Create non-metered 5g template
1131         final NetworkTemplate templateNonMetered5g = new NetworkTemplate.Builder(MATCH_MOBILE)
1132                 .setRatType(TelephonyManager.NETWORK_TYPE_NR)
1133                 .setMeteredness(METERED_NO).build();
1134 
1135         mockDefaultSettings();
1136         mockNetworkStatsSummary(buildEmptyStats());
1137         mockNetworkStatsUidDetail(buildEmptyStats());
1138 
1139         // Pretend that 5g mobile network comes online
1140         final NetworkStateSnapshot[] mobileStates =
1141                 new NetworkStateSnapshot[] {buildMobileState(IMSI_1), buildStateOfTransport(
1142                         NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
1143                         TEST_IFACE2, IMSI_1, null /* wifiNetworkKey */,
1144                         true /* isTemporarilyNotMetered */, false /* isRoaming */)};
1145         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
1146         mService.notifyNetworkStatus(NETWORKS_MOBILE, mobileStates,
1147                 getActiveIface(mobileStates), new UnderlyingNetworkInfo[0]);
1148 
1149         // Create some traffic
1150         // Note that all traffic from NetworkManagementService is tagged as METERED_NO, ROAMING_NO
1151         // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
1152         // They are layered on top by inspecting the iface properties.
1153         incrementCurrentTime(HOUR_IN_MILLIS);
1154         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1155                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
1156                         DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
1157                 .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
1158                         DEFAULT_NETWORK_YES, 256, 3L, 128L, 5L, 0L));
1159         forcePollAndWaitForIdle();
1160 
1161         // Verify service recorded history.
1162         assertUidTotal(templateMetered5g, UID_RED, 384L, 5L, 256L, 7L, 0);
1163         assertUidTotal(templateNonMetered5g, UID_RED, 0L, 0L, 0L, 0L, 0);
1164     }
1165 
1166     @Test
testMobileStatsOemManaged()1167     public void testMobileStatsOemManaged() throws Exception {
1168         final NetworkTemplate templateOemPaid = new NetworkTemplate.Builder(MATCH_MOBILE)
1169                 .setOemManaged(OEM_PAID).build();
1170 
1171         final NetworkTemplate templateOemPrivate = new NetworkTemplate.Builder(MATCH_MOBILE)
1172                 .setOemManaged(OEM_PRIVATE).build();
1173 
1174         final NetworkTemplate templateOemAll = new NetworkTemplate.Builder(MATCH_MOBILE)
1175                 .setOemManaged(OEM_PAID | OEM_PRIVATE).build();
1176 
1177         final NetworkTemplate templateOemYes = new NetworkTemplate.Builder(MATCH_MOBILE)
1178                 .setOemManaged(OEM_MANAGED_YES).build();
1179 
1180         final NetworkTemplate templateOemNone = new NetworkTemplate.Builder(MATCH_MOBILE)
1181                 .setOemManaged(OEM_MANAGED_NO).build();
1182 
1183         // OEM_PAID network comes online.
1184         NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
1185                 buildOemManagedMobileState(IMSI_1, false,
1186                 new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
1187         mockNetworkStatsSummary(buildEmptyStats());
1188         mockNetworkStatsUidDetail(buildEmptyStats());
1189         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1190                 new UnderlyingNetworkInfo[0]);
1191 
1192         // Create some traffic.
1193         incrementCurrentTime(MINUTE_IN_MILLIS);
1194         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1195                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1196                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 36L, 41L, 24L, 96L, 0L)));
1197         forcePollAndWaitForIdle();
1198 
1199         // OEM_PRIVATE network comes online.
1200         states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
1201                 new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})};
1202         mockNetworkStatsSummary(buildEmptyStats());
1203         mockNetworkStatsUidDetail(buildEmptyStats());
1204         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1205                 new UnderlyingNetworkInfo[0]);
1206 
1207         // Create some traffic.
1208         incrementCurrentTime(MINUTE_IN_MILLIS);
1209         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1210                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1211                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 49L, 71L, 72L, 48L, 0L)));
1212         forcePollAndWaitForIdle();
1213 
1214         // OEM_PAID + OEM_PRIVATE network comes online.
1215         states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
1216                 new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
1217                           NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
1218         mockNetworkStatsSummary(buildEmptyStats());
1219         mockNetworkStatsUidDetail(buildEmptyStats());
1220         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1221                 new UnderlyingNetworkInfo[0]);
1222 
1223         // Create some traffic.
1224         incrementCurrentTime(MINUTE_IN_MILLIS);
1225         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1226                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1227                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 57L, 86L, 83L, 93L, 0L)));
1228         forcePollAndWaitForIdle();
1229 
1230         // OEM_NONE network comes online.
1231         states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
1232         mockNetworkStatsSummary(buildEmptyStats());
1233         mockNetworkStatsUidDetail(buildEmptyStats());
1234         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1235                 new UnderlyingNetworkInfo[0]);
1236 
1237         // Create some traffic.
1238         incrementCurrentTime(MINUTE_IN_MILLIS);
1239         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1240                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1241                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 29L, 73L, 34L, 31L, 0L)));
1242         forcePollAndWaitForIdle();
1243 
1244         // Verify OEM_PAID template gets only relevant stats.
1245         assertUidTotal(templateOemPaid, UID_RED, 36L, 41L, 24L, 96L, 0);
1246 
1247         // Verify OEM_PRIVATE template gets only relevant stats.
1248         assertUidTotal(templateOemPrivate, UID_RED, 49L, 71L, 72L, 48L, 0);
1249 
1250         // Verify OEM_PAID + OEM_PRIVATE template gets only relevant stats.
1251         assertUidTotal(templateOemAll, UID_RED, 57L, 86L, 83L, 93L, 0);
1252 
1253         // Verify OEM_NONE sees only non-OEM managed stats.
1254         assertUidTotal(templateOemNone, UID_RED, 29L, 73L, 34L, 31L, 0);
1255 
1256         // Verify OEM_MANAGED_YES sees all OEM managed stats.
1257         assertUidTotal(templateOemYes, UID_RED,
1258                 36L + 49L + 57L,
1259                 41L + 71L + 86L,
1260                 24L + 72L + 83L,
1261                 96L + 48L + 93L, 0);
1262 
1263         // Verify ALL_MOBILE template gets both OEM managed and non-OEM managed stats.
1264         assertUidTotal(sTemplateImsi1, UID_RED,
1265                 36L + 49L + 57L + 29L,
1266                 41L + 71L + 86L + 73L,
1267                 24L + 72L + 83L + 34L,
1268                 96L + 48L + 93L + 31L, 0);
1269     }
1270 
1271     // TODO: support per IMSI state
setMobileRatTypeAndWaitForIdle(int ratType)1272     private void setMobileRatTypeAndWaitForIdle(int ratType) {
1273         doReturn(ratType).when(mNetworkStatsSubscriptionsMonitor)
1274                 .getRatTypeForSubscriberId(anyString());
1275         mService.handleOnCollapsedRatTypeChanged();
1276         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
1277     }
1278 
1279     @Test
testSummaryForAllUid()1280     public void testSummaryForAllUid() throws Exception {
1281         // pretend that network comes online
1282         mockDefaultSettings();
1283         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
1284         mockNetworkStatsSummary(buildEmptyStats());
1285         mockNetworkStatsUidDetail(buildEmptyStats());
1286 
1287         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1288                 new UnderlyingNetworkInfo[0]);
1289 
1290         // create some traffic for two apps
1291         incrementCurrentTime(HOUR_IN_MILLIS);
1292         mockDefaultSettings();
1293         mockNetworkStatsSummary(buildEmptyStats());
1294         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1295                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
1296                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
1297                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
1298         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
1299 
1300         forcePollAndWaitForIdle();
1301 
1302         // verify service recorded history
1303         assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
1304         assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
1305 
1306 
1307         // now create more traffic in next hour, but only for one app
1308         incrementCurrentTime(HOUR_IN_MILLIS);
1309         mockDefaultSettings();
1310         mockNetworkStatsSummary(buildEmptyStats());
1311         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1312                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
1313                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
1314                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
1315                         2048L, 16L, 1024L, 8L, 0L));
1316         forcePollAndWaitForIdle();
1317 
1318         // first verify entire history present
1319         NetworkStats stats = mSession.getSummaryForAllUid(
1320                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
1321         assertEquals(3, stats.size());
1322         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1323                 DEFAULT_NETWORK_YES, 50L, 5L, 50L, 5L, 1);
1324         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
1325                 DEFAULT_NETWORK_YES, 10L, 1L, 10L, 1L, 1);
1326         assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1327                 DEFAULT_NETWORK_YES, 2048L, 16L, 1024L, 8L, 0);
1328 
1329         // now verify that recent history only contains one uid
1330         final long currentTime = currentTimeMillis();
1331         stats = mSession.getSummaryForAllUid(
1332                 sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
1333         assertEquals(1, stats.size());
1334         assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1335                 DEFAULT_NETWORK_YES, 1024L, 8L, 512L, 4L, 0);
1336     }
1337 
1338     @Test
testGetLatestSummary()1339     public void testGetLatestSummary() throws Exception {
1340         // Pretend that network comes online.
1341         mockDefaultSettings();
1342         NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{buildWifiState()};
1343         mockNetworkStatsSummary(buildEmptyStats());
1344         mockNetworkStatsUidDetail(buildEmptyStats());
1345 
1346         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1347                 new UnderlyingNetworkInfo[0]);
1348 
1349         // Increase arbitrary time which does not align to the bucket edge, create some traffic.
1350         incrementCurrentTime(1751000L);
1351         NetworkStats.Entry entry = new NetworkStats.Entry(
1352                 TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1353                 DEFAULT_NETWORK_NO, 50L, 5L, 51L, 1L, 3L);
1354         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1).insertEntry(entry));
1355         mockNetworkStatsUidDetail(buildEmptyStats());
1356         forcePollAndWaitForIdle();
1357 
1358         // Verify the mocked stats is returned by querying with the range of the latest bucket.
1359         final ZonedDateTime end =
1360                 ZonedDateTime.ofInstant(mClock.instant(), ZoneId.systemDefault());
1361         final ZonedDateTime start = end.truncatedTo(ChronoUnit.HOURS);
1362         NetworkStats stats = mSession.getSummaryForNetwork(
1363                 new NetworkTemplate.Builder(MATCH_WIFI)
1364                 .setWifiNetworkKeys(Set.of(TEST_WIFI_NETWORK_KEY)).build(),
1365                 start.toInstant().toEpochMilli(), end.toInstant().toEpochMilli());
1366         assertEquals(1, stats.size());
1367         assertValues(stats, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
1368                 DEFAULT_NETWORK_ALL, 50L, 5L, 51L, 1L, 3L);
1369 
1370         // For getHistoryIntervalForNetwork, only includes buckets that atomically occur in
1371         // the inclusive time range, instead of including the latest bucket. This behavior is
1372         // already documented publicly, refer to {@link NetworkStatsManager#queryDetails}.
1373     }
1374 
1375     @Test
testQueryTestNetworkUsage()1376     public void testQueryTestNetworkUsage() throws Exception {
1377         final NetworkTemplate templateTestAll = new NetworkTemplate.Builder(MATCH_TEST).build();
1378         final NetworkTemplate templateTestIface1 = new NetworkTemplate.Builder(MATCH_TEST)
1379                 .setWifiNetworkKeys(Set.of(TEST_IFACE)).build();
1380         final NetworkTemplate templateTestIface2 = new NetworkTemplate.Builder(MATCH_TEST)
1381                 .setWifiNetworkKeys(Set.of(TEST_IFACE2)).build();
1382         // Test networks might use interface as subscriberId to identify individual networks.
1383         // Simulate both cases.
1384         final NetworkStateSnapshot[] states =
1385                 new NetworkStateSnapshot[]{buildTestState(TEST_IFACE, TEST_IFACE),
1386                         buildTestState(TEST_IFACE2, null /* wifiNetworkKey */)};
1387 
1388         // Test networks comes online.
1389         mockNetworkStatsSummary(buildEmptyStats());
1390         mockNetworkStatsUidDetail(buildEmptyStats());
1391         mService.notifyNetworkStatus(NETWORKS_TEST, states, getActiveIface(states),
1392                 new UnderlyingNetworkInfo[0]);
1393 
1394         // Create some traffic on both interfaces.
1395         incrementCurrentTime(MINUTE_IN_MILLIS);
1396         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1397                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
1398                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L))
1399                 .addEntry(new NetworkStats.Entry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE,
1400                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7L, 3L, 5L, 1L, 1L)));
1401         forcePollAndWaitForIdle();
1402 
1403         // Verify test network templates gets stats. Stats of test networks without subscriberId
1404         // can only be matched by templates without subscriberId requirement.
1405         assertUidTotal(templateTestAll, UID_RED, 19L, 21L, 19L, 2L, 1);
1406         assertUidTotal(templateTestIface1, UID_RED, 12L, 18L, 14L, 1L, 0);
1407         assertUidTotal(templateTestIface2, UID_RED, 0L, 0L, 0L, 0L, 0);
1408     }
1409 
1410     @Test
testUidStatsForTransport()1411     public void testUidStatsForTransport() throws Exception {
1412         // Setup both wifi and mobile networks, and set mobile network as the default interface.
1413         mockDefaultSettings();
1414         mockNetworkStatsUidDetail(buildEmptyStats());
1415 
1416         final NetworkStateSnapshot mobileState = buildStateOfTransport(
1417                 NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
1418                 TEST_IFACE2, IMSI_1, null /* wifiNetworkKey */,
1419                 false /* isTemporarilyNotMetered */, false /* isRoaming */);
1420 
1421         final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
1422                 mobileState, buildWifiState(false, TEST_IFACE, null),
1423                 buildWifiState(false, TEST_IFACE3, null)};
1424         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1425                 new UnderlyingNetworkInfo[0]);
1426         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
1427 
1428         // Mock traffic on wifi network.
1429         final NetworkStats.Entry entry1 = new NetworkStats.Entry(
1430                 TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1431                 DEFAULT_NETWORK_NO, 50L, 5L, 50L, 5L, 1L);
1432         final NetworkStats.Entry entry2 = new NetworkStats.Entry(
1433                 TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
1434                 DEFAULT_NETWORK_NO, 50L, 5L, 50L, 5L, 1L);
1435         final NetworkStats.Entry entry3 = new NetworkStats.Entry(
1436                 TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xBEEF, METERED_NO, ROAMING_NO,
1437                 DEFAULT_NETWORK_NO, 1024L, 8L, 512L, 4L, 2L);
1438         // Add an entry that with different wifi interface, but expected to be merged into entry3
1439         // after clearing interface information.
1440         final NetworkStats.Entry entry4 = new NetworkStats.Entry(
1441                 TEST_IFACE3, UID_BLUE, SET_DEFAULT, 0xBEEF, METERED_NO, ROAMING_NO,
1442                 DEFAULT_NETWORK_NO, 1L, 2L, 3L, 4L, 5L);
1443 
1444         final TetherStatsParcel[] emptyTetherStats = {};
1445         // The interfaces that expect to be used to query the stats.
1446         final String[] wifiIfaces = {TEST_IFACE, TEST_IFACE3};
1447         incrementCurrentTime(HOUR_IN_MILLIS);
1448         mockDefaultSettings();
1449         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
1450                 .insertEntry(entry1)
1451                 .insertEntry(entry2)
1452                 .insertEntry(entry3)
1453                 .insertEntry(entry4), emptyTetherStats, wifiIfaces);
1454 
1455         // getUidStatsForTransport (through getNetworkStatsUidDetail) adds all operation counts
1456         // with active interface, and the interface here is mobile interface, so this test makes
1457         // sure these operations are not surfaced in getUidStatsForTransport if the transport
1458         // doesn't match them.
1459         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
1460         final NetworkStats wifiStats = mService.getUidStatsForTransport(
1461                 NetworkCapabilities.TRANSPORT_WIFI);
1462 
1463         assertEquals(3, wifiStats.size());
1464         // The iface field of the returned stats should be null because getUidStatsForTransport
1465         // clears the interface fields before it returns the result.
1466         assertValues(wifiStats, null /* iface */, UID_RED, SET_DEFAULT, TAG_NONE,
1467                 METERED_NO, ROAMING_NO, METERED_NO, 50L, 5L, 50L, 5L, 1L);
1468         assertValues(wifiStats, null /* iface */, UID_RED, SET_DEFAULT, 0xF00D,
1469                 METERED_NO, ROAMING_NO, METERED_NO, 50L, 5L, 50L, 5L, 1L);
1470         assertValues(wifiStats, null /* iface */, UID_BLUE, SET_DEFAULT, 0xBEEF,
1471                 METERED_NO, ROAMING_NO, METERED_NO, 1025L, 10L, 515L, 8L, 7L);
1472 
1473         final String[] mobileIfaces = {TEST_IFACE2};
1474         mockNetworkStatsUidDetail(buildEmptyStats(), emptyTetherStats, mobileIfaces);
1475         final NetworkStats mobileStats = mService.getUidStatsForTransport(
1476                 NetworkCapabilities.TRANSPORT_CELLULAR);
1477 
1478         assertEquals(2, mobileStats.size());
1479         // Verify the operation count stats that caused by incrementOperationCount only appears
1480         // on the mobile interface since incrementOperationCount attributes them onto the active
1481         // interface.
1482         assertValues(mobileStats, null /* iface */, UID_RED, SET_DEFAULT, 0xF00D,
1483                 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 1);
1484         assertValues(mobileStats, null /* iface */, UID_RED, SET_DEFAULT, TAG_NONE,
1485                 METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 1);
1486     }
1487 
1488     @Test
testGetUidStatsForTransportWithCellularAndSatellite()1489     public void testGetUidStatsForTransportWithCellularAndSatellite() throws Exception {
1490         // Setup satellite mobile network and Cellular mobile network
1491         mockDefaultSettings();
1492         mockNetworkStatsUidDetail(buildEmptyStats());
1493 
1494         final NetworkStateSnapshot mobileState = buildStateOfTransport(
1495                 NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
1496                 TEST_IFACE2, IMSI_1, null /* wifiNetworkKey */,
1497                 false /* isTemporarilyNotMetered */, false /* isRoaming */);
1498 
1499         final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{mobileState,
1500                 buildSatelliteMobileState(IMSI_1)};
1501         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1502                 new UnderlyingNetworkInfo[0]);
1503         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
1504 
1505         // mock traffic on satellite network
1506         final NetworkStats.Entry entrySatellite = new NetworkStats.Entry(
1507                 TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1508                 DEFAULT_NETWORK_NO, 80L, 5L, 70L, 15L, 1L);
1509 
1510         // mock traffic on cellular network
1511         final NetworkStats.Entry entryCellular = new NetworkStats.Entry(
1512                 TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1513                 DEFAULT_NETWORK_NO, 100L, 15L, 150L, 15L, 1L);
1514 
1515         final TetherStatsParcel[] emptyTetherStats = {};
1516         // The interfaces that expect to be used to query the stats.
1517         final String[] mobileIfaces = {TEST_IFACE, TEST_IFACE2};
1518         incrementCurrentTime(HOUR_IN_MILLIS);
1519         mockDefaultSettings();
1520         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
1521                 .insertEntry(entrySatellite).insertEntry(entryCellular), emptyTetherStats,
1522                 mobileIfaces);
1523         // with getUidStatsForTransport(TRANSPORT_CELLULAR) return stats of both cellular
1524         // and satellite
1525         final NetworkStats mobileStats = mService.getUidStatsForTransport(
1526                 NetworkCapabilities.TRANSPORT_CELLULAR);
1527 
1528         // The iface field of the returned stats should be null because getUidStatsForTransport
1529         // clears the interface field before it returns the result.
1530         assertValues(mobileStats, null /* iface */, UID_RED, SET_DEFAULT, TAG_NONE,
1531                 METERED_NO, ROAMING_NO, METERED_NO, 180L, 20L, 220L, 30L, 2L);
1532 
1533         // getUidStatsForTransport(TRANSPORT_SATELLITE) is not supported
1534         assertThrows(IllegalArgumentException.class,
1535                 () -> mService.getUidStatsForTransport(NetworkCapabilities.TRANSPORT_SATELLITE));
1536 
1537     }
1538 
1539     @Test
testForegroundBackground()1540     public void testForegroundBackground() throws Exception {
1541         // pretend that network comes online
1542         mockDefaultSettings();
1543         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
1544         mockNetworkStatsSummary(buildEmptyStats());
1545         mockNetworkStatsUidDetail(buildEmptyStats());
1546 
1547         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1548                 new UnderlyingNetworkInfo[0]);
1549 
1550         // create some initial traffic
1551         incrementCurrentTime(HOUR_IN_MILLIS);
1552         mockDefaultSettings();
1553         mockNetworkStatsSummary(buildEmptyStats());
1554         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1555                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
1556                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
1557         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
1558 
1559         forcePollAndWaitForIdle();
1560 
1561         // verify service recorded history
1562         assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
1563 
1564 
1565         // now switch to foreground
1566         incrementCurrentTime(HOUR_IN_MILLIS);
1567         mockDefaultSettings();
1568         mockNetworkStatsSummary(buildEmptyStats());
1569         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1570                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
1571                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
1572                 .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
1573                 .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
1574         mService.noteUidForeground(UID_RED, true);
1575         verify(mUidCounterSetMap).updateEntry(
1576                 eq(new S32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
1577         mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
1578 
1579         forcePollAndWaitForIdle();
1580 
1581         // test that we combined correctly
1582         assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2);
1583 
1584         // verify entire history present
1585         final NetworkStats stats = mSession.getSummaryForAllUid(
1586                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
1587         assertEquals(4, stats.size());
1588         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1589                 DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1);
1590         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
1591                 DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1);
1592         assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
1593                 DEFAULT_NETWORK_YES, 32L, 2L, 32L, 2L, 1);
1594         assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, METERED_NO, ROAMING_NO,
1595                 DEFAULT_NETWORK_YES, 1L, 1L, 1L, 1L, 1);
1596     }
1597 
1598     @Test
testMetered()1599     public void testMetered() throws Exception {
1600         // pretend that network comes online
1601         mockDefaultSettings();
1602         NetworkStateSnapshot[] states =
1603                 new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
1604         mockNetworkStatsSummary(buildEmptyStats());
1605         mockNetworkStatsUidDetail(buildEmptyStats());
1606 
1607         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1608                 new UnderlyingNetworkInfo[0]);
1609 
1610         // create some initial traffic
1611         incrementCurrentTime(HOUR_IN_MILLIS);
1612         mockDefaultSettings();
1613         mockNetworkStatsSummary(buildEmptyStats());
1614         // Note that all traffic from NetworkManagementService is tagged as METERED_NO, ROAMING_NO
1615         // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
1616         // We layer them on top by inspecting the iface properties.
1617         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1618                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1619                         DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
1620                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
1621                         DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
1622         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
1623 
1624         forcePollAndWaitForIdle();
1625 
1626         // verify service recorded history
1627         assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
1628         // verify entire history present
1629         final NetworkStats stats = mSession.getSummaryForAllUid(
1630                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
1631         assertEquals(2, stats.size());
1632         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
1633                 DEFAULT_NETWORK_YES,  128L, 2L, 128L, 2L, 1);
1634         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
1635                 DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1);
1636     }
1637 
1638     @Test
testRoaming()1639     public void testRoaming() throws Exception {
1640         // pretend that network comes online
1641         mockDefaultSettings();
1642         NetworkStateSnapshot[] states =
1643             new NetworkStateSnapshot[] {buildStateOfTransport(
1644                     NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
1645                     TEST_IFACE,  IMSI_1, null /* wifiNetworkKey */,
1646                     false /* isTemporarilyNotMetered */, true /* isRoaming */)};
1647         mockNetworkStatsSummary(buildEmptyStats());
1648         mockNetworkStatsUidDetail(buildEmptyStats());
1649 
1650         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1651                 new UnderlyingNetworkInfo[0]);
1652 
1653         // Create some traffic
1654         incrementCurrentTime(HOUR_IN_MILLIS);
1655         mockDefaultSettings();
1656         mockNetworkStatsSummary(buildEmptyStats());
1657         // Note that all traffic from NetworkManagementService is tagged as METERED_NO and
1658         // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
1659         // on top by inspecting the iface properties.
1660         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
1661                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
1662                         DEFAULT_NETWORK_YES,  128L, 2L, 128L, 2L, 0L)
1663                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
1664                         DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
1665         forcePollAndWaitForIdle();
1666 
1667         // verify service recorded history
1668         assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
1669 
1670         // verify entire history present
1671         final NetworkStats stats = mSession.getSummaryForAllUid(
1672                 sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
1673         assertEquals(2, stats.size());
1674         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_YES,
1675                 DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0);
1676         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_YES,
1677                 DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0);
1678     }
1679 
1680     @Test
testTethering()1681     public void testTethering() throws Exception {
1682         // pretend first mobile network comes online
1683         mockDefaultSettings();
1684         final NetworkStateSnapshot[] states =
1685                 new NetworkStateSnapshot[]{buildMobileState(IMSI_1)};
1686         mockNetworkStatsSummary(buildEmptyStats());
1687         mockNetworkStatsUidDetail(buildEmptyStats());
1688 
1689         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1690                 new UnderlyingNetworkInfo[0]);
1691 
1692         // create some tethering traffic
1693         incrementCurrentTime(HOUR_IN_MILLIS);
1694         mockDefaultSettings();
1695 
1696         // Register custom provider and retrieve callback.
1697         final TestableNetworkStatsProviderBinder provider =
1698                 new TestableNetworkStatsProviderBinder();
1699         final INetworkStatsProviderCallback cb =
1700                 mService.registerNetworkStatsProvider("TEST-TETHERING-OFFLOAD", provider);
1701         assertNotNull(cb);
1702         final long now = getElapsedRealtime();
1703 
1704         // Traffic seen by kernel counters (includes software tethering).
1705         final NetworkStats swIfaceStats = new NetworkStats(now, 1)
1706                 .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L);
1707         // Hardware tethering traffic, not seen by kernel counters.
1708         final NetworkStats tetherHwIfaceStats = new NetworkStats(now, 1)
1709                 .insertEntry(new NetworkStats.Entry(TEST_IFACE, UID_ALL, SET_DEFAULT,
1710                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
1711                         512L, 4L, 128L, 1L, 0L));
1712         final NetworkStats tetherHwUidStats = new NetworkStats(now, 1)
1713                 .insertEntry(new NetworkStats.Entry(TEST_IFACE, UID_TETHERING, SET_DEFAULT,
1714                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
1715                         512L, 4L, 128L, 1L, 0L));
1716         cb.notifyStatsUpdated(0 /* unused */, tetherHwIfaceStats, tetherHwUidStats);
1717 
1718         // Fake some traffic done by apps on the device (as opposed to tethering), and record it
1719         // into UID stats (as opposed to iface stats).
1720         final NetworkStats localUidStats = new NetworkStats(now, 1)
1721                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
1722         // Software per-uid tethering traffic.
1723         final TetherStatsParcel[] tetherStatsParcels =
1724                 {buildTetherStatsParcel(TEST_IFACE, 1408L, 10L, 256L, 1L, 0)};
1725 
1726         mockNetworkStatsSummary(swIfaceStats);
1727         mockNetworkStatsUidDetail(localUidStats, tetherStatsParcels, INTERFACES_ALL);
1728         forcePollAndWaitForIdle();
1729 
1730         // verify service recorded history
1731         assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
1732         assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
1733         assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
1734     }
1735 
1736     @Test
testRegisterUsageCallback()1737     public void testRegisterUsageCallback() throws Exception {
1738         // pretend that wifi network comes online; service should ask about full
1739         // network state, and poll any existing interfaces before updating.
1740         mockDefaultSettings();
1741         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
1742         mockNetworkStatsSummary(buildEmptyStats());
1743         mockNetworkStatsUidDetail(buildEmptyStats());
1744 
1745         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1746                 new UnderlyingNetworkInfo[0]);
1747 
1748         // verify service has empty history for wifi
1749         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
1750         long thresholdInBytes = 1L;  // very small; should be overriden by framework
1751         DataUsageRequest inputRequest = new DataUsageRequest(
1752                 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdInBytes);
1753 
1754         // Force poll
1755         mockDefaultSettings();
1756         mockNetworkStatsSummary(buildEmptyStats());
1757         mockNetworkStatsUidDetail(buildEmptyStats());
1758 
1759         // Register and verify request and that binder was called
1760         DataUsageRequest request = mService.registerUsageCallback(
1761                 mServiceContext.getPackageName(), inputRequest, mUsageCallback);
1762         assertTrue(request.requestId > 0);
1763         assertTrue(Objects.equals(sTemplateWifi, request.template));
1764         long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
1765         assertEquals(minThresholdInBytes, request.thresholdInBytes);
1766 
1767         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
1768 
1769         // Make sure that the caller binder gets connected
1770         verify(mUsageCallbackBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
1771 
1772         // modify some number on wifi, and trigger poll event
1773         // not enough traffic to call data usage callback
1774         incrementCurrentTime(HOUR_IN_MILLIS);
1775         mockDefaultSettings();
1776         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
1777                 .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
1778         mockNetworkStatsUidDetail(buildEmptyStats());
1779         forcePollAndWaitForIdle();
1780 
1781         // verify service recorded history
1782         assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
1783 
1784         // make sure callback has not being called
1785         mUsageCallback.assertNoCallback();
1786 
1787         // and bump forward again, with counters going higher. this is
1788         // important, since it will trigger the data usage callback
1789         incrementCurrentTime(DAY_IN_MILLIS);
1790         mockDefaultSettings();
1791         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
1792                 .insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
1793         mockNetworkStatsUidDetail(buildEmptyStats());
1794         forcePollAndWaitForIdle();
1795 
1796         // verify service recorded history
1797         assertNetworkTotal(sTemplateWifi, 4096000L, 4L, 8192000L, 8L, 0);
1798 
1799 
1800         // Wait for the caller to invoke expectOnThresholdReached.
1801         mUsageCallback.expectOnThresholdReached(request);
1802 
1803         // Allow binder to disconnect
1804         doReturn(true).when(mUsageCallbackBinder)
1805                 .unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
1806 
1807         // Unregister request
1808         mService.unregisterUsageRequest(request);
1809 
1810         // Wait for the caller to invoke expectOnCallbackReleased.
1811         mUsageCallback.expectOnCallbackReleased(request);
1812 
1813         // Make sure that the caller binder gets disconnected
1814         verify(mUsageCallbackBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
1815     }
1816 
1817     @Test
testUnregisterUsageCallback_unknown_noop()1818     public void testUnregisterUsageCallback_unknown_noop() throws Exception {
1819         String callingPackage = "the.calling.package";
1820         long thresholdInBytes = 10 * 1024 * 1024;  // 10 MB
1821         DataUsageRequest unknownRequest = new DataUsageRequest(
1822                 2 /* requestId */, sTemplateImsi1, thresholdInBytes);
1823 
1824         mService.unregisterUsageRequest(unknownRequest);
1825     }
1826 
1827     @Test
testStatsProviderUpdateStats()1828     public void testStatsProviderUpdateStats() throws Exception {
1829         // Pretend that network comes online.
1830         mockDefaultSettings();
1831         final NetworkStateSnapshot[] states =
1832                 new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
1833         mockNetworkStatsSummary(buildEmptyStats());
1834         mockNetworkStatsUidDetail(buildEmptyStats());
1835 
1836         // Register custom provider and retrieve callback.
1837         final TestableNetworkStatsProviderBinder provider =
1838                 new TestableNetworkStatsProviderBinder();
1839         final INetworkStatsProviderCallback cb =
1840                 mService.registerNetworkStatsProvider("TEST", provider);
1841         assertNotNull(cb);
1842 
1843         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1844                 new UnderlyingNetworkInfo[0]);
1845 
1846         // Verifies that one requestStatsUpdate will be called during iface update.
1847         provider.expectOnRequestStatsUpdate(0 /* unused */);
1848 
1849         // Create some initial traffic and report to the service.
1850         incrementCurrentTime(HOUR_IN_MILLIS);
1851         final NetworkStats expectedStats = new NetworkStats(0L, 1)
1852                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
1853                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
1854                         128L, 2L, 128L, 2L, 1L))
1855                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
1856                         0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
1857                         64L, 1L, 64L, 1L, 1L));
1858         cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats);
1859 
1860         // Make another empty mutable stats object. This is necessary since the new NetworkStats
1861         // object will be used to compare with the old one in NetworkStatsRecoder, two of them
1862         // cannot be the same object.
1863         mockNetworkStatsUidDetail(buildEmptyStats());
1864 
1865         forcePollAndWaitForIdle();
1866 
1867         // Verifies that one requestStatsUpdate and setAlert will be called during polling.
1868         provider.expectOnRequestStatsUpdate(0 /* unused */);
1869         provider.expectOnSetAlert(MB_IN_BYTES);
1870 
1871         // Verifies that service recorded history, does not verify uid tag part.
1872         assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
1873 
1874         // Verifies that onStatsUpdated updates the stats accordingly.
1875         final NetworkStats stats = mSession.getSummaryForAllUid(
1876                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
1877         assertEquals(2, stats.size());
1878         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
1879                 DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L);
1880         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
1881                 DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L);
1882 
1883         // Verifies that unregister the callback will remove the provider from service.
1884         cb.unregister();
1885         forcePollAndWaitForIdle();
1886         provider.assertNoCallback();
1887     }
1888 
1889     @Test
testDualVilteProviderStats()1890     public void testDualVilteProviderStats() throws Exception {
1891         // Pretend that network comes online.
1892         mockDefaultSettings();
1893         final int subId1 = 1;
1894         final int subId2 = 2;
1895         final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
1896                 buildImsState(IMSI_1, subId1, TEST_IFACE),
1897                 buildImsState(IMSI_2, subId2, TEST_IFACE2)};
1898         mockNetworkStatsSummary(buildEmptyStats());
1899         mockNetworkStatsUidDetail(buildEmptyStats());
1900 
1901         // Register custom provider and retrieve callback.
1902         final TestableNetworkStatsProviderBinder provider =
1903                 new TestableNetworkStatsProviderBinder();
1904         final INetworkStatsProviderCallback cb =
1905                 mService.registerNetworkStatsProvider("TEST", provider);
1906         assertNotNull(cb);
1907 
1908         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
1909                 new UnderlyingNetworkInfo[0]);
1910 
1911         // Verifies that one requestStatsUpdate will be called during iface update.
1912         provider.expectOnRequestStatsUpdate(0 /* unused */);
1913 
1914         // Create some initial traffic and report to the service.
1915         incrementCurrentTime(HOUR_IN_MILLIS);
1916         final String vtIface1 = NetworkStats.IFACE_VT + subId1;
1917         final String vtIface2 = NetworkStats.IFACE_VT + subId2;
1918         final NetworkStats expectedStats = new NetworkStats(0L, 1)
1919                 .addEntry(new NetworkStats.Entry(vtIface1, UID_RED, SET_DEFAULT,
1920                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
1921                         128L, 2L, 128L, 2L, 1L))
1922                 .addEntry(new NetworkStats.Entry(vtIface2, UID_RED, SET_DEFAULT,
1923                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
1924                         64L, 1L, 64L, 1L, 1L));
1925         cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats);
1926 
1927         // Make another empty mutable stats object. This is necessary since the new NetworkStats
1928         // object will be used to compare with the old one in NetworkStatsRecoder, two of them
1929         // cannot be the same object.
1930         mockNetworkStatsUidDetail(buildEmptyStats());
1931 
1932         forcePollAndWaitForIdle();
1933 
1934         // Verifies that one requestStatsUpdate and setAlert will be called during polling.
1935         provider.expectOnRequestStatsUpdate(0 /* unused */);
1936         provider.expectOnSetAlert(MB_IN_BYTES);
1937 
1938         // Verifies that service recorded history, does not verify uid tag part.
1939         assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 1);
1940 
1941         // Verifies that onStatsUpdated updates the stats accordingly.
1942         NetworkStats stats = mSession.getSummaryForAllUid(
1943                 sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
1944         assertEquals(1, stats.size());
1945         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
1946                 DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L);
1947 
1948         stats = mSession.getSummaryForAllUid(
1949                 sTemplateImsi2, Long.MIN_VALUE, Long.MAX_VALUE, true);
1950         assertEquals(1, stats.size());
1951         assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
1952                 DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L);
1953 
1954         // Verifies that unregister the callback will remove the provider from service.
1955         cb.unregister();
1956         forcePollAndWaitForIdle();
1957         provider.assertNoCallback();
1958     }
1959 
1960     @Test
testStatsProviderSetAlert()1961     public void testStatsProviderSetAlert() throws Exception {
1962         // Pretend that network comes online.
1963         mockDefaultSettings();
1964         NetworkStateSnapshot[] states =
1965                 new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
1966         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
1967                 new UnderlyingNetworkInfo[0]);
1968 
1969         // Register custom provider and retrieve callback.
1970         final TestableNetworkStatsProviderBinder provider =
1971                 new TestableNetworkStatsProviderBinder();
1972         final INetworkStatsProviderCallback cb =
1973                 mService.registerNetworkStatsProvider("TEST", provider);
1974         assertNotNull(cb);
1975 
1976         // Simulates alert quota of the provider has been reached.
1977         cb.notifyAlertReached();
1978         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
1979 
1980         // Verifies that polling is triggered by alert reached.
1981         provider.expectOnRequestStatsUpdate(0 /* unused */);
1982         // Verifies that global alert will be re-armed.
1983         provider.expectOnSetAlert(MB_IN_BYTES);
1984     }
1985 
setCombineSubtypeEnabled(boolean enable)1986     private void setCombineSubtypeEnabled(boolean enable) {
1987         mSettings.setCombineSubtypeEnabled(enable);
1988         mHandler.post(() -> mContentObserver.onChange(false, Settings.Global
1989                     .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED)));
1990         waitForIdle();
1991         if (enable) {
1992             verify(mNetworkStatsSubscriptionsMonitor).stop();
1993         } else {
1994             verify(mNetworkStatsSubscriptionsMonitor).start();
1995         }
1996     }
1997 
1998     @Test
testDynamicWatchForNetworkRatTypeChanges()1999     public void testDynamicWatchForNetworkRatTypeChanges() throws Exception {
2000         // Build 3G template, type unknown template to get stats while network type is unknown
2001         // and type all template to get the sum of all network type stats.
2002         final NetworkTemplate template3g = new NetworkTemplate.Builder(MATCH_MOBILE)
2003                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
2004                 .setMeteredness(METERED_YES).build();
2005         final NetworkTemplate templateUnknown = new NetworkTemplate.Builder(MATCH_MOBILE)
2006                 .setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN)
2007                 .setMeteredness(METERED_YES).build();
2008         final NetworkTemplate templateAll = new NetworkTemplate.Builder(MATCH_MOBILE)
2009                 .setMeteredness(METERED_YES).build();
2010         final NetworkStateSnapshot[] states =
2011                 new NetworkStateSnapshot[]{buildMobileState(IMSI_1)};
2012 
2013         mockNetworkStatsSummary(buildEmptyStats());
2014         mockNetworkStatsUidDetail(buildEmptyStats());
2015 
2016         // 3G network comes online.
2017         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
2018         mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
2019                 new UnderlyingNetworkInfo[0]);
2020 
2021         // Create some traffic.
2022         incrementCurrentTime(MINUTE_IN_MILLIS);
2023         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
2024                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
2025                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L)));
2026         forcePollAndWaitForIdle();
2027 
2028         // Since CombineSubtypeEnabled is false by default in unit test, the generated traffic
2029         // will be split by RAT type. Verify 3G templates gets stats, while template with unknown
2030         // RAT type gets nothing, and template with NETWORK_TYPE_ALL gets all stats.
2031         assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
2032         assertUidTotal(templateUnknown, UID_RED, 0L, 0L, 0L, 0L, 0);
2033         assertUidTotal(templateAll, UID_RED, 12L, 18L, 14L, 1L, 0);
2034 
2035         // Stop monitoring data usage per RAT type changes NetworkStatsService records data
2036         // to {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}.
2037         setCombineSubtypeEnabled(true);
2038 
2039         // Call handleOnCollapsedRatTypeChanged manually to simulate the callback fired
2040         // when stopping monitor, this is needed by NetworkStatsService to trigger
2041         // handleNotifyNetworkStatus.
2042         mService.handleOnCollapsedRatTypeChanged();
2043         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
2044         // Create some traffic.
2045         incrementCurrentTime(MINUTE_IN_MILLIS);
2046         // Append more traffic on existing snapshot.
2047         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
2048                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
2049                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L + 4L, 18L + 4L, 14L + 3L,
2050                         1L + 1L, 0L))
2051                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
2052                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 35L, 29L, 7L, 11L, 1L)));
2053         forcePollAndWaitForIdle();
2054 
2055         // Verify 3G counters do not increase, while template with unknown RAT type gets new
2056         // traffic and template with NETWORK_TYPE_ALL gets all stats.
2057         assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
2058         assertUidTotal(templateUnknown, UID_RED, 4L + 35L, 4L + 29L, 3L + 7L, 1L + 11L, 1);
2059         assertUidTotal(templateAll, UID_RED, 16L + 35L, 22L + 29L, 17L + 7L, 2L + 11L, 1);
2060 
2061         // Start monitoring data usage per RAT type changes and NetworkStatsService records data
2062         // by a granular subtype representative of the actual subtype
2063         setCombineSubtypeEnabled(false);
2064 
2065         mService.handleOnCollapsedRatTypeChanged();
2066         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
2067         // Create some traffic.
2068         incrementCurrentTime(MINUTE_IN_MILLIS);
2069         // Append more traffic on existing snapshot.
2070         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
2071                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
2072                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 22L, 26L, 19L, 5L, 0L))
2073                 .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
2074                         METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 35L, 29L, 7L, 11L, 1L)));
2075         forcePollAndWaitForIdle();
2076 
2077         // Verify traffic is split by RAT type, no increase on template with unknown RAT type
2078         // and template with NETWORK_TYPE_ALL gets all stats.
2079         assertUidTotal(template3g, UID_RED, 6L + 12L , 4L + 18L, 2L + 14L, 3L + 1L, 0);
2080         assertUidTotal(templateUnknown, UID_RED, 4L + 35L, 4L + 29L, 3L + 7L, 1L + 11L, 1);
2081         assertUidTotal(templateAll, UID_RED, 22L + 35L, 26L + 29L, 19L + 7L, 5L + 11L, 1);
2082     }
2083 
2084     @Test
testOperationCount_nonDefault_traffic()2085     public void testOperationCount_nonDefault_traffic() throws Exception {
2086         // Pretend mobile network comes online, but wifi is the default network.
2087         mockDefaultSettings();
2088         NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
2089                 buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobileState(IMSI_1)};
2090         mockNetworkStatsUidDetail(buildEmptyStats());
2091         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
2092                 new UnderlyingNetworkInfo[0]);
2093 
2094         // Create some traffic on mobile network.
2095         incrementCurrentTime(HOUR_IN_MILLIS);
2096         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
2097                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
2098                         DEFAULT_NETWORK_NO, 2L, 1L, 3L, 4L, 0L)
2099                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
2100                         DEFAULT_NETWORK_YES, 1L, 3L, 2L, 1L, 0L)
2101                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 5L, 4L, 1L, 4L, 0L));
2102         // Increment operation count, which must have a specific tag.
2103         mService.incrementOperationCount(UID_RED, 0xF00D, 2);
2104         forcePollAndWaitForIdle();
2105 
2106         // Verify mobile summary is not changed by the operation count.
2107         final NetworkTemplate templateMobile = new NetworkTemplate.Builder(MATCH_MOBILE)
2108                 .setMeteredness(METERED_YES).build();
2109         final NetworkStats statsMobile = mSession.getSummaryForAllUid(
2110                 templateMobile, Long.MIN_VALUE, Long.MAX_VALUE, true);
2111         assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
2112                 DEFAULT_NETWORK_ALL, 3L, 4L, 5L, 5L, 0);
2113         assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL,
2114                 DEFAULT_NETWORK_ALL, 5L, 4L, 1L, 4L, 0);
2115 
2116         // Verify the operation count is blamed onto the default network.
2117         // TODO: Blame onto the default network is not very reasonable. Consider blame onto the
2118         //  network that generates the traffic.
2119         final NetworkTemplate templateWifi = new NetworkTemplate.Builder(MATCH_WIFI).build();
2120         final NetworkStats statsWifi = mSession.getSummaryForAllUid(
2121                 templateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
2122         assertValues(statsWifi, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL,
2123                 DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 2);
2124     }
2125 
2126     @Test
testTetheringEventCallback_onUpstreamChanged()2127     public void testTetheringEventCallback_onUpstreamChanged() throws Exception {
2128         // Register custom provider and retrieve callback.
2129         final TestableNetworkStatsProviderBinder provider =
2130                 new TestableNetworkStatsProviderBinder();
2131         final INetworkStatsProviderCallback cb =
2132                 mService.registerNetworkStatsProvider("TEST-TETHERING-OFFLOAD", provider);
2133         assertNotNull(cb);
2134         provider.assertNoCallback();
2135 
2136         // Post upstream changed event, verify the service will pull for stats.
2137         mTetheringEventCallback.onUpstreamChanged(WIFI_NETWORK);
2138         provider.expectOnRequestStatsUpdate(0 /* unused */);
2139     }
2140 
2141     /**
2142      * Verify the service will throw exceptions if the template is location sensitive but
2143      * the permission is not granted.
2144      */
2145     @Test
testEnforceTemplateLocationPermission()2146     public void testEnforceTemplateLocationPermission() throws Exception {
2147         doReturn(false).when(mLocationPermissionChecker)
2148                 .checkCallersLocationPermission(any(), any(), anyInt(), anyBoolean(), any());
2149         initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
2150         assertThrows(SecurityException.class, () ->
2151                 assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0));
2152         // Templates w/o wifi network keys can query stats as usual.
2153         assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
2154         assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
2155         // Templates for test network does not need to enforce location permission.
2156         final NetworkTemplate templateTestIface1 = new NetworkTemplate.Builder(MATCH_TEST)
2157                 .setWifiNetworkKeys(Set.of(TEST_IFACE)).build();
2158         assertNetworkTotal(templateTestIface1, 0L, 0L, 0L, 0L, 0);
2159 
2160         doReturn(true).when(mLocationPermissionChecker)
2161                 .checkCallersLocationPermission(any(), any(), anyInt(), anyBoolean(), any());
2162         assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
2163         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
2164         assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
2165         assertNetworkTotal(templateTestIface1, 0L, 0L, 0L, 0L, 0);
2166     }
2167 
2168     /**
2169      * Verify the service will perform data migration process can be controlled by the device flag.
2170      */
2171     @Test
testDataMigration()2172     public void testDataMigration() throws Exception {
2173         assertStatsFilesExist(false);
2174         mockDefaultSettings();
2175 
2176         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
2177 
2178         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
2179                 new UnderlyingNetworkInfo[0]);
2180 
2181         // modify some number on wifi, and trigger poll event
2182         incrementCurrentTime(HOUR_IN_MILLIS);
2183         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
2184                 .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
2185         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
2186                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
2187                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
2188                 .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
2189                 .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
2190                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
2191 
2192         mService.noteUidForeground(UID_RED, false);
2193         verify(mUidCounterSetMap, never()).deleteEntry(any());
2194         mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
2195         mService.noteUidForeground(UID_RED, true);
2196         verify(mUidCounterSetMap).updateEntry(
2197                 eq(new S32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
2198         mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
2199 
2200         forcePollAndWaitForIdle();
2201         // Simulate shutdown to force persisting data
2202         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
2203         assertStatsFilesExist(true);
2204 
2205         // Move the files to the legacy directory to simulate an import from old data
2206         for (File f : mStatsDir.listFiles()) {
2207             Files.move(f.toPath(), mLegacyStatsDir.toPath().resolve(f.getName()));
2208         }
2209         assertStatsFilesExist(false);
2210 
2211         // Fetch the stats from the legacy files and set platform stats collection to be identical
2212         mPlatformNetworkStatsCollection.put(PREFIX_DEV,
2213                 getLegacyCollection(PREFIX_DEV, false /* includeTags */));
2214         mPlatformNetworkStatsCollection.put(PREFIX_XT,
2215                 getLegacyCollection(PREFIX_XT, false /* includeTags */));
2216         mPlatformNetworkStatsCollection.put(PREFIX_UID,
2217                 getLegacyCollection(PREFIX_UID, false /* includeTags */));
2218         mPlatformNetworkStatsCollection.put(PREFIX_UID_TAG,
2219                 getLegacyCollection(PREFIX_UID_TAG, true /* includeTags */));
2220 
2221         // Mock zero usage and boot through serviceReady(), verify there is no imported data.
2222         prepareForSystemReady();
2223         mService.systemReady();
2224         assertStatsFilesExist(false);
2225 
2226         // Set the flag and reboot, verify the imported data is not there until next boot.
2227         mStoreFilesInApexData = true;
2228         mImportLegacyTargetAttempts = 3;
2229         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
2230         assertStatsFilesExist(false);
2231 
2232         // Boot through systemReady() again.
2233         prepareForSystemReady();
2234         mService.systemReady();
2235 
2236         // After systemReady(), the service should have historical stats loaded again.
2237         // Thus, verify
2238         //  1. The stats are absorbed by the recorder.
2239         //  2. The imported data are persisted.
2240         //  3. The attempts count is set to target attempts count to indicate a successful
2241         //     migration.
2242         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
2243         assertStatsFilesExist(true);
2244         verify(mImportLegacyAttemptsCounter).set(3);
2245         verify(mImportLegacySuccessesCounter).set(1);
2246 
2247         // TODO: Verify upgrading with Exception won't damege original data and
2248         //  will decrease the retry counter by 1.
2249     }
2250 
2251     @Test
testDataMigration_differentFromFallback()2252     public void testDataMigration_differentFromFallback() throws Exception {
2253         assertStatsFilesExist(false);
2254         mockDefaultSettings();
2255 
2256         NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{buildWifiState()};
2257 
2258         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
2259                 new UnderlyingNetworkInfo[0]);
2260 
2261         // modify some number on wifi, and trigger poll event
2262         incrementCurrentTime(HOUR_IN_MILLIS);
2263         mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
2264                 .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
2265         mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
2266                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
2267         forcePollAndWaitForIdle();
2268         // Simulate shutdown to force persisting data
2269         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
2270         assertStatsFilesExist(true);
2271 
2272         // Move the files to the legacy directory to simulate an import from old data
2273         for (File f : mStatsDir.listFiles()) {
2274             Files.move(f.toPath(), mLegacyStatsDir.toPath().resolve(f.getName()));
2275         }
2276         assertStatsFilesExist(false);
2277 
2278         // Prepare some unexpected data.
2279         final NetworkIdentity testWifiIdent = new NetworkIdentity.Builder().setType(TYPE_WIFI)
2280                 .setWifiNetworkKey(TEST_WIFI_NETWORK_KEY).build();
2281         final NetworkStatsCollection.Key unexpectedUidAllkey = new NetworkStatsCollection.Key(
2282                 Set.of(testWifiIdent), UID_ALL, SET_DEFAULT, 0);
2283         final NetworkStatsCollection.Key unexpectedUidBluekey = new NetworkStatsCollection.Key(
2284                 Set.of(testWifiIdent), UID_BLUE, SET_DEFAULT, 0);
2285         final NetworkStatsHistory unexpectedHistory = new NetworkStatsHistory
2286                 .Builder(965L /* bucketDuration */, 1)
2287                 .addEntry(new NetworkStatsHistory.Entry(TEST_START, 3L, 55L, 4L, 31L, 10L, 5L))
2288                 .build();
2289 
2290         // Simulate the platform stats collection somehow is different from what is read from
2291         // the fallback method. The service should read them as is. This usually happens when an
2292         // OEM has changed the implementation of NetworkStatsDataMigrationUtils inside the platform.
2293         final NetworkStatsCollection summaryCollection =
2294                 getLegacyCollection(PREFIX_XT, false /* includeTags */);
2295         summaryCollection.recordHistory(unexpectedUidAllkey, unexpectedHistory);
2296         final NetworkStatsCollection uidCollection =
2297                 getLegacyCollection(PREFIX_UID, false /* includeTags */);
2298         uidCollection.recordHistory(unexpectedUidBluekey, unexpectedHistory);
2299         mPlatformNetworkStatsCollection.put(PREFIX_DEV, summaryCollection);
2300         mPlatformNetworkStatsCollection.put(PREFIX_XT, summaryCollection);
2301         mPlatformNetworkStatsCollection.put(PREFIX_UID, uidCollection);
2302         mPlatformNetworkStatsCollection.put(PREFIX_UID_TAG,
2303                 getLegacyCollection(PREFIX_UID_TAG, true /* includeTags */));
2304 
2305         // Mock zero usage and boot through serviceReady(), verify there is no imported data.
2306         prepareForSystemReady();
2307         mService.systemReady();
2308         assertStatsFilesExist(false);
2309 
2310         // Set the flag and reboot, verify the imported data is not there until next boot.
2311         mStoreFilesInApexData = true;
2312         mImportLegacyTargetAttempts = 3;
2313         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
2314         assertStatsFilesExist(false);
2315 
2316         // Boot through systemReady() again.
2317         prepareForSystemReady();
2318         mService.systemReady();
2319 
2320         // Verify the result read from public API matches the result returned from the importer.
2321         assertNetworkTotal(sTemplateWifi, 1024L + 55L, 8L + 4L, 2048L + 31L, 16L + 10L, 0 + 5);
2322         assertUidTotal(sTemplateWifi, UID_BLUE,
2323                 128L + 55L, 1L + 4L, 128L + 31L, 1L + 10L, 0 + 5);
2324         assertStatsFilesExist(true);
2325         verify(mImportLegacyAttemptsCounter).set(3);
2326         verify(mImportLegacySuccessesCounter).set(1);
2327     }
2328 
2329     @Test
testShouldRunComparison()2330     public void testShouldRunComparison() {
2331         for (Boolean isDebuggable : Set.of(Boolean.TRUE, Boolean.FALSE)) {
2332             mIsDebuggable = isDebuggable;
2333             // Verify return false regardless of the device is debuggable.
2334             doReturn(0).when(mResources)
2335                     .getInteger(R.integer.config_netstats_validate_import);
2336             assertShouldRunComparison(false, isDebuggable);
2337             // Verify return true regardless of the device is debuggable.
2338             doReturn(1).when(mResources)
2339                     .getInteger(R.integer.config_netstats_validate_import);
2340             assertShouldRunComparison(true, isDebuggable);
2341             // Verify return true iff the device is debuggable.
2342             for (int testValue : Set.of(-1, 2)) {
2343                 doReturn(testValue).when(mResources)
2344                         .getInteger(R.integer.config_netstats_validate_import);
2345                 assertShouldRunComparison(isDebuggable, isDebuggable);
2346             }
2347         }
2348     }
2349 
2350     @Test
testAdoptFastDataInput_featureDisabled()2351     public void testAdoptFastDataInput_featureDisabled() throws Exception {
2352         // Boot through serviceReady() with flag disabled, verify the persistent
2353         // counters are not increased.
2354         mFastDataInputTargetAttempts = 0;
2355         doReturn(0).when(mFastDataInputSuccessesCounter).get();
2356         doReturn(0).when(mFastDataInputFallbacksCounter).get();
2357         mService.systemReady();
2358         verify(mFastDataInputSuccessesCounter, never()).set(anyInt());
2359         verify(mFastDataInputFallbacksCounter, never()).set(anyInt());
2360         assertEquals(0, mDeps.getCompareStatsInvocation());
2361     }
2362 
2363     @Test
testAdoptFastDataInput_noRetryAfterFail()2364     public void testAdoptFastDataInput_noRetryAfterFail() throws Exception {
2365         // Boot through serviceReady(), verify the service won't retry unexpectedly
2366         // since the target attempt remains the same.
2367         mFastDataInputTargetAttempts = 1;
2368         doReturn(0).when(mFastDataInputSuccessesCounter).get();
2369         doReturn(1).when(mFastDataInputFallbacksCounter).get();
2370         mService.systemReady();
2371         verify(mFastDataInputSuccessesCounter, never()).set(anyInt());
2372         verify(mFastDataInputFallbacksCounter, never()).set(anyInt());
2373     }
2374 
2375     @Test
testAdoptFastDataInput_noRetryAfterSuccess()2376     public void testAdoptFastDataInput_noRetryAfterSuccess() throws Exception {
2377         // Boot through serviceReady(), verify the service won't retry unexpectedly
2378         // since the target attempt remains the same.
2379         mFastDataInputTargetAttempts = 1;
2380         doReturn(1).when(mFastDataInputSuccessesCounter).get();
2381         doReturn(0).when(mFastDataInputFallbacksCounter).get();
2382         mService.systemReady();
2383         verify(mFastDataInputSuccessesCounter, never()).set(anyInt());
2384         verify(mFastDataInputFallbacksCounter, never()).set(anyInt());
2385     }
2386 
2387     @Test
testAdoptFastDataInput_hasDiff()2388     public void testAdoptFastDataInput_hasDiff() throws Exception {
2389         // Boot through serviceReady() with flag enabled and assumes the stats are
2390         // failed to compare, verify the fallbacks counter is increased.
2391         mockDefaultSettings();
2392         doReturn(0).when(mFastDataInputSuccessesCounter).get();
2393         doReturn(0).when(mFastDataInputFallbacksCounter).get();
2394         mFastDataInputTargetAttempts = 1;
2395         mCompareStatsResult = "Has differences";
2396         mService.systemReady();
2397         verify(mFastDataInputSuccessesCounter, never()).set(anyInt());
2398         verify(mFastDataInputFallbacksCounter).set(1);
2399     }
2400 
2401     @Test
testAdoptFastDataInput_noDiff()2402     public void testAdoptFastDataInput_noDiff() throws Exception {
2403         // Boot through serviceReady() with target attempts increased,
2404         // assumes there was a previous failure,
2405         // and assumes the stats are successfully compared,
2406         // verify the successes counter is increased.
2407         mFastDataInputTargetAttempts = 2;
2408         doReturn(1).when(mFastDataInputFallbacksCounter).get();
2409         mCompareStatsResult = null;
2410         mService.systemReady();
2411         verify(mFastDataInputSuccessesCounter).set(1);
2412         verify(mFastDataInputFallbacksCounter, never()).set(anyInt());
2413     }
2414 
2415     @Test
testStatsFactoryRemoveUids()2416     public void testStatsFactoryRemoveUids() throws Exception {
2417         // pretend that network comes online
2418         mockDefaultSettings();
2419         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
2420         mockNetworkStatsSummary(buildEmptyStats());
2421         mockNetworkStatsUidDetail(buildEmptyStats());
2422 
2423         mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
2424                 new UnderlyingNetworkInfo[0]);
2425 
2426         // Create some traffic
2427         incrementCurrentTime(HOUR_IN_MILLIS);
2428         mockDefaultSettings();
2429         final NetworkStats stats = new NetworkStats(getElapsedRealtime(), 1)
2430                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
2431                 .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
2432                         4096L, 258L, 512L, 32L, 0L)
2433                 .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 64L, 3L, 1024L, 8L, 0L);
2434         mockNetworkStatsUidDetail(stats);
2435 
2436         forcePollAndWaitForIdle();
2437 
2438         // Verify service recorded history
2439         assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 0);
2440         assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
2441         assertUidTotal(sTemplateWifi, UID_GREEN, 64L, 3L, 1024L, 8L, 0);
2442 
2443         // Simulate that the apps are removed.
2444         final Intent intentBlue = new Intent(ACTION_UID_REMOVED);
2445         intentBlue.putExtra(EXTRA_UID, UID_BLUE);
2446         mServiceContext.sendBroadcast(intentBlue);
2447 
2448         final Intent intentRed = new Intent(ACTION_UID_REMOVED);
2449         intentRed.putExtra(EXTRA_UID, UID_RED);
2450         mServiceContext.sendBroadcast(intentRed);
2451 
2452         final int[] removedUids = {UID_BLUE, UID_RED};
2453 
2454         final ArgumentCaptor<int[]> removedUidsCaptor = ArgumentCaptor.forClass(int[].class);
2455         verify(mStatsFactory, times(2)).removeUidsLocked(removedUidsCaptor.capture());
2456         final List<int[]> captureRemovedUids = removedUidsCaptor.getAllValues();
2457         // Simulate that the stats are removed in NetworkStatsFactory.
2458         if (captureRemovedUids.contains(removedUids)) {
2459             stats.removeUids(removedUids);
2460         }
2461 
2462         // Verify the stats of the removed uid is removed.
2463         assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
2464         assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
2465         assertUidTotal(sTemplateWifi, UID_GREEN, 64L, 3L, 1024L, 8L, 0);
2466     }
2467 
2468     @FeatureFlag(name = TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG, enabled = false)
2469     @Test
testGetRateLimitCacheConfig_featureDisabled()2470     public void testGetRateLimitCacheConfig_featureDisabled() {
2471         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
2472         assertFalse(mService.getRateLimitCacheConfig().isCacheEnabled);
2473         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
2474         assertFalse(mService.getRateLimitCacheConfig().isCacheEnabled);
2475     }
2476 
2477     @FeatureFlag(name = TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG)
2478     @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
2479     @Test
testGetRateLimitCacheConfig_vOrAbove()2480     public void testGetRateLimitCacheConfig_vOrAbove() {
2481         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
2482         assertTrue(mService.getRateLimitCacheConfig().isCacheEnabled);
2483         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
2484         assertTrue(mService.getRateLimitCacheConfig().isCacheEnabled);
2485     }
2486 
2487     @FeatureFlag(name = TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG)
2488     @DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
2489     @Test
testGetRateLimitCacheConfig_belowV()2490     public void testGetRateLimitCacheConfig_belowV() {
2491         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
2492         assertFalse(mService.getRateLimitCacheConfig().isCacheEnabled);
2493         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
2494         assertTrue(mService.getRateLimitCacheConfig().isCacheEnabled);
2495     }
2496 
2497     @FeatureFlag(name = TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG)
2498     @FeatureFlag(name = TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG)
2499     @Test
testTrafficStatsRateLimitCache_clientCacheEnabledDisableServiceCache()2500     public void testTrafficStatsRateLimitCache_clientCacheEnabledDisableServiceCache()
2501             throws Exception {
2502         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
2503         doTestTrafficStatsRateLimitCache(false /* expectCached */);
2504     }
2505 
2506     @FeatureFlag(name = TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG, enabled = false)
2507     @Test
testTrafficStatsRateLimitCache_disabledWithCompatChangeEnabled()2508     public void testTrafficStatsRateLimitCache_disabledWithCompatChangeEnabled() throws Exception {
2509         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
2510         doTestTrafficStatsRateLimitCache(false /* expectCached */);
2511     }
2512 
2513     @FeatureFlag(name = TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG)
2514     @Test
testTrafficStatsRateLimitCache_enabledWithCompatChangeEnabled()2515     public void testTrafficStatsRateLimitCache_enabledWithCompatChangeEnabled() throws Exception {
2516         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
2517         doTestTrafficStatsRateLimitCache(true /* expectCached */);
2518     }
2519 
2520     @FeatureFlag(name = TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG, enabled = false)
2521     @Test
testTrafficStatsRateLimitCache_disabledWithCompatChangeDisabled()2522     public void testTrafficStatsRateLimitCache_disabledWithCompatChangeDisabled() throws Exception {
2523         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
2524         doTestTrafficStatsRateLimitCache(false /* expectCached */);
2525     }
2526 
2527     @FeatureFlag(name = TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG)
2528     @DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
2529     @Test
testTrafficStatsRateLimitCache_enabledWithCompatChangeDisabled_belowV()2530     public void testTrafficStatsRateLimitCache_enabledWithCompatChangeDisabled_belowV()
2531             throws Exception {
2532         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
2533         doTestTrafficStatsRateLimitCache(false /* expectCached */);
2534     }
2535 
2536     @FeatureFlag(name = TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG)
2537     @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
2538     @Test
testTrafficStatsRateLimitCache_enabledWithCompatChangeDisabled_vOrAbove()2539     public void testTrafficStatsRateLimitCache_enabledWithCompatChangeDisabled_vOrAbove()
2540             throws Exception {
2541         mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
2542         doTestTrafficStatsRateLimitCache(true /* expectCached */);
2543     }
2544 
doTestTrafficStatsRateLimitCache(boolean expectCached)2545     private void doTestTrafficStatsRateLimitCache(boolean expectCached) throws Exception {
2546         mockDefaultSettings();
2547         // Calling uid is not injected into the service, use the real uid to pass the caller check.
2548         final int myUid = Process.myUid();
2549         mockTrafficStatsValues(64L, 3L, 1024L, 8L);
2550         assertTrafficStatsValues(TEST_IFACE, myUid, 64L, 3L, 1024L, 8L);
2551 
2552         // Verify the values are cached.
2553         incrementCurrentTime(DEFAULT_TRAFFIC_STATS_CACHE_EXPIRY_DURATION_MS / 2);
2554         mockTrafficStatsValues(65L, 8L, 1055L, 9L);
2555         if (expectCached) {
2556             assertTrafficStatsValues(TEST_IFACE, myUid, 64L, 3L, 1024L, 8L);
2557         } else {
2558             assertTrafficStatsValues(TEST_IFACE, myUid, 65L, 8L, 1055L, 9L);
2559         }
2560 
2561         // Verify the values are updated after cache expiry.
2562         incrementCurrentTime(DEFAULT_TRAFFIC_STATS_CACHE_EXPIRY_DURATION_MS);
2563         assertTrafficStatsValues(TEST_IFACE, myUid, 65L, 8L, 1055L, 9L);
2564     }
2565 
mockTrafficStatsValues(long rxBytes, long rxPackets, long txBytes, long txPackets)2566     private void mockTrafficStatsValues(long rxBytes, long rxPackets,
2567             long txBytes, long txPackets) {
2568         // In practice, keys and operations are not used and filled with default values when
2569         // returned by JNI layer.
2570         final NetworkStats.Entry entry = new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_DEFAULT,
2571                 TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
2572                 rxBytes, rxPackets, txBytes, txPackets, 0L);
2573         mDeps.setNativeStat(entry);
2574     }
2575 
2576     // Assert for 3 different API return values respectively.
assertTrafficStatsValues(String iface, int uid, long rxBytes, long rxPackets, long txBytes, long txPackets)2577     private void assertTrafficStatsValues(String iface, int uid, long rxBytes, long rxPackets,
2578             long txBytes, long txPackets) {
2579         assertStatsResultEquals(mService.getTotalStats(), rxBytes, rxPackets, txBytes, txPackets);
2580         assertStatsResultEquals(mService.getIfaceStats(iface), rxBytes, rxPackets, txBytes,
2581                 txPackets);
2582         assertStatsResultEquals(mService.getUidStats(uid), rxBytes, rxPackets, txBytes, txPackets);
2583     }
2584 
assertStatsResultEquals(StatsResult stats, long rxBytes, long rxPackets, long txBytes, long txPackets)2585     private void assertStatsResultEquals(StatsResult stats, long rxBytes, long rxPackets,
2586             long txBytes, long txPackets) {
2587         assertEquals(rxBytes, stats.rxBytes);
2588         assertEquals(rxPackets, stats.rxPackets);
2589         assertEquals(txBytes, stats.txBytes);
2590         assertEquals(txPackets, stats.txPackets);
2591     }
2592 
assertShouldRunComparison(boolean expected, boolean isDebuggable)2593     private void assertShouldRunComparison(boolean expected, boolean isDebuggable) {
2594         assertEquals("shouldRunComparison (debuggable=" + isDebuggable + "): ",
2595                 expected, mService.shouldRunComparison());
2596     }
2597 
makeTestRecorder(File directory, String prefix, Config config, boolean includeTags, boolean wipeOnError)2598     private NetworkStatsRecorder makeTestRecorder(File directory, String prefix, Config config,
2599             boolean includeTags, boolean wipeOnError) {
2600         final NetworkStats.NonMonotonicObserver observer =
2601                 mock(NetworkStats.NonMonotonicObserver.class);
2602         final DropBoxManager dropBox = mock(DropBoxManager.class);
2603         return new NetworkStatsRecorder(new FileRotator(
2604                 directory, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
2605                 observer, dropBox, prefix, config.bucketDuration, includeTags, wipeOnError,
2606                 false /* useFastDataInput */, directory);
2607     }
2608 
getLegacyCollection(String prefix, boolean includeTags)2609     private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {
2610         final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, prefix,
2611                 mSettings.getXtConfig(), includeTags, false);
2612         return recorder.getOrLoadCompleteLocked();
2613     }
2614 
assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)2615     private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
2616             long txBytes, long txPackets, int operations) throws Exception {
2617         assertNetworkTotal(template, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
2618                 txPackets, operations);
2619     }
2620 
assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)2621     private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes,
2622             long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
2623         // verify history API
2624         final NetworkStatsHistory history =
2625                 mSession.getHistoryIntervalForNetwork(template, FIELD_ALL, start, end);
2626         assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations);
2627 
2628         // verify summary API
2629         final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
2630         assertValues(stats, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
2631                 DEFAULT_NETWORK_ALL,  rxBytes, rxPackets, txBytes, txPackets, operations);
2632     }
2633 
assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)2634     private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
2635             long txBytes, long txPackets, int operations) throws Exception {
2636         assertUidTotal(template, uid, SET_ALL, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
2637                 rxBytes, rxPackets, txBytes, txPackets, operations);
2638     }
2639 
assertUidTotal(NetworkTemplate template, int uid, int set, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)2640     private void assertUidTotal(NetworkTemplate template, int uid, int set, int metered,
2641             int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes,
2642             long txPackets, int operations) throws Exception {
2643         // verify history API
2644         final NetworkStatsHistory history = mSession.getHistoryForUid(
2645                 template, uid, set, TAG_NONE, FIELD_ALL);
2646         assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
2647                 txPackets, operations);
2648 
2649         // verify summary API
2650         final NetworkStats stats = mSession.getSummaryForAllUid(
2651                 template, Long.MIN_VALUE, Long.MAX_VALUE, false);
2652         assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, metered, roaming, defaultNetwork,
2653                 rxBytes, rxPackets, txBytes, txPackets, operations);
2654     }
2655 
prepareForSystemReady()2656     private void prepareForSystemReady() throws Exception {
2657         mockDefaultSettings();
2658         mockNetworkStatsUidDetail(buildEmptyStats());
2659         mockNetworkStatsSummary(buildEmptyStats());
2660     }
2661 
getActiveIface(NetworkStateSnapshot... states)2662     private String getActiveIface(NetworkStateSnapshot... states) throws Exception {
2663         if (states == null || states.length == 0 || states[0].getLinkProperties() == null) {
2664             return null;
2665         }
2666         return states[0].getLinkProperties().getInterfaceName();
2667     }
2668 
mockNetworkStatsSummary(NetworkStats summary)2669     private void mockNetworkStatsSummary(NetworkStats summary) throws Exception {
2670         mockNetworkStatsSummaryXt(summary.clone());
2671     }
2672 
mockNetworkStatsSummaryXt(NetworkStats summary)2673     private void mockNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
2674         doReturn(summary).when(mStatsFactory).readNetworkStatsSummaryXt();
2675     }
2676 
mockNetworkStatsUidDetail(NetworkStats detail)2677     private void mockNetworkStatsUidDetail(NetworkStats detail) throws Exception {
2678         final TetherStatsParcel[] tetherStatsParcels = {};
2679         mockNetworkStatsUidDetail(detail, tetherStatsParcels, INTERFACES_ALL);
2680     }
2681 
mockNetworkStatsUidDetail(NetworkStats detail, TetherStatsParcel[] tetherStatsParcels, String[] ifaces)2682     private void mockNetworkStatsUidDetail(NetworkStats detail,
2683             TetherStatsParcel[] tetherStatsParcels, String[] ifaces) throws Exception {
2684 
2685         doReturn(detail).when(mStatsFactory)
2686                 .readNetworkStatsDetail(eq(UID_ALL), aryEq(ifaces), eq(TAG_ALL));
2687 
2688         // also include tethering details, since they are folded into UID
2689         doReturn(tetherStatsParcels).when(mNetd).tetherGetStats();
2690     }
2691 
mockDefaultSettings()2692     private void mockDefaultSettings() throws Exception {
2693         mockSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
2694         mSettings.setBroadcastNetworkStatsUpdateDelayMs(
2695                 NetworkStatsService.BROADCAST_NETWORK_STATS_UPDATED_DELAY_MS);
2696     }
2697 
mockSettings(long bucketDuration, long deleteAge)2698     private void mockSettings(long bucketDuration, long deleteAge) {
2699         mSettings.setConfig(new Config(bucketDuration, deleteAge, deleteAge));
2700     }
2701 
2702     // Note that this object will be accessed from test main thread and service handler thread.
2703     // Thus, it has to be thread safe in order to prevent from flakiness.
2704     private static class TestNetworkStatsSettings
2705             extends NetworkStatsService.DefaultNetworkStatsSettings {
2706 
2707         @NonNull
2708         private volatile Config mConfig;
2709         private final AtomicBoolean mCombineSubtypeEnabled = new AtomicBoolean();
2710         private long mBroadcastNetworkStatsUpdateDelayMs =
2711                 NetworkStatsService.BROADCAST_NETWORK_STATS_UPDATED_DELAY_MS;
2712 
TestNetworkStatsSettings(long bucketDuration, long deleteAge)2713         TestNetworkStatsSettings(long bucketDuration, long deleteAge) {
2714             mConfig = new Config(bucketDuration, deleteAge, deleteAge);
2715         }
2716 
setConfig(@onNull Config config)2717         void setConfig(@NonNull Config config) {
2718             mConfig = config;
2719         }
2720 
2721         @Override
getPollDelay()2722         public long getPollDelay() {
2723             return 0L;
2724         }
2725 
2726         @Override
getGlobalAlertBytes(long def)2727         public long getGlobalAlertBytes(long def) {
2728             return MB_IN_BYTES;
2729         }
2730 
2731         @Override
getXtConfig()2732         public Config getXtConfig() {
2733             return mConfig;
2734         }
2735 
2736         @Override
getUidConfig()2737         public Config getUidConfig() {
2738             return mConfig;
2739         }
2740 
2741         @Override
getUidTagConfig()2742         public Config getUidTagConfig() {
2743             return mConfig;
2744         }
2745 
2746         @Override
getXtPersistBytes(long def)2747         public long getXtPersistBytes(long def) {
2748             return MB_IN_BYTES;
2749         }
2750 
2751         @Override
getUidPersistBytes(long def)2752         public long getUidPersistBytes(long def) {
2753             return MB_IN_BYTES;
2754         }
2755 
2756         @Override
getUidTagPersistBytes(long def)2757         public long getUidTagPersistBytes(long def) {
2758             return MB_IN_BYTES;
2759         }
2760 
2761         @Override
getCombineSubtypeEnabled()2762         public boolean getCombineSubtypeEnabled() {
2763             return mCombineSubtypeEnabled.get();
2764         }
2765 
setCombineSubtypeEnabled(boolean enable)2766         public void setCombineSubtypeEnabled(boolean enable) {
2767             mCombineSubtypeEnabled.set(enable);
2768         }
2769 
2770         @Override
getAugmentEnabled()2771         public boolean getAugmentEnabled() {
2772             return false;
2773         }
2774 
2775         @Override
getBroadcastNetworkStatsUpdateDelayMs()2776         public long getBroadcastNetworkStatsUpdateDelayMs() {
2777             return mBroadcastNetworkStatsUpdateDelayMs;
2778         }
2779 
setBroadcastNetworkStatsUpdateDelayMs(long broadcastDelay)2780         public void setBroadcastNetworkStatsUpdateDelayMs(long broadcastDelay) {
2781             mBroadcastNetworkStatsUpdateDelayMs = broadcastDelay;
2782         }
2783     }
2784 
assertStatsFilesExist(boolean exist)2785     private void assertStatsFilesExist(boolean exist) {
2786         if (exist) {
2787             assertTrue(mStatsDir.list().length > 0);
2788         } else {
2789             assertTrue(mStatsDir.list().length == 0);
2790         }
2791     }
2792 
assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)2793     private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
2794             long rxPackets, long txBytes, long txPackets, int operations) {
2795         final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
2796         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
2797         assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
2798         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
2799         assertEquals("unexpected txPackets", txPackets, entry.txPackets);
2800         assertEquals("unexpected operations", operations, entry.operations);
2801     }
2802 
buildWifiState()2803     private static NetworkStateSnapshot buildWifiState() {
2804         return buildWifiState(false, TEST_IFACE, null);
2805     }
2806 
buildWifiState(boolean isMetered, @NonNull String iface)2807     private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) {
2808         return buildWifiState(isMetered, iface, null);
2809     }
2810 
buildWifiState(boolean isMetered, @NonNull String iface, String subscriberId)2811     private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface,
2812             String subscriberId) {
2813         final LinkProperties prop = new LinkProperties();
2814         prop.setInterfaceName(iface);
2815         final NetworkCapabilities capabilities = new NetworkCapabilities();
2816         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
2817         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
2818         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
2819         capabilities.setTransportInfo(sWifiInfo);
2820         return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, subscriberId, TYPE_WIFI);
2821     }
2822 
buildMobileState(String subscriberId)2823     private static NetworkStateSnapshot buildMobileState(String subscriberId) {
2824         return buildStateOfTransport(NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
2825                 TEST_IFACE, subscriberId, null /* wifiNetworkKey */,
2826                 false /* isTemporarilyNotMetered */, false /* isRoaming */);
2827     }
2828 
buildSatelliteMobileState(String subscriberId)2829     private static NetworkStateSnapshot buildSatelliteMobileState(String subscriberId) {
2830         return buildStateOfTransport(NetworkCapabilities.TRANSPORT_SATELLITE, TYPE_MOBILE,
2831                 TEST_IFACE, subscriberId, null /* wifiNetworkKey */,
2832                 false /* isTemporarilyNotMetered */, false /* isRoaming */);
2833     }
2834 
buildTestState(@onNull String iface, @Nullable String wifiNetworkKey)2835     private static NetworkStateSnapshot buildTestState(@NonNull String iface,
2836             @Nullable String wifiNetworkKey) {
2837         return buildStateOfTransport(NetworkCapabilities.TRANSPORT_TEST, TYPE_TEST,
2838                 iface, null /* subscriberId */, wifiNetworkKey,
2839                 false /* isTemporarilyNotMetered */, false /* isRoaming */);
2840     }
2841 
buildStateOfTransport(int transport, int legacyType, String iface, String subscriberId, String wifiNetworkKey, boolean isTemporarilyNotMetered, boolean isRoaming)2842     private static NetworkStateSnapshot buildStateOfTransport(int transport, int legacyType,
2843             String iface, String subscriberId, String wifiNetworkKey,
2844             boolean isTemporarilyNotMetered, boolean isRoaming) {
2845         final LinkProperties prop = new LinkProperties();
2846         prop.setInterfaceName(iface);
2847         final NetworkCapabilities capabilities = new NetworkCapabilities();
2848 
2849         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
2850                 isTemporarilyNotMetered);
2851         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
2852         capabilities.addTransportType(transport);
2853         if (legacyType == TYPE_TEST && !TextUtils.isEmpty(wifiNetworkKey)) {
2854             capabilities.setNetworkSpecifier(new TestNetworkSpecifier(wifiNetworkKey));
2855         }
2856         return new NetworkStateSnapshot(
2857                 MOBILE_NETWORK, capabilities, prop, subscriberId, legacyType);
2858     }
2859 
buildEmptyStats()2860     private NetworkStats buildEmptyStats() {
2861         return new NetworkStats(getElapsedRealtime(), 0);
2862     }
2863 
buildOemManagedMobileState( String subscriberId, boolean isRoaming, int[] oemNetCapabilities)2864     private static NetworkStateSnapshot buildOemManagedMobileState(
2865             String subscriberId, boolean isRoaming, int[] oemNetCapabilities) {
2866         final LinkProperties prop = new LinkProperties();
2867         prop.setInterfaceName(TEST_IFACE);
2868         final NetworkCapabilities capabilities = new NetworkCapabilities();
2869         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
2870         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
2871         for (int nc : oemNetCapabilities) {
2872             capabilities.setCapability(nc, true);
2873         }
2874         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
2875         return new NetworkStateSnapshot(MOBILE_NETWORK, capabilities, prop, subscriberId,
2876                 TYPE_MOBILE);
2877     }
2878 
buildImsState( String subscriberId, int subId, String ifaceName)2879     private static NetworkStateSnapshot buildImsState(
2880             String subscriberId, int subId, String ifaceName) {
2881         final LinkProperties prop = new LinkProperties();
2882         prop.setInterfaceName(ifaceName);
2883         final NetworkCapabilities capabilities = new NetworkCapabilities();
2884         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, true);
2885         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
2886         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_IMS, true);
2887         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
2888         capabilities.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId));
2889         return new NetworkStateSnapshot(
2890                 MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
2891     }
2892 
getElapsedRealtime()2893     private long getElapsedRealtime() {
2894         return mElapsedRealtime;
2895     }
2896 
startTimeMillis()2897     private long startTimeMillis() {
2898         return TEST_START;
2899     }
2900 
currentTimeMillis()2901     private long currentTimeMillis() {
2902         return startTimeMillis() + mElapsedRealtime;
2903     }
2904 
incrementCurrentTime(long duration)2905     private void incrementCurrentTime(long duration) {
2906         mElapsedRealtime += duration;
2907     }
2908 
forcePollAndWaitForIdle()2909     private void forcePollAndWaitForIdle() {
2910         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
2911         waitForIdle();
2912     }
2913 
waitForIdle()2914     private void waitForIdle() {
2915         HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
2916     }
2917 
cookieTagMapContainsUid(int uid)2918     private boolean cookieTagMapContainsUid(int uid) throws ErrnoException {
2919         final AtomicBoolean found = new AtomicBoolean();
2920         mCookieTagMap.forEach((k, v) -> {
2921             if (v.uid == uid) {
2922                 found.set(true);
2923             }
2924         });
2925         return found.get();
2926     }
2927 
statsMapContainsUid( TestBpfMap<K, V> map, int uid)2928     private static <K extends StatsMapKey, V extends StatsMapValue> boolean statsMapContainsUid(
2929             TestBpfMap<K, V> map, int uid) throws ErrnoException {
2930         final AtomicBoolean found = new AtomicBoolean();
2931         map.forEach((k, v) -> {
2932             if (k.uid == uid) {
2933                 found.set(true);
2934             }
2935         });
2936         return found.get();
2937     }
2938 
initBpfMapsWithTagData(int uid)2939     private void initBpfMapsWithTagData(int uid) throws ErrnoException {
2940         // key needs to be unique, use some offset from uid.
2941         mCookieTagMap.insertEntry(new CookieTagMapKey(1000 + uid), new CookieTagMapValue(uid, 1));
2942         mCookieTagMap.insertEntry(new CookieTagMapKey(2000 + uid), new CookieTagMapValue(uid, 2));
2943 
2944         mStatsMapA.insertEntry(new StatsMapKey(uid, 1, 0, 10), new StatsMapValue(5, 5000, 3, 3000));
2945         mStatsMapA.insertEntry(new StatsMapKey(uid, 2, 0, 10), new StatsMapValue(5, 5000, 3, 3000));
2946 
2947         mStatsMapB.insertEntry(new StatsMapKey(uid, 1, 0, 10), new StatsMapValue(0, 0, 0, 0));
2948 
2949         mAppUidStatsMap.insertEntry(new UidStatsMapKey(uid), new StatsMapValue(10, 10000, 6, 6000));
2950 
2951         mUidCounterSetMap.insertEntry(new S32(uid), new U8((short) 1));
2952 
2953         assertTrue(cookieTagMapContainsUid(uid));
2954         assertTrue(statsMapContainsUid(mStatsMapA, uid));
2955         assertTrue(statsMapContainsUid(mStatsMapB, uid));
2956         assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(uid)));
2957         assertTrue(mUidCounterSetMap.containsKey(new S32(uid)));
2958     }
2959 
2960     @Test
testRemovingUidRemovesTagDataForUid()2961     public void testRemovingUidRemovesTagDataForUid() throws ErrnoException {
2962         initBpfMapsWithTagData(UID_BLUE);
2963         initBpfMapsWithTagData(UID_RED);
2964 
2965         final Intent intent = new Intent(ACTION_UID_REMOVED);
2966         intent.putExtra(EXTRA_UID, UID_BLUE);
2967         mServiceContext.sendBroadcast(intent);
2968 
2969         // assert that all UID_BLUE related tag data has been removed from the maps.
2970         assertFalse(cookieTagMapContainsUid(UID_BLUE));
2971         assertFalse(statsMapContainsUid(mStatsMapA, UID_BLUE));
2972         assertFalse(statsMapContainsUid(mStatsMapB, UID_BLUE));
2973         assertFalse(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_BLUE)));
2974         assertFalse(mUidCounterSetMap.containsKey(new S32(UID_BLUE)));
2975 
2976         // assert that UID_RED related tag data is still in the maps.
2977         assertTrue(cookieTagMapContainsUid(UID_RED));
2978         assertTrue(statsMapContainsUid(mStatsMapA, UID_RED));
2979         assertTrue(statsMapContainsUid(mStatsMapB, UID_RED));
2980         assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_RED)));
2981         assertTrue(mUidCounterSetMap.containsKey(new S32(UID_RED)));
2982     }
2983 
assertDumpContains(final String dump, final String message)2984     private void assertDumpContains(final String dump, final String message) {
2985         assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
2986                 dump.contains(message));
2987     }
2988 
getDump(final String[] args)2989     private String getDump(final String[] args) {
2990         final StringWriter sw = new StringWriter();
2991         mService.dump(new FileDescriptor(), new PrintWriter(sw), args);
2992         return sw.toString();
2993     }
2994 
getDump()2995     private String getDump() {
2996         return getDump(new String[]{});
2997     }
2998 
parseBpfRawMap( Class<K> keyClass, Class<V> valueClass, String dumpStr)2999     private <K extends Struct, V extends Struct> Map<K, V> parseBpfRawMap(
3000             Class<K> keyClass, Class<V> valueClass, String dumpStr) {
3001         final HashMap<K, V> map = new HashMap<>();
3002         for (final String line : dumpStr.split(LINE_DELIMITER)) {
3003             final Pair<K, V> keyValue =
3004                     BpfDump.fromBase64EncodedString(keyClass, valueClass, line.trim());
3005             map.put(keyValue.first, keyValue.second);
3006         }
3007         return map;
3008     }
3009 
3010     @Test
testDumpCookieTagMap()3011     public void testDumpCookieTagMap() throws ErrnoException {
3012         initBpfMapsWithTagData(UID_BLUE);
3013 
3014         final String dump = getDump();
3015         assertDumpContains(dump, "mCookieTagMap: OK");
3016         assertDumpContains(dump, "cookie=2002 tag=0x1 uid=1002");
3017         assertDumpContains(dump, "cookie=3002 tag=0x2 uid=1002");
3018     }
3019 
3020     @Test
testDumpCookieTagMapBpfRawMap()3021     public void testDumpCookieTagMapBpfRawMap() throws ErrnoException {
3022         initBpfMapsWithTagData(UID_BLUE);
3023 
3024         final String dump = getDump(new String[]{DUMPSYS_BPF_RAW_MAP, DUMPSYS_COOKIE_TAG_MAP});
3025         Map<CookieTagMapKey, CookieTagMapValue> cookieTagMap = parseBpfRawMap(
3026                 CookieTagMapKey.class, CookieTagMapValue.class, dump);
3027 
3028         final CookieTagMapValue val1 = cookieTagMap.get(new CookieTagMapKey(2002));
3029         assertEquals(1, val1.tag);
3030         assertEquals(1002, val1.uid);
3031 
3032         final CookieTagMapValue val2 = cookieTagMap.get(new CookieTagMapKey(3002));
3033         assertEquals(2, val2.tag);
3034         assertEquals(1002, val2.uid);
3035     }
3036 
3037     @Test
testDumpUidCounterSetMap()3038     public void testDumpUidCounterSetMap() throws ErrnoException {
3039         initBpfMapsWithTagData(UID_BLUE);
3040 
3041         final String dump = getDump();
3042         assertDumpContains(dump, "mUidCounterSetMap: OK");
3043         assertDumpContains(dump, "uid=1002 set=1");
3044     }
3045 
3046     @Test
testAppUidStatsMap()3047     public void testAppUidStatsMap() throws ErrnoException {
3048         initBpfMapsWithTagData(UID_BLUE);
3049 
3050         final String dump = getDump();
3051         assertDumpContains(dump, "mAppUidStatsMap: OK");
3052         assertDumpContains(dump, "uid rxBytes rxPackets txBytes txPackets");
3053         assertDumpContains(dump, "1002 10000 10 6000 6");
3054     }
3055 
doTestDumpStatsMap(final String expectedIfaceName)3056     private void doTestDumpStatsMap(final String expectedIfaceName) throws ErrnoException {
3057         initBpfMapsWithTagData(UID_BLUE);
3058 
3059         final String dump = getDump();
3060         assertDumpContains(dump, "mStatsMapA: OK");
3061         assertDumpContains(dump, "mStatsMapB: OK");
3062         assertDumpContains(dump,
3063                 "ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets");
3064         assertDumpContains(dump, "10 " + expectedIfaceName + " 0x2 1002 0 5000 5 3000 3");
3065         assertDumpContains(dump, "10 " + expectedIfaceName + " 0x1 1002 0 5000 5 3000 3");
3066     }
3067 
3068     @Test
testDumpStatsMap()3069     public void testDumpStatsMap() throws ErrnoException {
3070         doReturn("wlan0").when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
3071         doTestDumpStatsMap("wlan0");
3072     }
3073 
3074     @Test
testDumpStatsMapUnknownInterface()3075     public void testDumpStatsMapUnknownInterface() throws ErrnoException {
3076         doReturn(null).when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
3077         doTestDumpStatsMap("unknown");
3078     }
3079 
doTestDumpIfaceStatsMap(final String expectedIfaceName)3080     void doTestDumpIfaceStatsMap(final String expectedIfaceName) throws Exception {
3081         mIfaceStatsMap.insertEntry(new S32(10), new StatsMapValue(3, 3000, 3, 3000));
3082 
3083         final String dump = getDump();
3084         assertDumpContains(dump, "mIfaceStatsMap: OK");
3085         assertDumpContains(dump, "ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets");
3086         assertDumpContains(dump, "10 " + expectedIfaceName + " 3000 3 3000 3");
3087     }
3088 
3089     @Test
testDumpIfaceStatsMap()3090     public void testDumpIfaceStatsMap() throws Exception {
3091         doReturn("wlan0").when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
3092         doTestDumpIfaceStatsMap("wlan0");
3093     }
3094 
3095     @Test
testDumpIfaceStatsMapUnknownInterface()3096     public void testDumpIfaceStatsMapUnknownInterface() throws Exception {
3097         doReturn(null).when(mBpfInterfaceMapHelper).getIfNameByIndex(10 /* index */);
3098         doTestDumpIfaceStatsMap("unknown");
3099     }
3100 
3101     // Basic test to ensure event logger dump is called.
3102     // Note that tests to ensure detailed correctness is done in the dedicated tests.
3103     // See NetworkStatsEventLoggerTest.
3104     @Test
testDumpEventLogger()3105     public void testDumpEventLogger() {
3106         setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
3107         final String dump = getDump();
3108         assertDumpContains(dump, pollReasonNameOf(POLL_REASON_RAT_CHANGED));
3109     }
3110 
3111     @Test
testEnforcePackageNameMatchesUid()3112     public void testEnforcePackageNameMatchesUid() throws Exception {
3113         final String testMyPackageName = "test.package.myname";
3114         final String testRedPackageName = "test.package.red";
3115         final String testInvalidPackageName = "test.package.notfound";
3116 
3117         doReturn(UID_RED).when(mPm).getPackageUid(eq(testRedPackageName), anyInt());
3118         doReturn(Process.myUid()).when(mPm).getPackageUid(eq(testMyPackageName), anyInt());
3119         doThrow(new PackageManager.NameNotFoundException()).when(mPm)
3120                 .getPackageUid(eq(testInvalidPackageName), anyInt());
3121 
3122         assertThrows(SecurityException.class, () ->
3123                 mService.openSessionForUsageStats(0 /* flags */, testRedPackageName));
3124         assertThrows(SecurityException.class, () ->
3125                 mService.openSessionForUsageStats(0 /* flags */, testInvalidPackageName));
3126         assertThrows(NullPointerException.class, () ->
3127                 mService.openSessionForUsageStats(0 /* flags */, null));
3128         // Verify package name belongs to ourselves does not throw.
3129         mService.openSessionForUsageStats(0 /* flags */, testMyPackageName);
3130 
3131         long thresholdInBytes = 10 * 1024 * 1024;  // 10 MB
3132         DataUsageRequest request = new DataUsageRequest(
3133                 2 /* requestId */, sTemplateImsi1, thresholdInBytes);
3134         assertThrows(SecurityException.class, () ->
3135                 mService.registerUsageCallback(testRedPackageName, request, mUsageCallback));
3136         assertThrows(SecurityException.class, () ->
3137                 mService.registerUsageCallback(testInvalidPackageName, request, mUsageCallback));
3138         assertThrows(NullPointerException.class, () ->
3139                 mService.registerUsageCallback(null, request, mUsageCallback));
3140         mService.registerUsageCallback(testMyPackageName, request, mUsageCallback);
3141     }
3142 
3143     @Test
testDumpSkDestroyListenerLogs()3144     public void testDumpSkDestroyListenerLogs() throws ErrnoException {
3145         doAnswer((invocation) -> {
3146             final IndentingPrintWriter ipw = (IndentingPrintWriter) invocation.getArgument(0);
3147             ipw.println("Log for testing");
3148             return null;
3149         }).when(mSkDestroyListener).dump(any());
3150 
3151         final String dump = getDump();
3152         assertDumpContains(dump, "Log for testing");
3153     }
3154 
3155     private static class TestNetworkStatsUpdatedReceiver extends BroadcastReceiver {
3156         private final ArrayTrackRecord<Intent>.ReadHead mHistory;
3157 
TestNetworkStatsUpdatedReceiver()3158         TestNetworkStatsUpdatedReceiver() {
3159             mHistory = (new ArrayTrackRecord<Intent>()).newReadHead();
3160         }
3161 
3162         @Override
onReceive(Context context, Intent intent)3163         public void onReceive(Context context, Intent intent) {
3164             mHistory.add(intent);
3165         }
3166 
3167         /**
3168          * Assert no broadcast intent is received in blocking manner
3169          */
assertNoBroadcastIntentReceived()3170         public void assertNoBroadcastIntentReceived()  {
3171             assertNull(mHistory.peek());
3172         }
3173 
3174         /**
3175          * Assert an intent is received and remove it from queue
3176          */
assertBroadcastIntentReceived()3177         public void assertBroadcastIntentReceived() {
3178             assertNotNull(mHistory.poll(WAIT_TIMEOUT, number -> true));
3179         }
3180     }
3181 
3182     @FeatureFlag(name = BROADCAST_NETWORK_STATS_UPDATED_RATE_LIMIT_ENABLED_FLAG)
3183     @Test
testNetworkStatsUpdatedIntentSpam_rateLimitOn()3184     public void testNetworkStatsUpdatedIntentSpam_rateLimitOn() throws Exception {
3185         // Set the update delay long enough that messages won't be processed before unblocked
3186         // Set a short time to test the behavior before reaching delay.
3187         // Constraint: test running time < toleranceMs < update delay time
3188         mSettings.setBroadcastNetworkStatsUpdateDelayMs(100_000L);
3189         final long toleranceMs = 5000;
3190 
3191         final TestableLooper mTestableLooper = new TestableLooper(mHandlerThread.getLooper());
3192         final TestNetworkStatsUpdatedReceiver receiver = new TestNetworkStatsUpdatedReceiver();
3193         mServiceContext.registerReceiver(receiver, new IntentFilter(ACTION_NETWORK_STATS_UPDATED));
3194 
3195         try {
3196             // Test that before anything, the intent is delivered immediately
3197             mService.forceUpdate();
3198             mTestableLooper.processAllMessages();
3199             receiver.assertBroadcastIntentReceived();
3200             receiver.assertNoBroadcastIntentReceived();
3201 
3202             // Test that the next two intents results in exactly one intent delivered
3203             for (int i = 0; i < 2; i++) {
3204                 mService.forceUpdate();
3205             }
3206             // Test that the delay depends on our set value
3207             mTestableLooper.moveTimeForward(mSettings.getBroadcastNetworkStatsUpdateDelayMs()
3208                     - toleranceMs);
3209             mTestableLooper.processAllMessages();
3210             receiver.assertNoBroadcastIntentReceived();
3211 
3212             // Unblock messages and test that the second and third update
3213             // is broadcasted right after the delay
3214             mTestableLooper.moveTimeForward(toleranceMs);
3215             mTestableLooper.processAllMessages();
3216             receiver.assertBroadcastIntentReceived();
3217             receiver.assertNoBroadcastIntentReceived();
3218 
3219         } finally {
3220             mTestableLooper.destroy();
3221         }
3222     }
3223 
3224     @FeatureFlag(name = BROADCAST_NETWORK_STATS_UPDATED_RATE_LIMIT_ENABLED_FLAG, enabled = false)
3225     @Test
testNetworkStatsUpdatedIntentSpam_rateLimitOff()3226     public void testNetworkStatsUpdatedIntentSpam_rateLimitOff() throws Exception {
3227         // Set the update delay long enough to ensure that messages are processed
3228         // despite the rate limit.
3229         mSettings.setBroadcastNetworkStatsUpdateDelayMs(100_000L);
3230 
3231         final TestNetworkStatsUpdatedReceiver receiver = new TestNetworkStatsUpdatedReceiver();
3232         mServiceContext.registerReceiver(receiver, new IntentFilter(ACTION_NETWORK_STATS_UPDATED));
3233 
3234         for (int i = 0; i < 2; i++) {
3235             mService.forceUpdate();
3236             waitForIdle();
3237             receiver.assertBroadcastIntentReceived();
3238         }
3239         receiver.assertNoBroadcastIntentReceived();
3240     }
3241 }
3242