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 android.accounts.Account; 20 import android.accounts.AccountManager; 21 import android.app.AlarmManager; 22 import android.app.PendingIntent; 23 import android.app.Activity; 24 import android.app.job.JobInfo; 25 import android.app.job.JobScheduler; 26 import android.bluetooth.BluetoothAdapter; 27 import android.bluetooth.le.BluetoothLeScanner; 28 import android.bluetooth.le.ScanCallback; 29 import android.bluetooth.le.ScanFilter; 30 import android.bluetooth.le.ScanResult; 31 import android.bluetooth.le.ScanSettings; 32 import android.content.BroadcastReceiver; 33 import android.content.ComponentName; 34 import android.content.ContentResolver; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.content.IntentFilter; 38 import android.hardware.camera2.CameraDevice; 39 import android.hardware.camera2.CameraManager; 40 import android.hardware.camera2.CameraCharacteristics; 41 import android.hardware.camera2.CameraManager; 42 import android.location.Location; 43 import android.location.LocationListener; 44 import android.location.LocationManager; 45 import android.media.MediaPlayer; 46 import android.net.wifi.WifiManager; 47 import android.os.AsyncTask; 48 import android.os.Bundle; 49 import android.os.Handler; 50 import android.os.HandlerThread; 51 import android.os.Looper; 52 import android.os.PowerManager; 53 import android.os.SystemClock; 54 import android.support.test.InstrumentationRegistry; 55 import android.util.Log; 56 import android.util.StatsLog; 57 58 import static com.android.compatibility.common.util.SystemUtil.runShellCommand; 59 import static org.junit.Assert.assertTrue; 60 import static org.junit.Assert.fail; 61 import org.junit.Test; 62 63 import java.util.Arrays; 64 import java.util.List; 65 import java.util.concurrent.CountDownLatch; 66 import java.util.concurrent.TimeUnit; 67 68 public class AtomTests { 69 private static final String TAG = AtomTests.class.getSimpleName(); 70 71 @Test testAudioState()72 public void testAudioState() { 73 // TODO: This should surely be getTargetContext(), here and everywhere, but test first. 74 Context context = InstrumentationRegistry.getContext(); 75 MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.good); 76 mediaPlayer.start(); 77 sleep(2_000); 78 mediaPlayer.stop(); 79 } 80 81 @Test testBleScanOpportunistic()82 public void testBleScanOpportunistic() { 83 ScanSettings scanSettings = new ScanSettings.Builder() 84 .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC).build(); 85 performBleScan(scanSettings, null,false); 86 } 87 88 @Test testBleScanUnoptimized()89 public void testBleScanUnoptimized() { 90 ScanSettings scanSettings = new ScanSettings.Builder() 91 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); 92 performBleScan(scanSettings, null, false); 93 } 94 95 @Test testBleScanResult()96 public void testBleScanResult() { 97 ScanSettings scanSettings = new ScanSettings.Builder() 98 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); 99 ScanFilter.Builder scanFilter = new ScanFilter.Builder(); 100 performBleScan(scanSettings, Arrays.asList(scanFilter.build()), true); 101 } 102 performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult)103 private static void performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult) { 104 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 105 if (bluetoothAdapter == null) { 106 Log.e(TAG, "Device does not support Bluetooth"); 107 return; 108 } 109 boolean bluetoothEnabledByTest = false; 110 if (!bluetoothAdapter.isEnabled()) { 111 if (!bluetoothAdapter.enable()) { 112 Log.e(TAG, "Bluetooth is not enabled"); 113 return; 114 } 115 sleep(8_000); 116 bluetoothEnabledByTest = true; 117 } 118 BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner(); 119 if (bleScanner == null) { 120 Log.e(TAG, "Cannot access BLE scanner"); 121 return; 122 } 123 124 CountDownLatch resultsLatch = new CountDownLatch(1); 125 ScanCallback scanCallback = new ScanCallback() { 126 @Override 127 public void onScanResult(int callbackType, ScanResult result) { 128 Log.v(TAG, "called onScanResult"); 129 resultsLatch.countDown(); 130 } 131 @Override 132 public void onScanFailed(int errorCode) { 133 Log.v(TAG, "called onScanFailed"); 134 } 135 @Override 136 public void onBatchScanResults(List<ScanResult> results) { 137 Log.v(TAG, "called onBatchScanResults"); 138 resultsLatch.countDown(); 139 } 140 }; 141 142 bleScanner.startScan(scanFilters, scanSettings, scanCallback); 143 if (waitForResult) { 144 waitForReceiver(InstrumentationRegistry.getContext(), 59_000, resultsLatch, null); 145 } else { 146 sleep(2_000); 147 } 148 bleScanner.stopScan(scanCallback); 149 150 // Restore adapter state at end of test 151 if (bluetoothEnabledByTest) { 152 bluetoothAdapter.disable(); 153 } 154 } 155 156 @Test testCameraState()157 public void testCameraState() throws Exception { 158 Context context = InstrumentationRegistry.getContext(); 159 CameraManager cam = context.getSystemService(CameraManager.class); 160 String[] cameraIds = cam.getCameraIdList(); 161 if (cameraIds.length == 0) { 162 Log.e(TAG, "No camera found on device"); 163 return; 164 } 165 166 CountDownLatch latch = new CountDownLatch(1); 167 final CameraDevice.StateCallback cb = new CameraDevice.StateCallback() { 168 @Override 169 public void onOpened(CameraDevice cd) { 170 Log.i(TAG, "CameraDevice " + cd.getId() + " opened"); 171 sleep(2_000); 172 cd.close(); 173 } 174 @Override 175 public void onClosed(CameraDevice cd) { 176 latch.countDown(); 177 Log.i(TAG, "CameraDevice " + cd.getId() + " closed"); 178 } 179 @Override 180 public void onDisconnected(CameraDevice cd) { 181 Log.w(TAG, "CameraDevice " + cd.getId() + " disconnected"); 182 } 183 @Override 184 public void onError(CameraDevice cd, int error) { 185 Log.e(TAG, "CameraDevice " + cd.getId() + "had error " + error); 186 } 187 }; 188 189 HandlerThread handlerThread = new HandlerThread("br_handler_thread"); 190 handlerThread.start(); 191 Looper looper = handlerThread.getLooper(); 192 Handler handler = new Handler(looper); 193 194 cam.openCamera(cameraIds[0], cb, handler); 195 waitForReceiver(context, 10_000, latch, null); 196 } 197 198 @Test testFlashlight()199 public void testFlashlight() throws Exception { 200 Context context = InstrumentationRegistry.getContext(); 201 CameraManager cam = context.getSystemService(CameraManager.class); 202 String[] cameraIds = cam.getCameraIdList(); 203 boolean foundFlash = false; 204 for (int i = 0; i < cameraIds.length; i++) { 205 String id = cameraIds[i]; 206 if(cam.getCameraCharacteristics(id).get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) { 207 cam.setTorchMode(id, true); 208 sleep(500); 209 cam.setTorchMode(id, false); 210 foundFlash = true; 211 break; 212 } 213 } 214 if(!foundFlash) { 215 Log.e(TAG, "No flashlight found on device"); 216 } 217 } 218 219 @Test testForegroundService()220 public void testForegroundService() throws Exception { 221 Context context = InstrumentationRegistry.getContext(); 222 // The service goes into foreground and exits shortly 223 Intent intent = new Intent(context, StatsdCtsForegroundService.class); 224 context.startService(intent); 225 sleep(500); 226 context.stopService(intent); 227 } 228 229 @Test testGpsScan()230 public void testGpsScan() { 231 Context context = InstrumentationRegistry.getContext(); 232 final LocationManager locManager = context.getSystemService(LocationManager.class); 233 if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 234 Log.e(TAG, "GPS provider is not enabled"); 235 return; 236 } 237 CountDownLatch latch = new CountDownLatch(1); 238 239 final LocationListener locListener = new LocationListener() { 240 public void onLocationChanged(Location location) { 241 Log.v(TAG, "onLocationChanged: location has been obtained"); 242 } 243 public void onProviderDisabled(String provider) { 244 Log.w(TAG, "onProviderDisabled " + provider); 245 } 246 public void onProviderEnabled(String provider) { 247 Log.w(TAG, "onProviderEnabled " + provider); 248 } 249 public void onStatusChanged(String provider, int status, Bundle extras) { 250 Log.w(TAG, "onStatusChanged " + provider + " " + status); 251 } 252 }; 253 254 new AsyncTask<Void, Void, Void>() { 255 @Override 256 protected Void doInBackground(Void... params) { 257 Looper.prepare(); 258 locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 990, 0, 259 locListener); 260 sleep(1_000); 261 locManager.removeUpdates(locListener); 262 latch.countDown(); 263 return null; 264 } 265 }.execute(); 266 267 waitForReceiver(context, 59_000, latch, null); 268 } 269 270 @Test testScreenBrightness()271 public void testScreenBrightness() { 272 Context context = InstrumentationRegistry.getContext(); 273 PowerManager pm = context.getSystemService(PowerManager.class); 274 PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | 275 PowerManager.ACQUIRE_CAUSES_WAKEUP, "StatsdBrightnessTest"); 276 wl.acquire(); 277 sleep(500); 278 279 setScreenBrightness(47); 280 sleep(500); 281 setScreenBrightness(100); 282 sleep(500); 283 setScreenBrightness(198); 284 sleep(500); 285 286 287 wl.release(); 288 } 289 290 @Test testSyncState()291 public void testSyncState() throws Exception { 292 293 Context context = InstrumentationRegistry.getContext(); 294 StatsdAuthenticator.removeAllAccounts(context); 295 AccountManager am = context.getSystemService(AccountManager.class); 296 CountDownLatch latch = StatsdSyncAdapter.resetCountDownLatch(); 297 298 Account account = StatsdAuthenticator.getTestAccount(); 299 StatsdAuthenticator.ensureTestAccount(context); 300 sleep(500); 301 302 // Just force set is syncable. 303 ContentResolver.setMasterSyncAutomatically(true); 304 sleep(500); 305 ContentResolver.setIsSyncable(account, StatsdProvider.AUTHORITY, 1); 306 // Wait for the first (automatic) sync to finish 307 waitForReceiver(context, 120_000, latch, null); 308 309 //Sleep for 500ms, since we assert each start/stop to be ~500ms apart. 310 sleep(500); 311 312 // Request and wait for the second sync to finish 313 latch = StatsdSyncAdapter.resetCountDownLatch(); 314 StatsdSyncAdapter.requestSync(account); 315 waitForReceiver(context, 120_000, latch, null); 316 StatsdAuthenticator.removeAllAccounts(context); 317 } 318 319 @Test testScheduledJob()320 public void testScheduledJob() throws Exception { 321 final ComponentName name = new ComponentName("com.android.server.cts.device.statsd", 322 StatsdJobService.class.getName()); 323 324 Context context = InstrumentationRegistry.getContext(); 325 JobScheduler js = context.getSystemService(JobScheduler.class); 326 assertTrue("JobScheduler service not available", js != null); 327 328 JobInfo.Builder builder = new JobInfo.Builder(1, name); 329 builder.setOverrideDeadline(0); 330 JobInfo job = builder.build(); 331 332 long startTime = System.currentTimeMillis(); 333 CountDownLatch latch = StatsdJobService.resetCountDownLatch(); 334 js.schedule(job); 335 waitForReceiver(context, 2_500, latch, null); 336 } 337 338 @Test testWakelockState()339 public void testWakelockState() { 340 Context context = InstrumentationRegistry.getContext(); 341 PowerManager pm = context.getSystemService(PowerManager.class); 342 PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 343 "StatsdPartialWakelock"); 344 wl.acquire(); 345 sleep(500); 346 wl.release(); 347 } 348 349 @Test testWakelockLoad()350 public void testWakelockLoad() { 351 final int NUM_THREADS = 16; 352 CountDownLatch latch = new CountDownLatch(NUM_THREADS); 353 for (int i = 0; i < NUM_THREADS; i++) { 354 Thread t = new Thread(new WakelockLoadTestRunnable("StatsdPartialWakelock" + i, latch)); 355 t.start(); 356 } 357 waitForReceiver(null, 120_000, latch, null); 358 } 359 360 @Test testWakeupAlarm()361 public void testWakeupAlarm() { 362 Context context = InstrumentationRegistry.getContext(); 363 String name = "android.cts.statsd.testWakeupAlarm"; 364 CountDownLatch onReceiveLatch = new CountDownLatch(1); 365 BroadcastReceiver receiver = 366 registerReceiver(context, onReceiveLatch, new IntentFilter(name)); 367 AlarmManager manager = (AlarmManager) (context.getSystemService(AlarmManager.class)); 368 PendingIntent pintent = PendingIntent.getBroadcast(context, 0, new Intent(name), 0); 369 manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 370 SystemClock.elapsedRealtime() + 2_000, pintent); 371 waitForReceiver(context, 10_000, onReceiveLatch, receiver); 372 } 373 374 @Test testWifiLock()375 public void testWifiLock() { 376 Context context = InstrumentationRegistry.getContext(); 377 WifiManager wm = context.getSystemService(WifiManager.class); 378 WifiManager.WifiLock lock = wm.createWifiLock("StatsdCTSWifiLock"); 379 lock.acquire(); 380 sleep(500); 381 lock.release(); 382 } 383 384 @Test testWifiMulticastLock()385 public void testWifiMulticastLock() { 386 Context context = InstrumentationRegistry.getContext(); 387 WifiManager wm = context.getSystemService(WifiManager.class); 388 WifiManager.MulticastLock lock = wm.createMulticastLock("StatsdCTSMulticastLock"); 389 lock.acquire(); 390 sleep(500); 391 lock.release(); 392 } 393 394 @Test 395 /** Does two wifi scans. */ 396 // TODO: Copied this from BatterystatsValidation but we probably don't need to wait for results. testWifiScan()397 public void testWifiScan() { 398 Context context = InstrumentationRegistry.getContext(); 399 IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 400 // Sometimes a scan was already running (from a different uid), so the first scan doesn't 401 // start when requested. Therefore, additionally wait for whatever scan is currently running 402 // to finish, then request a scan again - at least one of these two scans should be 403 // attributed to this app. 404 for (int i = 0; i < 2; i++) { 405 CountDownLatch onReceiveLatch = new CountDownLatch(1); 406 BroadcastReceiver receiver = registerReceiver(context, onReceiveLatch, intentFilter); 407 context.getSystemService(WifiManager.class).startScan(); 408 waitForReceiver(context, 60_000, onReceiveLatch, receiver); 409 } 410 } 411 412 @Test testSimpleCpu()413 public void testSimpleCpu() { 414 long timestamp = System.currentTimeMillis(); 415 for (int i = 0; i < 10000; i ++) { 416 timestamp += i; 417 } 418 Log.i(TAG, "The answer is " + timestamp); 419 } 420 421 // ------- Helper methods 422 423 /** Puts the current thread to sleep. */ sleep(int millis)424 static void sleep(int millis) { 425 try { 426 Thread.sleep(millis); 427 } catch (InterruptedException e) { 428 Log.e(TAG, "Interrupted exception while sleeping", e); 429 } 430 } 431 432 /** Register receiver to determine when given action is complete. */ registerReceiver( Context ctx, CountDownLatch onReceiveLatch, IntentFilter intentFilter)433 private static BroadcastReceiver registerReceiver( 434 Context ctx, CountDownLatch onReceiveLatch, IntentFilter intentFilter) { 435 BroadcastReceiver receiver = new BroadcastReceiver() { 436 @Override 437 public void onReceive(Context context, Intent intent) { 438 Log.d(TAG, "Received broadcast."); 439 onReceiveLatch.countDown(); 440 } 441 }; 442 // Run Broadcast receiver in a different thread since the main thread will wait. 443 HandlerThread handlerThread = new HandlerThread("br_handler_thread"); 444 handlerThread.start(); 445 Looper looper = handlerThread.getLooper(); 446 Handler handler = new Handler(looper); 447 ctx.registerReceiver(receiver, intentFilter, null, handler); 448 return receiver; 449 } 450 451 /** 452 * Uses the receiver to wait until the action is complete. ctx and receiver may be null if no 453 * receiver is needed to be unregistered. 454 */ waitForReceiver(Context ctx, int maxWaitTimeMs, CountDownLatch latch, BroadcastReceiver receiver)455 private static void waitForReceiver(Context ctx, 456 int maxWaitTimeMs, CountDownLatch latch, BroadcastReceiver receiver) { 457 try { 458 boolean didFinish = latch.await(maxWaitTimeMs, TimeUnit.MILLISECONDS); 459 if (didFinish) { 460 Log.v(TAG, "Finished performing action"); 461 } else { 462 // This is not necessarily a problem. If we just want to make sure a count was 463 // recorded for the request, it doesn't matter if the action actually finished. 464 Log.w(TAG, "Did not finish in specified time."); 465 } 466 } catch (InterruptedException e) { 467 Log.e(TAG, "Interrupted exception while awaiting action to finish", e); 468 } 469 if (ctx != null && receiver != null) { 470 ctx.unregisterReceiver(receiver); 471 } 472 } 473 setScreenBrightness(int brightness)474 private static void setScreenBrightness(int brightness) { 475 runShellCommand("settings put system screen_brightness " + brightness); 476 } 477 } 478