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