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