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 android.cts.statsdatom.appstart; 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.annotations.Nullable; 27 import com.android.os.AtomsProto; 28 import com.android.os.StatsLog; 29 import com.android.tradefed.build.IBuildInfo; 30 import com.android.tradefed.testtype.DeviceTestCase; 31 import com.android.tradefed.testtype.IBuildReceiver; 32 33 import java.util.List; 34 35 public class AppStartStatsTests extends DeviceTestCase implements IBuildReceiver { 36 public static final String CMD_APP_HIBERNATION_SET_STATE_GLOBAL = 37 "cmd app_hibernation set-state --global "; 38 public static final String STATSD_CTS_FOREGROUND_ACTIVITY = "StatsdCtsForegroundActivity"; 39 public static final int WAIT_TIME_MS = 3_500; 40 public static final String COMMAND_ENABLE_APP_HIBERNATION = 41 "device_config put app_hibernation app_hibernation_enabled true"; 42 private static final String CMD_GET_STAY_ON = "settings get global stay_on_while_plugged_in"; 43 private static final String CMD_PUT_STAY_ON_TEMPLATE = 44 "settings put global stay_on_while_plugged_in %d"; 45 private static final String CMD_ENABLE_STAY_ON = 46 "settings put global stay_on_while_plugged_in 7"; 47 private IBuildInfo mCtsBuild; 48 private long mOriginalStayOnSetting; 49 50 @Override setUp()51 protected void setUp() throws Exception { 52 super.setUp(); 53 assertThat(mCtsBuild).isNotNull(); 54 ConfigUtils.removeConfig(getDevice()); 55 ReportUtils.clearReports(getDevice()); 56 DeviceUtils.installStatsdTestApp(getDevice(), mCtsBuild); 57 mOriginalStayOnSetting = Long.parseLong( 58 getDevice().executeShellCommand(CMD_GET_STAY_ON).trim()); 59 getDevice().executeShellCommand(CMD_ENABLE_STAY_ON); 60 DeviceUtils.turnScreenOn(getDevice()); 61 Thread.sleep(AtomTestUtils.WAIT_TIME_LONG); 62 } 63 64 @Override tearDown()65 protected void tearDown() throws Exception { 66 getDevice().executeShellCommand( 67 String.format(CMD_PUT_STAY_ON_TEMPLATE, mOriginalStayOnSetting)); 68 ConfigUtils.removeConfig(getDevice()); 69 ReportUtils.clearReports(getDevice()); 70 DeviceUtils.uninstallStatsdTestApp(getDevice()); 71 super.tearDown(); 72 } 73 74 @Override setBuild(IBuildInfo buildInfo)75 public void setBuild(IBuildInfo buildInfo) { 76 mCtsBuild = buildInfo; 77 } 78 testAppStartOccurred()79 public void testAppStartOccurred() throws Exception { 80 runTestAppStartOccurredCommon(null, atom -> { 81 assertThat(atom.getType()).isEqualTo( 82 AtomsProto.AppStartOccurred.TransitionType.COLD); 83 assertThat(atom.getProcessState()).isEqualTo( 84 AtomsProto.AppStartOccurred.AppProcessState.PROCESS_STATE_NONEXISTENT); 85 }); 86 } 87 testAppStartOccurredWarm()88 public void testAppStartOccurredWarm() throws Exception { 89 runTestAppStartOccurredCommon(() -> { 90 DeviceUtils.executeBackgroundService(getDevice(), "action.end_immediately"); 91 Thread.sleep(WAIT_TIME_MS); 92 }, atom -> { 93 assertThat(atom.getType()).isEqualTo( 94 AtomsProto.AppStartOccurred.TransitionType.WARM); 95 assertThat(atom.getProcessState()).isEqualTo( 96 AtomsProto.AppStartOccurred.AppProcessState.PROCESS_STATE_CACHED_EMPTY); 97 }); 98 } 99 100 private interface RunnableWithException { run()101 void run() throws Exception; 102 } 103 104 private interface ConsumerWithException<T> { accept(T t)105 void accept(T t) throws Exception; 106 } 107 runTestAppStartOccurredCommon(@ullable RunnableWithException prolog, @Nullable ConsumerWithException<AtomsProto.AppStartOccurred> epilog)108 private void runTestAppStartOccurredCommon(@Nullable RunnableWithException prolog, 109 @Nullable ConsumerWithException<AtomsProto.AppStartOccurred> epilog) throws Exception { 110 final int atomTag = AtomsProto.Atom.APP_START_OCCURRED_FIELD_NUMBER; 111 ConfigUtils.uploadConfigForPushedAtomWithUid(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 112 atomTag, /*uidInAttributionChain=*/false); 113 getDevice().executeShellCommand(getGlobalHibernationCommand( 114 DeviceUtils.STATSD_ATOM_TEST_PKG, false)); 115 116 if (prolog != null) { 117 prolog.run(); 118 } 119 120 DeviceUtils.runActivity(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 121 STATSD_CTS_FOREGROUND_ACTIVITY, "action", "action.sleep_top", WAIT_TIME_MS); 122 123 // Sorted list of events in order in which they occurred. 124 List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 125 126 assertThat(data).hasSize(1); 127 AtomsProto.AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred(); 128 assertThat(atom.getPkgName()).isEqualTo(DeviceUtils.STATSD_ATOM_TEST_PKG); 129 assertThat(atom.getActivityName()) 130 .isEqualTo("com.android.server.cts.device.statsdatom.StatsdCtsForegroundActivity"); 131 assertThat(atom.getIsInstantApp()).isFalse(); 132 assertThat(atom.getActivityStartTimestampMillis()).isGreaterThan(0L); 133 assertThat(atom.getTransitionDelayMillis()).isGreaterThan(0); 134 assertThat(atom.getIsHibernating()).isFalse(); 135 if (epilog != null) { 136 epilog.accept(atom); 137 } 138 } 139 testHibernatingAppStartOccurred()140 public void testHibernatingAppStartOccurred() throws Exception { 141 final int atomTag = AtomsProto.Atom.APP_START_OCCURRED_FIELD_NUMBER; 142 ConfigUtils.uploadConfigForPushedAtomWithUid(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 143 atomTag, /*uidInAttributionChain=*/false); 144 getDevice().executeShellCommand(COMMAND_ENABLE_APP_HIBERNATION); 145 getDevice().executeShellCommand(getGlobalHibernationCommand( 146 DeviceUtils.STATSD_ATOM_TEST_PKG, true)); 147 148 DeviceUtils.runActivity(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 149 STATSD_CTS_FOREGROUND_ACTIVITY, "action", "action.sleep_top", WAIT_TIME_MS); 150 151 // Sorted list of events in order in which they occurred. 152 List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 153 assertThat(data).hasSize(1); 154 AtomsProto.AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred(); 155 assertThat(atom.getIsHibernating()).isTrue(); 156 } 157 testHibernatingAppStartOccurredTwice_isHibernatingShouldBeFalseSecondTime()158 public void testHibernatingAppStartOccurredTwice_isHibernatingShouldBeFalseSecondTime() 159 throws Exception { 160 final int atomTag = AtomsProto.Atom.APP_START_OCCURRED_FIELD_NUMBER; 161 ConfigUtils.uploadConfigForPushedAtomWithUid(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 162 atomTag, /*uidInAttributionChain=*/false); 163 getDevice().executeShellCommand(COMMAND_ENABLE_APP_HIBERNATION); 164 getDevice().executeShellCommand(getGlobalHibernationCommand( 165 DeviceUtils.STATSD_ATOM_TEST_PKG, true)); 166 167 DeviceUtils.runActivity(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 168 STATSD_CTS_FOREGROUND_ACTIVITY, "action", "action.sleep_top", WAIT_TIME_MS); 169 DeviceUtils.runActivity(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 170 STATSD_CTS_FOREGROUND_ACTIVITY, "action", "action.sleep_top", WAIT_TIME_MS); 171 172 // Sorted list of events in order in which they occurred. 173 List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 174 175 assertThat(data).hasSize(2); 176 AtomsProto.AppStartOccurred atom = data.get(1).getAtom().getAppStartOccurred(); 177 assertThat(atom.getIsHibernating()).isFalse(); 178 } 179 getGlobalHibernationCommand(String packageName, boolean isHibernating)180 private static String getGlobalHibernationCommand(String packageName, boolean isHibernating) { 181 return CMD_APP_HIBERNATION_SET_STATE_GLOBAL + packageName + " " + isHibernating; 182 } 183 } 184