NetworkStatsObserversTest.java revision 6965c1869aa8499706522d057b5143bbc240178b
1/* 2 * Copyright (C) 2016 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 17package com.android.server.net; 18 19import static android.net.ConnectivityManager.TYPE_MOBILE; 20import static android.net.ConnectivityManager.TYPE_WIFI; 21import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 22import static org.mockito.Matchers.any; 23import static org.mockito.Matchers.anyInt; 24import static org.mockito.Matchers.isA; 25import static org.mockito.Mockito.when; 26 27import static android.net.NetworkStats.SET_DEFAULT; 28import static android.net.NetworkStats.ROAMING_NO; 29import static android.net.NetworkStats.TAG_NONE; 30import static android.net.NetworkTemplate.buildTemplateMobileAll; 31import static android.net.NetworkTemplate.buildTemplateWifiWildcard; 32import static android.net.TrafficStats.MB_IN_BYTES; 33import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 34 35import android.app.usage.NetworkStatsManager; 36import android.net.DataUsageRequest; 37import android.net.NetworkIdentity; 38import android.net.NetworkStats; 39import android.net.NetworkTemplate; 40import android.os.Handler; 41import android.os.HandlerThread; 42import android.os.IBinder; 43import android.os.Process; 44 45import android.os.ConditionVariable; 46import android.os.Looper; 47import android.os.Messenger; 48import android.os.Message; 49import android.os.UserHandle; 50import android.telephony.TelephonyManager; 51import android.util.ArrayMap; 52 53import com.android.internal.net.VpnInfo; 54import com.android.server.net.NetworkStatsService; 55import com.android.server.net.NetworkStatsServiceTest.IdleableHandlerThread; 56import com.android.server.net.NetworkStatsServiceTest.LatchedHandler; 57 58import java.util.ArrayList; 59import java.util.Objects; 60import java.util.List; 61 62import junit.framework.TestCase; 63 64import org.mockito.Mock; 65import org.mockito.Mockito; 66import org.mockito.MockitoAnnotations; 67 68/** 69 * Tests for {@link NetworkStatsObservers}. 70 */ 71public class NetworkStatsObserversTest extends TestCase { 72 private static final String TEST_IFACE = "test0"; 73 private static final String TEST_IFACE2 = "test1"; 74 private static final long TEST_START = 1194220800000L; 75 76 private static final String IMSI_1 = "310004"; 77 private static final String IMSI_2 = "310260"; 78 private static final String TEST_SSID = "AndroidAP"; 79 80 private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard(); 81 private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1); 82 private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2); 83 84 private static final int UID_RED = UserHandle.PER_USER_RANGE + 1; 85 private static final int UID_BLUE = UserHandle.PER_USER_RANGE + 2; 86 private static final int UID_GREEN = UserHandle.PER_USER_RANGE + 3; 87 private static final int UID_ANOTHER_USER = 2 * UserHandle.PER_USER_RANGE + 4; 88 89 private static final long WAIT_TIMEOUT = 500; // 1/2 sec 90 private static final long THRESHOLD_BYTES = 2 * MB_IN_BYTES; 91 private static final long BASE_BYTES = 7 * MB_IN_BYTES; 92 private static final int INVALID_TYPE = -1; 93 94 private static final VpnInfo[] VPN_INFO = new VpnInfo[0]; 95 96 private long mElapsedRealtime; 97 98 private IdleableHandlerThread mObserverHandlerThread; 99 private Handler mObserverNoopHandler; 100 101 private LatchedHandler mHandler; 102 private ConditionVariable mCv; 103 104 private NetworkStatsObservers mStatsObservers; 105 private Messenger mMessenger; 106 private ArrayMap<String, NetworkIdentitySet> mActiveIfaces; 107 private ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces; 108 109 @Mock private IBinder mockBinder; 110 111 @Override 112 public void setUp() throws Exception { 113 super.setUp(); 114 MockitoAnnotations.initMocks(this); 115 116 mObserverHandlerThread = new IdleableHandlerThread("HandlerThread"); 117 mObserverHandlerThread.start(); 118 final Looper observerLooper = mObserverHandlerThread.getLooper(); 119 mStatsObservers = new NetworkStatsObservers() { 120 @Override 121 protected Looper getHandlerLooperLocked() { 122 return observerLooper; 123 } 124 }; 125 126 mCv = new ConditionVariable(); 127 mHandler = new LatchedHandler(Looper.getMainLooper(), mCv); 128 mMessenger = new Messenger(mHandler); 129 130 mActiveIfaces = new ArrayMap<>(); 131 mActiveUidIfaces = new ArrayMap<>(); 132 } 133 134 public void testRegister_thresholdTooLow_setsDefaultThreshold() throws Exception { 135 long thresholdTooLowBytes = 1L; 136 DataUsageRequest inputRequest = new DataUsageRequest( 137 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdTooLowBytes); 138 139 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 140 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 141 assertTrue(request.requestId > 0); 142 assertTrue(Objects.equals(sTemplateWifi, request.template)); 143 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 144 } 145 146 public void testRegister_highThreshold_accepted() throws Exception { 147 long highThresholdBytes = 2 * THRESHOLD_BYTES; 148 DataUsageRequest inputRequest = new DataUsageRequest( 149 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, highThresholdBytes); 150 151 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 152 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 153 assertTrue(request.requestId > 0); 154 assertTrue(Objects.equals(sTemplateWifi, request.template)); 155 assertEquals(highThresholdBytes, request.thresholdInBytes); 156 } 157 158 public void testRegister_twoRequests_twoIds() throws Exception { 159 DataUsageRequest inputRequest = new DataUsageRequest( 160 DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, THRESHOLD_BYTES); 161 162 DataUsageRequest request1 = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 163 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 164 assertTrue(request1.requestId > 0); 165 assertTrue(Objects.equals(sTemplateWifi, request1.template)); 166 assertEquals(THRESHOLD_BYTES, request1.thresholdInBytes); 167 168 DataUsageRequest request2 = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 169 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 170 assertTrue(request2.requestId > request1.requestId); 171 assertTrue(Objects.equals(sTemplateWifi, request2.template)); 172 assertEquals(THRESHOLD_BYTES, request2.thresholdInBytes); 173 } 174 175 public void testUnregister_unknownRequest_noop() throws Exception { 176 DataUsageRequest unknownRequest = new DataUsageRequest( 177 123456 /* id */, sTemplateWifi, THRESHOLD_BYTES); 178 179 mStatsObservers.unregister(unknownRequest, UID_RED); 180 } 181 182 public void testUnregister_knownRequest_releasesCaller() throws Exception { 183 DataUsageRequest inputRequest = new DataUsageRequest( 184 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 185 186 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 187 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 188 assertTrue(request.requestId > 0); 189 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 190 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 191 Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 192 193 mStatsObservers.unregister(request, Process.SYSTEM_UID); 194 waitForObserverToIdle(); 195 196 Mockito.verify(mockBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 197 } 198 199 public void testUnregister_knownRequest_invalidUid_doesNotUnregister() throws Exception { 200 DataUsageRequest inputRequest = new DataUsageRequest( 201 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 202 203 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 204 UID_RED, NetworkStatsAccess.Level.DEVICE); 205 assertTrue(request.requestId > 0); 206 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 207 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 208 Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); 209 210 mStatsObservers.unregister(request, UID_BLUE); 211 waitForObserverToIdle(); 212 213 Mockito.verifyZeroInteractions(mockBinder); 214 } 215 216 public void testUpdateStats_initialSample_doesNotNotify() throws Exception { 217 DataUsageRequest inputRequest = new DataUsageRequest( 218 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 219 220 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 221 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 222 assertTrue(request.requestId > 0); 223 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 224 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 225 226 NetworkIdentitySet identSet = new NetworkIdentitySet(); 227 identSet.add(new NetworkIdentity( 228 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 229 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 230 mActiveIfaces.put(TEST_IFACE, identSet); 231 232 // Baseline 233 NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) 234 .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); 235 NetworkStats uidSnapshot = null; 236 237 mStatsObservers.updateStats( 238 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 239 VPN_INFO, TEST_START); 240 waitForObserverToIdle(); 241 242 assertTrue(mCv.block(WAIT_TIMEOUT)); 243 assertEquals(INVALID_TYPE, mHandler.mLastMessageType); 244 } 245 246 public void testUpdateStats_belowThreshold_doesNotNotify() throws Exception { 247 DataUsageRequest inputRequest = new DataUsageRequest( 248 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 249 250 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 251 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 252 assertTrue(request.requestId > 0); 253 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 254 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 255 256 NetworkIdentitySet identSet = new NetworkIdentitySet(); 257 identSet.add(new NetworkIdentity( 258 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 259 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 260 mActiveIfaces.put(TEST_IFACE, identSet); 261 262 // Baseline 263 NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) 264 .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); 265 NetworkStats uidSnapshot = null; 266 mStatsObservers.updateStats( 267 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 268 VPN_INFO, TEST_START); 269 270 // Delta 271 xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) 272 .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L); 273 mStatsObservers.updateStats( 274 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 275 VPN_INFO, TEST_START); 276 waitForObserverToIdle(); 277 278 assertTrue(mCv.block(WAIT_TIMEOUT)); 279 mCv.block(WAIT_TIMEOUT); 280 assertEquals(INVALID_TYPE, mHandler.mLastMessageType); 281 } 282 283 public void testUpdateStats_deviceAccess_notifies() throws Exception { 284 DataUsageRequest inputRequest = new DataUsageRequest( 285 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 286 287 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 288 Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); 289 assertTrue(request.requestId > 0); 290 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 291 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 292 293 NetworkIdentitySet identSet = new NetworkIdentitySet(); 294 identSet.add(new NetworkIdentity( 295 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 296 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 297 mActiveIfaces.put(TEST_IFACE, identSet); 298 299 // Baseline 300 NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) 301 .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); 302 NetworkStats uidSnapshot = null; 303 mStatsObservers.updateStats( 304 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 305 VPN_INFO, TEST_START); 306 307 // Delta 308 xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */) 309 .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L, 310 BASE_BYTES + THRESHOLD_BYTES, 22L); 311 mStatsObservers.updateStats( 312 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 313 VPN_INFO, TEST_START); 314 waitForObserverToIdle(); 315 316 assertTrue(mCv.block(WAIT_TIMEOUT)); 317 assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType); 318 } 319 320 public void testUpdateStats_defaultAccess_notifiesSameUid() throws Exception { 321 DataUsageRequest inputRequest = new DataUsageRequest( 322 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 323 324 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 325 UID_RED, NetworkStatsAccess.Level.DEFAULT); 326 assertTrue(request.requestId > 0); 327 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 328 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 329 330 NetworkIdentitySet identSet = new NetworkIdentitySet(); 331 identSet.add(new NetworkIdentity( 332 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 333 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 334 mActiveUidIfaces.put(TEST_IFACE, identSet); 335 336 // Baseline 337 NetworkStats xtSnapshot = null; 338 NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) 339 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 340 BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); 341 mStatsObservers.updateStats( 342 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 343 VPN_INFO, TEST_START); 344 345 // Delta 346 uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) 347 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 348 BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); 349 mStatsObservers.updateStats( 350 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 351 VPN_INFO, TEST_START); 352 waitForObserverToIdle(); 353 354 assertTrue(mCv.block(WAIT_TIMEOUT)); 355 assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType); 356 } 357 358 public void testUpdateStats_defaultAccess_usageOtherUid_doesNotNotify() throws Exception { 359 DataUsageRequest inputRequest = new DataUsageRequest( 360 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 361 362 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 363 UID_BLUE, NetworkStatsAccess.Level.DEFAULT); 364 assertTrue(request.requestId > 0); 365 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 366 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 367 368 NetworkIdentitySet identSet = new NetworkIdentitySet(); 369 identSet.add(new NetworkIdentity( 370 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 371 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 372 mActiveUidIfaces.put(TEST_IFACE, identSet); 373 374 // Baseline 375 NetworkStats xtSnapshot = null; 376 NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) 377 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 378 BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); 379 mStatsObservers.updateStats( 380 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 381 VPN_INFO, TEST_START); 382 383 // Delta 384 uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) 385 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 386 BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); 387 mStatsObservers.updateStats( 388 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 389 VPN_INFO, TEST_START); 390 waitForObserverToIdle(); 391 392 assertTrue(mCv.block(WAIT_TIMEOUT)); 393 assertEquals(INVALID_TYPE, mHandler.mLastMessageType); 394 } 395 396 public void testUpdateStats_userAccess_usageSameUser_notifies() throws Exception { 397 DataUsageRequest inputRequest = new DataUsageRequest( 398 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 399 400 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 401 UID_BLUE, NetworkStatsAccess.Level.USER); 402 assertTrue(request.requestId > 0); 403 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 404 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 405 406 NetworkIdentitySet identSet = new NetworkIdentitySet(); 407 identSet.add(new NetworkIdentity( 408 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 409 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 410 mActiveUidIfaces.put(TEST_IFACE, identSet); 411 412 // Baseline 413 NetworkStats xtSnapshot = null; 414 NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) 415 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 416 BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); 417 mStatsObservers.updateStats( 418 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 419 VPN_INFO, TEST_START); 420 421 // Delta 422 uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) 423 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 424 BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); 425 mStatsObservers.updateStats( 426 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 427 VPN_INFO, TEST_START); 428 waitForObserverToIdle(); 429 430 assertTrue(mCv.block(WAIT_TIMEOUT)); 431 assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType); 432 } 433 434 public void testUpdateStats_userAccess_usageAnotherUser_doesNotNotify() throws Exception { 435 DataUsageRequest inputRequest = new DataUsageRequest( 436 DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); 437 438 DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, 439 UID_RED, NetworkStatsAccess.Level.USER); 440 assertTrue(request.requestId > 0); 441 assertTrue(Objects.equals(sTemplateImsi1, request.template)); 442 assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); 443 444 NetworkIdentitySet identSet = new NetworkIdentitySet(); 445 identSet.add(new NetworkIdentity( 446 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, 447 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */)); 448 mActiveUidIfaces.put(TEST_IFACE, identSet); 449 450 // Baseline 451 NetworkStats xtSnapshot = null; 452 NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) 453 .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO, 454 BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); 455 mStatsObservers.updateStats( 456 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 457 VPN_INFO, TEST_START); 458 459 // Delta 460 uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) 461 .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO, 462 BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); 463 mStatsObservers.updateStats( 464 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, 465 VPN_INFO, TEST_START); 466 waitForObserverToIdle(); 467 468 assertTrue(mCv.block(WAIT_TIMEOUT)); 469 assertEquals(INVALID_TYPE, mHandler.mLastMessageType); 470 } 471 472 private void waitForObserverToIdle() { 473 // Send dummy message to make sure that any previous message has been handled 474 mHandler.sendMessage(mHandler.obtainMessage(-1)); 475 mObserverHandlerThread.waitForIdle(WAIT_TIMEOUT); 476 } 477} 478