1 /* 2 * Copyright (C) 2021 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.tests.scheduling.host; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 22 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 23 24 import org.junit.Test; 25 import org.junit.runner.RunWith; 26 27 import java.util.Scanner; 28 import java.util.concurrent.TimeUnit; 29 30 /** 31 * Host side tests for Reboot Readiness detection. 32 */ 33 @RunWith(DeviceJUnit4ClassRunner.class) 34 public class RebootReadinessHostTest extends BaseHostJUnit4Test { 35 36 private static final String METRIC_TIME_TO_REBOOT_READY = "rebootReadyMs"; 37 private static final String METRIC_TIME_TO_FIRST_UNLOCK = "timeUntilFirstUnlockMs"; 38 private static final String METRIC_BLOCKED_BY_INTERACTIVITY = "blockedByInteractivity"; 39 private static final String METRIC_BLOCKED_BY_COMPONENTS = "blockedBySubsystems"; 40 private static final String METRIC_BLOCKED_BY_APP_ACTIVITY = "blockedByAppActivity"; 41 runPhase(String methodName)42 private void runPhase(String methodName) throws Exception { 43 assertThat(runDeviceTests("com.android.tests.scheduling", 44 "com.android.tests.scheduling.RebootReadinessTest", 45 methodName)).isTrue(); 46 } 47 48 /** 49 * Ensures that the correct metric is logged when the device is in a reboot-ready state 50 * immediately. 51 */ 52 @Test testUnattendedRebootMetrics_Basic()53 public void testUnattendedRebootMetrics_Basic() throws Exception { 54 runPhase("testRebootReadyBroadcastReceived"); 55 56 getDevice().reboot(); 57 getDevice().executeAdbCommand("logcat", "-c"); 58 59 // This command will unlock the device, which will cause the metric to be logged 60 getDevice().executeShellCommand("wm dismiss-keyguard"); 61 62 // Wait a small amount of time for the metrics to be logged, before querying logcat 63 Thread.sleep(2000); 64 String logs = getDevice().executeAdbCommand( 65 "logcat", "-v", "brief", "-d", "RebootReadinessLogger:I", "*:S"); 66 UnattendedRebootMetricEvent event = null; 67 Scanner in = new Scanner(logs); 68 while (in.hasNextLine()) { 69 String line = in.nextLine(); 70 if (line.contains("UnattendedRebootOccurred")) { 71 event = parseUnattendedRebootEvent(line); 72 break; 73 } 74 } 75 in.close(); 76 77 assertThat(event).isNotNull(); 78 assertThat(event.mTimesBlockedByAppActivity).isEqualTo(0); 79 assertThat(event.mTimesBlockedByComponents).isEqualTo(0); 80 assertThat(event.mTimesBlockedByInteractivity).isEqualTo(0); 81 assertThat(event.mTimeToFirstUnlockMs).isAtLeast(0); 82 assertThat(event.mTimeToFirstUnlockMs).isLessThan(TimeUnit.MINUTES.toMillis(1)); 83 assertThat(event.mTimeToRebootReadyMs).isAtLeast(0); 84 assertThat(event.mTimeToRebootReadyMs).isLessThan(TimeUnit.MINUTES.toMillis(1)); 85 } 86 parseUnattendedRebootEvent(String line)87 private UnattendedRebootMetricEvent parseUnattendedRebootEvent(String line) { 88 String[] metricFields = line.split("UnattendedRebootOccurred")[1].trim().split(" "); 89 UnattendedRebootMetricEvent event = new UnattendedRebootMetricEvent(); 90 for (String metric: metricFields) { 91 // Each key-value pair will be of the form "key=value" 92 event.setField(metric.split("=")[0], metric.split("=")[1]); 93 } 94 return event; 95 } 96 97 98 private static final class UnattendedRebootMetricEvent { 99 100 long mTimeToFirstUnlockMs = -1; 101 long mTimeToRebootReadyMs = -1; 102 int mTimesBlockedByInteractivity = -1; 103 int mTimesBlockedByComponents = -1; 104 int mTimesBlockedByAppActivity = -1; 105 UnattendedRebootMetricEvent()106 UnattendedRebootMetricEvent() { 107 } 108 setField(String value, String key)109 void setField(String value, String key) { 110 switch (value) { 111 case METRIC_TIME_TO_REBOOT_READY: 112 mTimeToRebootReadyMs = Long.parseLong(key); 113 break; 114 case METRIC_TIME_TO_FIRST_UNLOCK: 115 mTimeToFirstUnlockMs = Long.parseLong(key); 116 break; 117 case METRIC_BLOCKED_BY_INTERACTIVITY: 118 mTimesBlockedByInteractivity = Integer.parseInt(key); 119 break; 120 case METRIC_BLOCKED_BY_COMPONENTS: 121 mTimesBlockedByComponents = Integer.parseInt(key); 122 break; 123 case METRIC_BLOCKED_BY_APP_ACTIVITY: 124 mTimesBlockedByAppActivity = Integer.parseInt(key); 125 break; 126 default: 127 break; 128 } 129 } 130 } 131 132 } 133