1 /* 2 * Copyright (C) 2020 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.cts.verifier.car; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.SharedPreferences; 22 import android.os.Bundle; 23 import android.provider.Settings; 24 import android.util.Log; 25 import android.view.View; 26 import android.widget.Button; 27 import android.widget.TextView; 28 29 import com.android.cts.verifier.PassFailButtons; 30 import com.android.cts.verifier.R; 31 32 import java.text.DateFormat; 33 34 /** 35 * Tests that Garage Mode runs at the end of a drive 36 */ 37 public final class GarageModeTestActivity extends PassFailButtons.Activity { 38 // Requirements from Android 11 Compatibility Definition 39 // 2.5.4. Performance and Power 40 // Automotive device implementations: 41 // 42 // [8.3/A-1-3] MUST support Garage Mode 43 // [8.3/A-1-4] SHOULD be in Garage Mode for at least 15 minutes unless: 44 // The battery is drained. 45 // No idle jobs are scheduled. 46 // The driver exits Garage Mode. 47 // 48 // I understand that Google intends to require that Garage Mode is occasionally 49 // allowed to run at least 30 seconds. This code tests for that minimum time. 50 51 private static final String TAG = GarageModeTestActivity.class.getSimpleName(); 52 53 // The recommendation is for Garage Mode to run for 15 minutes. To allow 54 // for some variation, run the test for 14 minutes and verify that it 55 // ran at least 13 minutes. 56 private static final int NUM_SECONDS_DURATION = 14 * 60; 57 private static final long RECOMMENDED_DURATION_MS = (NUM_SECONDS_DURATION - 60) * 1000L; 58 59 // The hard requirement is for Garage Mode to run for 30 seconds. Fail if 60 // the test doesn't run at least this long. 61 private static final long REQUIRED_DURATION_MS = 30 * 1000L; 62 63 // Once a test is started, Garage Mode is expected to start within 10 minutes. If it doesn't, 64 // the test is marked as fail. 65 private static final long MAX_WAIT_UNTIL_GARAGE_MODE = 10 * 60 * 1000L; 66 67 private TextView mStatusText; 68 69 @Override onCreate(Bundle savedInstanceState)70 protected void onCreate(Bundle savedInstanceState) { 71 super.onCreate(savedInstanceState); 72 View view = getLayoutInflater().inflate(R.layout.garage_test_main, null); 73 setContentView(view); 74 75 setInfoResources(R.string.car_garage_mode_test, R.string.car_garage_mode_test_desc, -1); 76 setPassFailButtonClickListeners(); 77 getPassButton().setEnabled(false); 78 mStatusText = findViewById(R.id.car_garage_mode_results); 79 80 // Garage Mode Monitor 81 Button monitorButton = (Button) view.findViewById(R.id.launch_garage_monitor); 82 monitorButton.setOnClickListener((buttonView) -> { 83 Context context = GarageModeTestActivity.this; 84 SharedPreferences prefs = context.getSharedPreferences( 85 GarageModeChecker.PREFS_FILE_NAME, Context.MODE_PRIVATE); 86 long now = System.currentTimeMillis(); 87 SharedPreferences.Editor editor = prefs.edit(); 88 editor.putLong(GarageModeChecker.PREFS_INITIATION, now); 89 editor.putLong(GarageModeChecker.PREFS_GARAGE_MODE_START, 0); 90 editor.putLong(GarageModeChecker.PREFS_GARAGE_MODE_END, 0); 91 editor.putLong(GarageModeChecker.PREFS_TERMINATION, 0); 92 editor.putBoolean(GarageModeChecker.PREFS_HAD_CONNECTIVITY, false); 93 editor.putLong(GarageModeChecker.PREFS_START_BOOT_COUNT, 94 GarageModeChecker.getBootCount(context)); 95 editor.commit(); 96 97 GarageModeChecker.scheduleAnIdleJob(context, NUM_SECONDS_DURATION); 98 verifyStatus(); 99 Log.v(TAG, "Scheduled GarageModeChecker to run when idle"); 100 }); 101 102 // Wifi settings 103 Button wifiButton = view.findViewById(R.id.car_wifi_settings); 104 wifiButton.setOnClickListener( 105 v -> startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS))); 106 } 107 108 @Override onResume()109 protected void onResume() { 110 super.onResume(); 111 verifyStatus(); 112 } 113 114 @Override onWindowFocusChanged(boolean hasWindowFocus)115 public void onWindowFocusChanged(boolean hasWindowFocus) { 116 super.onWindowFocusChanged(hasWindowFocus); 117 if (hasWindowFocus) { 118 verifyStatus(); 119 } 120 } 121 verifyStatus()122 private void verifyStatus() { 123 Context context = GarageModeTestActivity.this; 124 SharedPreferences prefs = context.getSharedPreferences( 125 GarageModeChecker.PREFS_FILE_NAME, Context.MODE_PRIVATE); 126 String resultsString; 127 DateFormat dateTime = DateFormat.getDateTimeInstance(); 128 129 long now = System.currentTimeMillis(); 130 long initiateTime = prefs.getLong(GarageModeChecker.PREFS_INITIATION, 0); 131 long garageModeStart = prefs.getLong(GarageModeChecker.PREFS_GARAGE_MODE_START, 0); 132 long garageModeEnd = prefs.getLong(GarageModeChecker.PREFS_GARAGE_MODE_END, 0); 133 long termination = prefs.getLong(GarageModeChecker.PREFS_TERMINATION, 0); 134 long jobUpdate = prefs.getLong(GarageModeChecker.PREFS_JOB_UPDATE, 0); 135 boolean hadConnectivity = prefs.getBoolean(GarageModeChecker.PREFS_HAD_CONNECTIVITY, false); 136 long startBootCount = prefs.getLong(GarageModeChecker.PREFS_START_BOOT_COUNT, 0); 137 long currentBootCount = GarageModeChecker.getBootCount(context); 138 139 boolean testPassed = false; 140 if (initiateTime == 0) { 141 resultsString = "No results are available.\n\n" 142 + "Perform the indicated steps to run the test."; 143 } else if (garageModeStart == 0) { 144 if (now < initiateTime + MAX_WAIT_UNTIL_GARAGE_MODE) { 145 resultsString = String.format("Waitng for Garage Mode to start.\n\n" 146 + "%s -- Test was enabled", 147 dateTime.format(initiateTime)); 148 } else { 149 resultsString = String.format("Test failed.\n" 150 + "Garage Mode did not run.\n\n" 151 + "%s -- Test was enabled", 152 dateTime.format(initiateTime)); 153 } 154 } else if (garageModeEnd > (garageModeStart + RECOMMENDED_DURATION_MS)) { 155 testPassed = hadConnectivity; 156 resultsString = String.format("Test %s.\n" 157 + "Garage Mode ran as required and for the recommended time.\n" 158 + "Connectivity was %savailable.\n\n" 159 + "%s -- Test was enabled\n" 160 + "%s -- Garage mode started\n" 161 + "%s -- Garage mode completed", 162 (testPassed ? "Passed" : "Failed"), 163 (hadConnectivity ? "" : "not "), 164 dateTime.format(initiateTime), dateTime.format(garageModeStart), 165 dateTime.format(garageModeEnd)); 166 } else if (termination > (garageModeStart + REQUIRED_DURATION_MS)) { 167 testPassed = hadConnectivity; 168 resultsString = String.format("Test %s.\n" 169 + "Garage Mode ran as required, " 170 + "but for less time than is recommended.\n" 171 + " The CDD recommends that Garage Mode runs for 15 minutes.\n" 172 + "Connectivity was %savailable.\n\n" 173 + "%s -- Test was enabled\n" 174 + "%s -- Garage mode started\n" 175 + "%s -- Garage mode was terminated", 176 (testPassed ? "Passed" : "Failed"), 177 (hadConnectivity ? "" : "not "), 178 dateTime.format(initiateTime), dateTime.format(garageModeStart), 179 dateTime.format(termination)); 180 } else if (termination > 0) { 181 resultsString = String.format("Test Failed.\n" 182 + "Garage Mode ran, but for less than the required time.\n" 183 + " The minimum requirement is that Garage Mode runs for 30 seconds.\n" 184 + " The CDD recommends that Garage Mode runs for 15 minutes.\n" 185 + "Connectivity was %savailable.\n\n" 186 + "%s -- Test was enabled\n" 187 + "%s -- Garage mode started\n" 188 + "%s -- Garage mode was terminated", 189 (hadConnectivity ? "" : "not "), 190 dateTime.format(initiateTime), dateTime.format(garageModeStart), 191 dateTime.format(termination)); 192 } else if ((garageModeStart > 0 && garageModeEnd == 0) 193 && (currentBootCount - startBootCount > 0)) { 194 resultsString = "Test failed.\n\n" 195 + "Garage Mode started, but system restarted before it completed.\n\n" 196 + dateTime.format(initiateTime) + " -- Test was enabled\n" 197 + dateTime.format(garageModeStart) + " -- Garage mode started"; 198 } else if (now < jobUpdate + GarageModeChecker.MS_PER_ITERATION * 2) { 199 resultsString = "Garage Mode started and test is running.\n\n" 200 + dateTime.format(initiateTime) + " -- Test was enabled\n" 201 + dateTime.format(garageModeStart) + " -- Garage mode started\n" 202 + dateTime.format(jobUpdate) + " -- Last job updated"; 203 } else { 204 resultsString = "Test failed.\n\n" 205 + "Garage Mode started, but terminated unexpectedly.\n\n" 206 + dateTime.format(initiateTime) + " -- Test was enabled\n" 207 + dateTime.format(garageModeStart) + " -- Garage mode started"; 208 } 209 mStatusText.setText(resultsString); 210 getPassButton().setEnabled(testPassed); 211 } 212 } 213