1 /* 2 * Copyright (C) 2017 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.cts.device.statsd; 18 19 import static com.android.compatibility.common.util.SystemUtil.runShellCommand; 20 import static com.google.common.truth.Truth.assertWithMessage; 21 22 import android.accounts.Account; 23 import android.accounts.AccountManager; 24 import android.app.ActivityManager; 25 import android.app.ActivityManager.RunningServiceInfo; 26 import android.app.AlarmManager; 27 import android.app.PendingIntent; 28 import android.app.blob.BlobStoreManager; 29 import android.app.job.JobInfo; 30 import android.app.job.JobScheduler; 31 import android.bluetooth.BluetoothAdapter; 32 import android.bluetooth.le.BluetoothLeScanner; 33 import android.bluetooth.le.ScanCallback; 34 import android.bluetooth.le.ScanFilter; 35 import android.bluetooth.le.ScanResult; 36 import android.bluetooth.le.ScanSettings; 37 import android.content.BroadcastReceiver; 38 import android.content.ComponentName; 39 import android.content.ContentResolver; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.content.IntentFilter; 43 import android.content.pm.ApplicationInfo; 44 import android.hardware.camera2.CameraCharacteristics; 45 import android.hardware.camera2.CameraDevice; 46 import android.hardware.camera2.CameraManager; 47 import android.location.GnssStatus; 48 import android.location.Location; 49 import android.location.LocationListener; 50 import android.location.LocationManager; 51 import android.media.MediaPlayer; 52 import android.net.ConnectivityManager; 53 import android.net.Network; 54 import android.net.NetworkCapabilities; 55 import android.net.NetworkRequest; 56 import android.net.cts.util.CtsNetUtils; 57 import android.net.wifi.WifiManager; 58 import android.os.AsyncTask; 59 import android.os.Bundle; 60 import android.os.Handler; 61 import android.os.HandlerThread; 62 import android.os.Looper; 63 import android.os.ParcelFileDescriptor; 64 import android.os.PowerManager; 65 import android.os.Process; 66 import android.os.SystemClock; 67 import android.os.VibrationEffect; 68 import android.os.Vibrator; 69 import android.provider.Settings; 70 import android.text.TextUtils; 71 import android.util.ArrayMap; 72 import android.util.Log; 73 import android.util.StatsEvent; 74 import android.util.StatsLog; 75 import androidx.annotation.NonNull; 76 import androidx.test.InstrumentationRegistry; 77 import com.android.compatibility.common.util.ShellIdentityUtils; 78 import com.google.common.io.BaseEncoding; 79 import java.net.HttpURLConnection; 80 import java.net.URL; 81 import java.util.Arrays; 82 import java.util.List; 83 import java.util.Map; 84 import java.util.concurrent.CompletableFuture; 85 import java.util.concurrent.CountDownLatch; 86 import java.util.concurrent.TimeUnit; 87 import java.util.function.BiConsumer; 88 import org.junit.Test; 89 90 public class AtomTests { 91 private static final String TAG = AtomTests.class.getSimpleName(); 92 93 private static final String MY_PACKAGE_NAME = "com.android.server.cts.device.statsd"; 94 95 @Test testAudioState()96 public void testAudioState() { 97 // TODO: This should surely be getTargetContext(), here and everywhere, but test first. 98 Context context = InstrumentationRegistry.getContext(); 99 MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.good); 100 mediaPlayer.start(); 101 sleep(2_000); 102 mediaPlayer.stop(); 103 } 104 105 @Test testBleScanOpportunistic()106 public void testBleScanOpportunistic() { 107 ScanSettings scanSettings = new ScanSettings.Builder() 108 .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC).build(); 109 performBleScan(scanSettings, null,false); 110 } 111 112 @Test testBleScanUnoptimized()113 public void testBleScanUnoptimized() { 114 ScanSettings scanSettings = new ScanSettings.Builder() 115 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); 116 performBleScan(scanSettings, null, false); 117 } 118 119 @Test testBleScanResult()120 public void testBleScanResult() { 121 ScanSettings scanSettings = new ScanSettings.Builder() 122 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); 123 ScanFilter.Builder scanFilter = new ScanFilter.Builder(); 124 performBleScan(scanSettings, Arrays.asList(scanFilter.build()), true); 125 } 126 127 @Test testBleScanInterrupted()128 public void testBleScanInterrupted() throws Exception { 129 performBleAction((bluetoothAdapter, bleScanner) -> { 130 ScanSettings scanSettings = new ScanSettings.Builder() 131 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); 132 ScanCallback scanCallback = new ScanCallback() { 133 @Override 134 public void onScanResult(int callbackType, ScanResult result) { 135 Log.v(TAG, "called onScanResult"); 136 } 137 @Override 138 public void onScanFailed(int errorCode) { 139 Log.v(TAG, "called onScanFailed"); 140 } 141 @Override 142 public void onBatchScanResults(List<ScanResult> results) { 143 Log.v(TAG, "called onBatchScanResults"); 144 } 145 }; 146 147 int uid = Process.myUid(); 148 int whatAtomId = 9_999; 149 150 // Get the current setting for bluetooth background scanning. 151 // Set to 0 if the setting is not found or an error occurs. 152 int initialBleScanGlobalSetting = Settings.Global.getInt( 153 InstrumentationRegistry.getTargetContext().getContentResolver(), 154 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0); 155 156 // Turn off bluetooth background scanning. 157 Settings.Global.putInt(InstrumentationRegistry.getTargetContext().getContentResolver(), 158 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0); 159 160 // Change state to State.ON. 161 bleScanner.startScan(null, scanSettings, scanCallback); 162 sleep(6_000); 163 writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false); 164 writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false); 165 166 bluetoothAdapter.disable(); 167 sleep(6_000); 168 169 // Trigger State.RESET so that new state is State.OFF. 170 if (!bluetoothAdapter.enable()) { 171 Log.e(TAG, "Could not enable bluetooth to trigger state reset"); 172 return; 173 } 174 sleep(6_000); // Wait for Bluetooth to fully turn on. 175 writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false); 176 writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false); 177 writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false); 178 179 // Set bluetooth background scanning to original setting. 180 Settings.Global.putInt(InstrumentationRegistry.getTargetContext().getContentResolver(), 181 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, initialBleScanGlobalSetting); 182 }); 183 } 184 writeSliceByBleScanStateChangedAtom(int atomId, int firstUid, boolean field2, boolean field3, boolean field4)185 private static void writeSliceByBleScanStateChangedAtom(int atomId, int firstUid, 186 boolean field2, boolean field3, 187 boolean field4) { 188 final StatsEvent.Builder builder = StatsEvent.newBuilder() 189 .setAtomId(atomId) 190 .writeAttributionChain(new int[] {firstUid}, new String[] {"tag1"}) 191 .writeBoolean(field2) 192 .writeBoolean(field3) 193 .writeBoolean(field4) 194 .usePooledBuffer(); 195 196 StatsLog.write(builder.build()); 197 } 198 199 /** 200 * Set up BluetoothLeScanner and perform the action in the callback. 201 * Restore Bluetooth to original state afterwards. 202 **/ performBleAction(BiConsumer<BluetoothAdapter, BluetoothLeScanner> actions)203 private static void performBleAction(BiConsumer<BluetoothAdapter, BluetoothLeScanner> actions) { 204 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 205 if (bluetoothAdapter == null) { 206 Log.e(TAG, "Device does not support Bluetooth"); 207 return; 208 } 209 boolean bluetoothEnabledByTest = false; 210 if (!bluetoothAdapter.isEnabled()) { 211 if (!bluetoothAdapter.enable()) { 212 Log.e(TAG, "Bluetooth is not enabled"); 213 return; 214 } 215 sleep(2_000); // Wait for Bluetooth to fully turn on. 216 bluetoothEnabledByTest = true; 217 } 218 BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner(); 219 if (bleScanner == null) { 220 Log.e(TAG, "Cannot access BLE scanner"); 221 return; 222 } 223 224 actions.accept(bluetoothAdapter, bleScanner); 225 226 // Restore adapter state 227 if (bluetoothEnabledByTest) { 228 bluetoothAdapter.disable(); 229 } 230 } 231 232 performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult)233 private static void performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult) { 234 performBleAction((bluetoothAdapter, bleScanner) -> { 235 CountDownLatch resultsLatch = new CountDownLatch(1); 236 ScanCallback scanCallback = new ScanCallback() { 237 @Override 238 public void onScanResult(int callbackType, ScanResult result) { 239 Log.v(TAG, "called onScanResult"); 240 resultsLatch.countDown(); 241 } 242 @Override 243 public void onScanFailed(int errorCode) { 244 Log.v(TAG, "called onScanFailed"); 245 } 246 @Override 247 public void onBatchScanResults(List<ScanResult> results) { 248 Log.v(TAG, "called onBatchScanResults"); 249 resultsLatch.countDown(); 250 } 251 }; 252 253 bleScanner.startScan(scanFilters, scanSettings, scanCallback); 254 if (waitForResult) { 255 waitForReceiver(InstrumentationRegistry.getContext(), 59_000, resultsLatch, null); 256 } else { 257 sleep(2_000); 258 } 259 bleScanner.stopScan(scanCallback); 260 }); 261 } 262 263 @Test testCameraState()264 public void testCameraState() throws Exception { 265 Context context = InstrumentationRegistry.getContext(); 266 CameraManager cam = context.getSystemService(CameraManager.class); 267 String[] cameraIds = cam.getCameraIdList(); 268 if (cameraIds.length == 0) { 269 Log.e(TAG, "No camera found on device"); 270 return; 271 } 272 273 CountDownLatch latch = new CountDownLatch(1); 274 final CameraDevice.StateCallback cb = new CameraDevice.StateCallback() { 275 @Override 276 public void onOpened(CameraDevice cd) { 277 Log.i(TAG, "CameraDevice " + cd.getId() + " opened"); 278 sleep(2_000); 279 cd.close(); 280 } 281 @Override 282 public void onClosed(CameraDevice cd) { 283 latch.countDown(); 284 Log.i(TAG, "CameraDevice " + cd.getId() + " closed"); 285 } 286 @Override 287 public void onDisconnected(CameraDevice cd) { 288 Log.w(TAG, "CameraDevice " + cd.getId() + " disconnected"); 289 } 290 @Override 291 public void onError(CameraDevice cd, int error) { 292 Log.e(TAG, "CameraDevice " + cd.getId() + "had error " + error); 293 } 294 }; 295 296 HandlerThread handlerThread = new HandlerThread("br_handler_thread"); 297 handlerThread.start(); 298 Looper looper = handlerThread.getLooper(); 299 Handler handler = new Handler(looper); 300 301 cam.openCamera(cameraIds[0], cb, handler); 302 waitForReceiver(context, 10_000, latch, null); 303 } 304 305 @Test testFlashlight()306 public void testFlashlight() throws Exception { 307 Context context = InstrumentationRegistry.getContext(); 308 CameraManager cam = context.getSystemService(CameraManager.class); 309 String[] cameraIds = cam.getCameraIdList(); 310 boolean foundFlash = false; 311 for (int i = 0; i < cameraIds.length; i++) { 312 String id = cameraIds[i]; 313 if(cam.getCameraCharacteristics(id).get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) { 314 cam.setTorchMode(id, true); 315 sleep(500); 316 cam.setTorchMode(id, false); 317 foundFlash = true; 318 break; 319 } 320 } 321 if(!foundFlash) { 322 Log.e(TAG, "No flashlight found on device"); 323 } 324 } 325 326 @Test testForegroundService()327 public void testForegroundService() throws Exception { 328 Context context = InstrumentationRegistry.getContext(); 329 // The service goes into foreground and exits shortly 330 Intent intent = new Intent(context, StatsdCtsForegroundService.class); 331 context.startService(intent); 332 sleep(500); 333 context.stopService(intent); 334 } 335 336 /** Check if service is running. */ checkIfServiceRunning(Context context, String serviceName)337 public boolean checkIfServiceRunning(Context context, String serviceName) { 338 ActivityManager manager = context.getSystemService(ActivityManager.class); 339 for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 340 if (serviceName.equals(service.service.getClassName()) && service.foreground) { 341 return true; 342 } 343 } 344 return false; 345 } 346 347 @Test testGpsScan()348 public void testGpsScan() { 349 Context context = InstrumentationRegistry.getContext(); 350 final LocationManager locManager = context.getSystemService(LocationManager.class); 351 if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 352 Log.e(TAG, "GPS provider is not enabled"); 353 return; 354 } 355 CountDownLatch latch = new CountDownLatch(1); 356 357 final LocationListener locListener = new LocationListener() { 358 public void onLocationChanged(Location location) { 359 Log.v(TAG, "onLocationChanged: location has been obtained"); 360 } 361 public void onProviderDisabled(String provider) { 362 Log.w(TAG, "onProviderDisabled " + provider); 363 } 364 public void onProviderEnabled(String provider) { 365 Log.w(TAG, "onProviderEnabled " + provider); 366 } 367 public void onStatusChanged(String provider, int status, Bundle extras) { 368 Log.w(TAG, "onStatusChanged " + provider + " " + status); 369 } 370 }; 371 372 new AsyncTask<Void, Void, Void>() { 373 @Override 374 protected Void doInBackground(Void... params) { 375 Looper.prepare(); 376 locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 990, 0, 377 locListener); 378 sleep(1_000); 379 locManager.removeUpdates(locListener); 380 latch.countDown(); 381 return null; 382 } 383 }.execute(); 384 385 waitForReceiver(context, 59_000, latch, null); 386 } 387 388 @Test testGpsStatus()389 public void testGpsStatus() { 390 Context context = InstrumentationRegistry.getContext(); 391 final LocationManager locManager = context.getSystemService(LocationManager.class); 392 393 if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 394 Log.e(TAG, "GPS provider is not enabled"); 395 return; 396 } 397 398 // Time out set to 85 seconds (5 seconds for sleep and a possible 85 seconds if TTFF takes 399 // max time which would be around 90 seconds. 400 // This is based on similar location cts test timeout values. 401 final int TIMEOUT_IN_MSEC = 85_000; 402 final int SLEEP_TIME_IN_MSEC = 5_000; 403 404 final CountDownLatch mLatchNetwork = new CountDownLatch(1); 405 406 final LocationListener locListener = location -> { 407 Log.v(TAG, "onLocationChanged: location has been obtained"); 408 mLatchNetwork.countDown(); 409 }; 410 411 // fetch the networklocation first to make sure the ttff is not flaky 412 if (locManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { 413 Log.i(TAG, "Request Network Location updates."); 414 locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 415 0 /* minTime*/, 416 0 /* minDistance */, 417 locListener, 418 Looper.getMainLooper()); 419 } 420 waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchNetwork, null); 421 422 // TTFF could take up to 90 seconds, thus we need to wait till TTFF does occur if it does 423 // not occur in the first SLEEP_TIME_IN_MSEC 424 final CountDownLatch mLatchTtff = new CountDownLatch(1); 425 426 GnssStatus.Callback gnssStatusCallback = new GnssStatus.Callback() { 427 @Override 428 public void onStarted() { 429 Log.v(TAG, "Gnss Status Listener Started"); 430 } 431 432 @Override 433 public void onStopped() { 434 Log.v(TAG, "Gnss Status Listener Stopped"); 435 } 436 437 @Override 438 public void onFirstFix(int ttffMillis) { 439 Log.v(TAG, "Gnss Status Listener Received TTFF"); 440 mLatchTtff.countDown(); 441 } 442 443 @Override 444 public void onSatelliteStatusChanged(GnssStatus status) { 445 Log.v(TAG, "Gnss Status Listener Received Status Update"); 446 } 447 }; 448 449 boolean gnssStatusCallbackAdded = locManager.registerGnssStatusCallback( 450 gnssStatusCallback, new Handler(Looper.getMainLooper())); 451 if (!gnssStatusCallbackAdded) { 452 // Registration of GnssMeasurements listener has failed, this indicates a platform bug. 453 Log.e(TAG, "Failed to start gnss status callback"); 454 } 455 456 locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 457 0, 458 0 /* minDistance */, 459 locListener, 460 Looper.getMainLooper()); 461 sleep(SLEEP_TIME_IN_MSEC); 462 waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchTtff, null); 463 locManager.removeUpdates(locListener); 464 locManager.unregisterGnssStatusCallback(gnssStatusCallback); 465 } 466 467 @Test testScreenBrightness()468 public void testScreenBrightness() { 469 Context context = InstrumentationRegistry.getContext(); 470 PowerManager pm = context.getSystemService(PowerManager.class); 471 PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | 472 PowerManager.ACQUIRE_CAUSES_WAKEUP, "StatsdBrightnessTest"); 473 wl.acquire(); 474 sleep(500); 475 476 setScreenBrightness(47); 477 sleep(500); 478 setScreenBrightness(100); 479 sleep(500); 480 setScreenBrightness(198); 481 sleep(500); 482 483 484 wl.release(); 485 } 486 487 @Test testSyncState()488 public void testSyncState() throws Exception { 489 490 Context context = InstrumentationRegistry.getContext(); 491 StatsdAuthenticator.removeAllAccounts(context); 492 AccountManager am = context.getSystemService(AccountManager.class); 493 CountDownLatch latch = StatsdSyncAdapter.resetCountDownLatch(); 494 495 Account account = StatsdAuthenticator.getTestAccount(); 496 StatsdAuthenticator.ensureTestAccount(context); 497 sleep(500); 498 499 // Just force set is syncable. 500 ContentResolver.setMasterSyncAutomatically(true); 501 sleep(500); 502 ContentResolver.setIsSyncable(account, StatsdProvider.AUTHORITY, 1); 503 // Wait for the first (automatic) sync to finish 504 waitForReceiver(context, 120_000, latch, null); 505 506 //Sleep for 500ms, since we assert each start/stop to be ~500ms apart. 507 sleep(500); 508 509 // Request and wait for the second sync to finish 510 latch = StatsdSyncAdapter.resetCountDownLatch(); 511 StatsdSyncAdapter.requestSync(account); 512 waitForReceiver(context, 120_000, latch, null); 513 StatsdAuthenticator.removeAllAccounts(context); 514 } 515 516 @Test testScheduledJob()517 public void testScheduledJob() throws Exception { 518 final ComponentName name = new ComponentName(MY_PACKAGE_NAME, 519 StatsdJobService.class.getName()); 520 521 Context context = InstrumentationRegistry.getContext(); 522 JobScheduler js = context.getSystemService(JobScheduler.class); 523 assertWithMessage("JobScheduler service not available").that(js).isNotNull(); 524 525 JobInfo.Builder builder = new JobInfo.Builder(1, name); 526 builder.setOverrideDeadline(0); 527 JobInfo job = builder.build(); 528 529 long startTime = System.currentTimeMillis(); 530 CountDownLatch latch = StatsdJobService.resetCountDownLatch(); 531 js.schedule(job); 532 waitForReceiver(context, 5_000, latch, null); 533 } 534 535 @Test testVibratorState()536 public void testVibratorState() { 537 Context context = InstrumentationRegistry.getContext(); 538 Vibrator vib = context.getSystemService(Vibrator.class); 539 if (vib.hasVibrator()) { 540 vib.vibrate(VibrationEffect.createOneShot( 541 500 /* ms */, VibrationEffect.DEFAULT_AMPLITUDE)); 542 } 543 } 544 545 @Test testWakelockState()546 public void testWakelockState() { 547 Context context = InstrumentationRegistry.getContext(); 548 PowerManager pm = context.getSystemService(PowerManager.class); 549 PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 550 "StatsdPartialWakelock"); 551 wl.acquire(); 552 sleep(500); 553 wl.release(); 554 } 555 556 @Test testSliceByWakelockState()557 public void testSliceByWakelockState() { 558 int uid = Process.myUid(); 559 int whatAtomId = 9_998; 560 int wakelockType = PowerManager.PARTIAL_WAKE_LOCK; 561 String tag = "StatsdPartialWakelock"; 562 563 Context context = InstrumentationRegistry.getContext(); 564 PowerManager pm = context.getSystemService(PowerManager.class); 565 PowerManager.WakeLock wl = pm.newWakeLock(wakelockType, tag); 566 567 wl.acquire(); 568 sleep(500); 569 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 570 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 571 wl.acquire(); 572 sleep(500); 573 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 574 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 575 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 576 wl.release(); 577 sleep(500); 578 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 579 wl.release(); 580 sleep(500); 581 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 582 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 583 writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag); 584 } 585 writeSliceByWakelockStateChangedAtom(int atomId, int firstUid, int field2, String field3)586 private static void writeSliceByWakelockStateChangedAtom(int atomId, int firstUid, 587 int field2, String field3) { 588 final StatsEvent.Builder builder = StatsEvent.newBuilder() 589 .setAtomId(atomId) 590 .writeAttributionChain(new int[] {firstUid}, new String[] {"tag1"}) 591 .writeInt(field2) 592 .writeString(field3) 593 .usePooledBuffer(); 594 595 StatsLog.write(builder.build()); 596 } 597 598 599 @Test testWakelockLoad()600 public void testWakelockLoad() { 601 final int NUM_THREADS = 16; 602 CountDownLatch latch = new CountDownLatch(NUM_THREADS); 603 for (int i = 0; i < NUM_THREADS; i++) { 604 Thread t = new Thread(new WakelockLoadTestRunnable("StatsdPartialWakelock" + i, latch)); 605 t.start(); 606 } 607 waitForReceiver(null, 120_000, latch, null); 608 } 609 610 @Test testWakeupAlarm()611 public void testWakeupAlarm() { 612 Context context = InstrumentationRegistry.getContext(); 613 String name = "android.cts.statsd.testWakeupAlarm"; 614 CountDownLatch onReceiveLatch = new CountDownLatch(1); 615 BroadcastReceiver receiver = 616 registerReceiver(context, onReceiveLatch, new IntentFilter(name)); 617 AlarmManager manager = (AlarmManager) (context.getSystemService(AlarmManager.class)); 618 PendingIntent pintent = PendingIntent.getBroadcast(context, 0, new Intent(name), 0); 619 manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 620 SystemClock.elapsedRealtime() + 2_000, pintent); 621 waitForReceiver(context, 10_000, onReceiveLatch, receiver); 622 } 623 624 @Test testWifiLockHighPerf()625 public void testWifiLockHighPerf() { 626 Context context = InstrumentationRegistry.getContext(); 627 WifiManager wm = context.getSystemService(WifiManager.class); 628 WifiManager.WifiLock lock = 629 wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "StatsdCTSWifiLock"); 630 lock.acquire(); 631 sleep(500); 632 lock.release(); 633 } 634 635 @Test testWifiLockLowLatency()636 public void testWifiLockLowLatency() { 637 Context context = InstrumentationRegistry.getContext(); 638 WifiManager wm = context.getSystemService(WifiManager.class); 639 WifiManager.WifiLock lock = 640 wm.createWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "StatsdCTSWifiLock"); 641 lock.acquire(); 642 sleep(500); 643 lock.release(); 644 } 645 646 @Test testWifiMulticastLock()647 public void testWifiMulticastLock() { 648 Context context = InstrumentationRegistry.getContext(); 649 WifiManager wm = context.getSystemService(WifiManager.class); 650 WifiManager.MulticastLock lock = wm.createMulticastLock("StatsdCTSMulticastLock"); 651 lock.acquire(); 652 sleep(500); 653 lock.release(); 654 } 655 656 @Test 657 /** Does two wifi scans. */ 658 // TODO: Copied this from BatterystatsValidation but we probably don't need to wait for results. testWifiScan()659 public void testWifiScan() { 660 Context context = InstrumentationRegistry.getContext(); 661 IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 662 // Sometimes a scan was already running (from a different uid), so the first scan doesn't 663 // start when requested. Therefore, additionally wait for whatever scan is currently running 664 // to finish, then request a scan again - at least one of these two scans should be 665 // attributed to this app. 666 for (int i = 0; i < 2; i++) { 667 CountDownLatch onReceiveLatch = new CountDownLatch(1); 668 BroadcastReceiver receiver = registerReceiver(context, onReceiveLatch, intentFilter); 669 context.getSystemService(WifiManager.class).startScan(); 670 waitForReceiver(context, 60_000, onReceiveLatch, receiver); 671 } 672 } 673 674 @Test testSimpleCpu()675 public void testSimpleCpu() { 676 long timestamp = System.currentTimeMillis(); 677 for (int i = 0; i < 10000; i ++) { 678 timestamp += i; 679 } 680 Log.i(TAG, "The answer is " + timestamp); 681 } 682 683 @Test testWriteRawTestAtom()684 public void testWriteRawTestAtom() throws Exception { 685 Context context = InstrumentationRegistry.getTargetContext(); 686 ApplicationInfo appInfo = context.getPackageManager() 687 .getApplicationInfo(context.getPackageName(), 0); 688 int[] uids = {1234, appInfo.uid}; 689 String[] tags = {"tag1", "tag2"}; 690 byte[] experimentIds = {8, 1, 8, 2, 8, 3}; // Corresponds to 1, 2, 3. 691 StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, uids, tags, 42, 692 Long.MAX_VALUE, 3.14f, "This is a basic test!", false, 693 StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__ON, experimentIds); 694 695 // All nulls. Should get dropped since cts app is not in the attribution chain. 696 StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, null, null, 0, 0, 697 0f, null, false, StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__ON, null); 698 699 // Null tag in attribution chain. 700 int[] uids2 = {9999, appInfo.uid}; 701 String[] tags2 = {"tag9999", null}; 702 StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, uids2, tags2, 100, 703 Long.MIN_VALUE, -2.5f, "Test null uid", true, 704 StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__UNKNOWN, experimentIds); 705 706 // Non chained non-null 707 StatsLogStatsdCts.write_non_chained(StatsLogStatsdCts.TEST_ATOM_REPORTED, 708 appInfo.uid, "tag1", -256, -1234567890L, 42.01f, "Test non chained", true, 709 StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__OFF, experimentIds); 710 711 // Non chained all null 712 StatsLogStatsdCts.write_non_chained(StatsLogStatsdCts.TEST_ATOM_REPORTED, appInfo.uid, null, 713 0, 0, 0f, null, true, StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__OFF, null); 714 715 } 716 717 /** 718 * Bring up and generate some traffic on cellular data connection. 719 */ 720 @Test testGenerateMobileTraffic()721 public void testGenerateMobileTraffic() throws Exception { 722 final Context context = InstrumentationRegistry.getContext(); 723 doGenerateNetworkTraffic(context, NetworkCapabilities.TRANSPORT_CELLULAR); 724 } 725 726 // Constants which are locally used by doGenerateNetworkTraffic. 727 private static final int NETWORK_TIMEOUT_MILLIS = 15000; 728 private static final String HTTPS_HOST_URL = 729 "https://connectivitycheck.gstatic.com/generate_204"; 730 doGenerateNetworkTraffic(@onNull Context context, int transport)731 private void doGenerateNetworkTraffic(@NonNull Context context, int transport) 732 throws InterruptedException { 733 final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); 734 final NetworkRequest request = new NetworkRequest.Builder().addCapability( 735 NetworkCapabilities.NET_CAPABILITY_INTERNET).addTransportType(transport).build(); 736 final CtsNetUtils.TestNetworkCallback callback = new CtsNetUtils.TestNetworkCallback(); 737 738 // Request network, and make http query when the network is available. 739 cm.requestNetwork(request, callback); 740 741 // If network is not available, throws IllegalStateException. 742 final Network network = callback.waitForAvailable(); 743 if (network == null) { 744 throw new IllegalStateException("network " + request + " is not available."); 745 } 746 747 final long startTime = SystemClock.elapsedRealtime(); 748 try { 749 exerciseRemoteHost(cm, network, new URL(HTTPS_HOST_URL)); 750 Log.i(TAG, "exerciseRemoteHost successful in " + (SystemClock.elapsedRealtime() 751 - startTime) + " ms"); 752 } catch (Exception e) { 753 Log.e(TAG, "exerciseRemoteHost failed in " + (SystemClock.elapsedRealtime() 754 - startTime) + " ms: " + e); 755 } finally { 756 cm.unregisterNetworkCallback(callback); 757 } 758 } 759 760 /** 761 * Generate traffic on specified network. 762 */ exerciseRemoteHost(@onNull ConnectivityManager cm, @NonNull Network network, @NonNull URL url)763 private void exerciseRemoteHost(@NonNull ConnectivityManager cm, @NonNull Network network, 764 @NonNull URL url) throws Exception { 765 cm.bindProcessToNetwork(network); 766 HttpURLConnection urlc = null; 767 try { 768 urlc = (HttpURLConnection) network.openConnection(url); 769 urlc.setConnectTimeout(NETWORK_TIMEOUT_MILLIS); 770 urlc.setUseCaches(false); 771 urlc.connect(); 772 } finally { 773 if (urlc != null) { 774 urlc.disconnect(); 775 } 776 } 777 } 778 779 // Constants for testBlobStore 780 private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5; 781 private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000; 782 private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L; 783 private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000; 784 private static final byte[] FAKE_PKG_CERT_SHA256 = BaseEncoding.base16().decode( 785 "187E3D3172F2177D6FEC2EA53785BF1E25DFF7B2E5F6E59807E365A7A837E6C3"); 786 787 // ------- Helper methods 788 789 /** Puts the current thread to sleep. */ sleep(int millis)790 static void sleep(int millis) { 791 try { 792 Thread.sleep(millis); 793 } catch (InterruptedException e) { 794 Log.e(TAG, "Interrupted exception while sleeping", e); 795 } 796 } 797 798 /** Register receiver to determine when given action is complete. */ registerReceiver( Context ctx, CountDownLatch onReceiveLatch, IntentFilter intentFilter)799 private static BroadcastReceiver registerReceiver( 800 Context ctx, CountDownLatch onReceiveLatch, IntentFilter intentFilter) { 801 BroadcastReceiver receiver = new BroadcastReceiver() { 802 @Override 803 public void onReceive(Context context, Intent intent) { 804 Log.d(TAG, "Received broadcast."); 805 onReceiveLatch.countDown(); 806 } 807 }; 808 // Run Broadcast receiver in a different thread since the main thread will wait. 809 HandlerThread handlerThread = new HandlerThread("br_handler_thread"); 810 handlerThread.start(); 811 Looper looper = handlerThread.getLooper(); 812 Handler handler = new Handler(looper); 813 ctx.registerReceiver(receiver, intentFilter, null, handler); 814 return receiver; 815 } 816 817 /** 818 * Uses the receiver to wait until the action is complete. ctx and receiver may be null if no 819 * receiver is needed to be unregistered. 820 */ waitForReceiver(Context ctx, int maxWaitTimeMs, CountDownLatch latch, BroadcastReceiver receiver)821 private static void waitForReceiver(Context ctx, 822 int maxWaitTimeMs, CountDownLatch latch, BroadcastReceiver receiver) { 823 try { 824 boolean didFinish = latch.await(maxWaitTimeMs, TimeUnit.MILLISECONDS); 825 if (didFinish) { 826 Log.v(TAG, "Finished performing action"); 827 } else { 828 // This is not necessarily a problem. If we just want to make sure a count was 829 // recorded for the request, it doesn't matter if the action actually finished. 830 Log.w(TAG, "Did not finish in specified time."); 831 } 832 } catch (InterruptedException e) { 833 Log.e(TAG, "Interrupted exception while awaiting action to finish", e); 834 } 835 if (ctx != null && receiver != null) { 836 ctx.unregisterReceiver(receiver); 837 } 838 } 839 setScreenBrightness(int brightness)840 private static void setScreenBrightness(int brightness) { 841 runShellCommand("settings put system screen_brightness " + brightness); 842 } 843 } 844