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 android.cts.statsdatom.sizecompatrestartbutton; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import android.cts.statsdatom.lib.AtomTestUtils; 22 import android.cts.statsdatom.lib.ConfigUtils; 23 import android.cts.statsdatom.lib.DeviceUtils; 24 import android.cts.statsdatom.lib.ReportUtils; 25 26 import com.android.os.AtomsProto; 27 import com.android.os.AtomsProto.SizeCompatRestartButtonEventReported; 28 import com.android.os.AtomsProto.SizeCompatRestartButtonEventReported.Event; 29 import com.android.os.StatsLog; 30 import com.android.tradefed.build.IBuildInfo; 31 import com.android.tradefed.device.ITestDevice; 32 import com.android.tradefed.log.LogUtil.CLog; 33 import com.android.tradefed.testtype.DeviceTestCase; 34 import com.android.tradefed.testtype.IBuildReceiver; 35 import com.android.tradefed.util.Pair; 36 import com.android.tradefed.util.RunUtil; 37 38 import java.util.List; 39 40 /** 41 * This test is for making sure that Size Compat Restart Button appearances and clicks log the 42 * desired atoms. 43 * 44 * <p>Build/Install/Run: 45 * atest CtsStatsdAtomHostTestCases:SizeCompatRestartButtonStatsTests 46 */ 47 // TODO(b/197223993): add test for clicked event 48 public class SizeCompatRestartButtonStatsTests extends DeviceTestCase implements IBuildReceiver { 49 50 private static final String NON_RESIZEABLE_PORTRAIT_ACTIVITY = 51 "StatsdCtsNonResizeablePortraitActivity"; 52 private static final String CMD_GET_STAY_ON = "settings get global stay_on_while_plugged_in"; 53 private static final String CMD_PUT_STAY_ON_TEMPLATE = 54 "settings put global stay_on_while_plugged_in %d"; 55 private static final int ENABLE_STAY_ON_CODE = 7; 56 private static final String CMD_RESET_DEVICE_STATE = "cmd device_state state reset"; 57 private static final String CMD_PUT_DEVICE_STATE_TEMPLATE = "cmd device_state state %d"; 58 private static final String CMD_GET_CURRENT_DEVICE_STATE = "cmd device_state print-state"; 59 private static final int DEVICE_STATE_CLOSED = 0; 60 private static final int DEVICE_STATE_OPENED = 2; 61 62 private IBuildInfo mCtsBuild; 63 private long mOriginalStayOnSetting; 64 private int mOriginalDeviceState; 65 66 @Override setUp()67 protected void setUp() throws Exception { 68 super.setUp(); 69 assertThat(mCtsBuild).isNotNull(); 70 mOriginalStayOnSetting = Long.parseLong( 71 getDevice().executeShellCommand(CMD_GET_STAY_ON).trim()); 72 mOriginalDeviceState = Integer.parseInt( 73 getDevice().executeShellCommand(CMD_GET_CURRENT_DEVICE_STATE).trim()); 74 getDevice().executeShellCommand( 75 String.format(CMD_PUT_STAY_ON_TEMPLATE, ENABLE_STAY_ON_CODE)); 76 getDevice().executeShellCommand( 77 String.format(CMD_PUT_DEVICE_STATE_TEMPLATE, DEVICE_STATE_CLOSED)); 78 ConfigUtils.removeConfig(getDevice()); 79 ReportUtils.clearReports(getDevice()); 80 DeviceUtils.installStatsdTestApp(getDevice(), mCtsBuild); 81 DeviceUtils.turnScreenOn(getDevice()); 82 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 83 ConfigUtils.uploadConfigForPushedAtomWithUid(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 84 AtomsProto.Atom.SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED_FIELD_NUMBER, 85 /*uidInAttributionChain=*/ false); 86 } 87 88 @Override tearDown()89 protected void tearDown() throws Exception { 90 getDevice().executeShellCommand( 91 String.format(CMD_PUT_STAY_ON_TEMPLATE, mOriginalStayOnSetting)); 92 getDevice().executeShellCommand( 93 String.format(CMD_PUT_DEVICE_STATE_TEMPLATE, mOriginalDeviceState)); 94 getDevice().executeShellCommand(CMD_RESET_DEVICE_STATE); 95 ConfigUtils.removeConfig(getDevice()); 96 ReportUtils.clearReports(getDevice()); 97 DeviceUtils.uninstallStatsdTestApp(getDevice()); 98 super.tearDown(); 99 } 100 101 @Override setBuild(IBuildInfo buildInfo)102 public void setBuild(IBuildInfo buildInfo) { 103 mCtsBuild = buildInfo; 104 } 105 testSizeCompatRestartButtonAppearedButNotClicked()106 public void testSizeCompatRestartButtonAppearedButNotClicked() throws Exception { 107 if (!isFoldableStateAvailable(DEVICE_STATE_OPENED) 108 || !isFoldableStateAvailable(DEVICE_STATE_CLOSED)) { 109 CLog.i("Device doesn't support OPENED or CLOSED device states."); 110 return; 111 } 112 113 Pair<Integer, Integer> displaySizeClosed = getDisplayRealSize(getDevice()); 114 if (displaySizeClosed == null) { 115 CLog.i("Could not determine display size while CLOSED."); 116 return; 117 } 118 try (AutoCloseable a = DeviceUtils.withActivity(getDevice(), 119 DeviceUtils.STATSD_ATOM_TEST_PKG, NON_RESIZEABLE_PORTRAIT_ACTIVITY, "action", 120 "action.sleep_top")) { 121 // Wait before unfolding to make sure app is opened. 122 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 123 getDevice().executeShellCommand( 124 String.format(CMD_PUT_DEVICE_STATE_TEMPLATE, DEVICE_STATE_OPENED)); 125 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 126 } 127 128 Pair<Integer, Integer> displaySizeOpened = getDisplayRealSize(getDevice()); 129 if (displaySizeOpened == null) { 130 CLog.i("Could not determine display size while OPENED."); 131 return; 132 } 133 if (displaySizeClosed.equals(displaySizeOpened)) { 134 CLog.i("Display size has not changed."); 135 return; 136 } 137 // Wait to make sure metric event is reported. 138 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 139 List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 140 assertThat(data.size()).isEqualTo(1); 141 142 SizeCompatRestartButtonEventReported atom = 143 data.get(0).getAtom().getSizeCompatRestartButtonEventReported(); 144 assertThat(atom.getUid()).isEqualTo(DeviceUtils.getStatsdTestAppUid(getDevice())); 145 assertThat(atom.getEvent()).isEqualTo(Event.APPEARED); 146 } 147 isFoldableStateAvailable(int state)148 private boolean isFoldableStateAvailable(int state) throws Exception { 149 return getDevice().getFoldableStates().stream().anyMatch( 150 foldableState -> foldableState.getIdentifier() == state); 151 } 152 153 /** 154 * Returns the physical size of the current display used. 155 */ getDisplayRealSize(ITestDevice device)156 private Pair<Integer, Integer> getDisplayRealSize(ITestDevice device) throws Exception { 157 final String physicalSize = "Physical size: "; 158 String str = device.executeShellCommand("wm size"); 159 if (!str.isEmpty()) { 160 String[] lines = str.split(System.getProperty("line.separator")); 161 for (String s : lines) { 162 if (s.contains(physicalSize)) { 163 String substring = s.substring(physicalSize.length()); 164 if (!substring.isEmpty()) { 165 return Pair.create(Integer.parseInt(substring.split("x")[0]), 166 Integer.parseInt(substring.split("x")[1])); 167 } 168 } 169 } 170 } 171 return null; 172 } 173 } 174