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