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