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.apphibernation; 18 19 import com.android.tradefed.util.RunUtil; 20 import static com.google.common.truth.Truth.assertThat; 21 22 import android.cts.statsdatom.lib.AtomTestUtils; 23 import android.cts.statsdatom.lib.ConfigUtils; 24 import android.cts.statsdatom.lib.DeviceUtils; 25 import android.cts.statsdatom.lib.ReportUtils; 26 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 AppHibernationStatsTest extends DeviceTestCase implements IBuildReceiver { 36 private static final String CMD_APP_HIBERNATION_SET_STATE = 37 "cmd app_hibernation set-state %s %s %s"; 38 private static final String CMD_ENABLE_APP_HIBERNATION = 39 "device_config put app_hibernation app_hibernation_enabled true"; 40 private static final String GLOBAL_OPTION = "--global"; 41 private IBuildInfo mCtsBuild; 42 43 @Override setUp()44 protected void setUp() throws Exception { 45 super.setUp(); 46 assertThat(mCtsBuild).isNotNull(); 47 ConfigUtils.removeConfig(getDevice()); 48 ReportUtils.clearReports(getDevice()); 49 DeviceUtils.installStatsdTestApp(getDevice(), mCtsBuild); 50 getDevice().executeShellCommand(CMD_ENABLE_APP_HIBERNATION); 51 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 52 } 53 54 @Override tearDown()55 protected void tearDown() throws Exception { 56 ConfigUtils.removeConfig(getDevice()); 57 ReportUtils.clearReports(getDevice()); 58 DeviceUtils.uninstallStatsdTestApp(getDevice()); 59 super.tearDown(); 60 } 61 62 @Override setBuild(IBuildInfo buildInfo)63 public void setBuild(IBuildInfo buildInfo) { 64 mCtsBuild = buildInfo; 65 } 66 testUserLevelAppHibernationStateChanged_fromNotHibernatingToHibernating()67 public void testUserLevelAppHibernationStateChanged_fromNotHibernatingToHibernating() 68 throws Exception { 69 getDevice().executeShellCommand( 70 getHibernationCommand(DeviceUtils.STATSD_ATOM_TEST_PKG, 71 /* isGlobal */ false, /* isHibernating */ false)); 72 ConfigUtils.uploadConfigForPushedAtomWithUid(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 73 AtomsProto.Atom.USER_LEVEL_HIBERNATION_STATE_CHANGED_FIELD_NUMBER, 74 /*uidInAttributionChain=*/false); 75 76 getDevice().executeShellCommand( 77 getHibernationCommand(DeviceUtils.STATSD_ATOM_TEST_PKG, 78 /* isGlobal */ false, /* isHibernating */ true)); 79 80 // Sorted list of events in order in which they occurred. 81 final List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 82 assertThat(data.size()).isAtLeast(1); 83 assertUserLevelHibernationStateChangedEvent(data, /* isHibernating */ true, 84 getDevice().getCurrentUser()); 85 } 86 testUserLevelAppHibernationStateChanged_fromHibernatingToNotHibernating()87 public void testUserLevelAppHibernationStateChanged_fromHibernatingToNotHibernating() 88 throws Exception { 89 getDevice().executeShellCommand( 90 getHibernationCommand(DeviceUtils.STATSD_ATOM_TEST_PKG, 91 /* isGlobal */ false, /* isHibernating */ true)); 92 ConfigUtils.uploadConfigForPushedAtomWithUid(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 93 AtomsProto.Atom.USER_LEVEL_HIBERNATION_STATE_CHANGED_FIELD_NUMBER, 94 /*uidInAttributionChain=*/false); 95 96 getDevice().executeShellCommand( 97 getHibernationCommand(DeviceUtils.STATSD_ATOM_TEST_PKG, 98 /* isGlobal */ false, /* isHibernating */ false)); 99 100 // Sorted list of events in order in which they occurred. 101 final List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); 102 assertThat(data.size()).isAtLeast(1); 103 assertUserLevelHibernationStateChangedEvent(data, /* isHibernating */ false, 104 getDevice().getCurrentUser()); 105 } 106 testUserLevelHibernatedApps()107 public void testUserLevelHibernatedApps() throws Exception { 108 ConfigUtils.uploadConfigForPulledAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 109 AtomsProto.Atom.USER_LEVEL_HIBERNATED_APPS_FIELD_NUMBER); 110 getDevice().executeShellCommand( 111 getHibernationCommand(DeviceUtils.STATSD_ATOM_TEST_PKG, 112 /* isGlobal */ false, /* isHibernating */ true)); 113 114 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice()); 115 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 116 117 final List<AtomsProto.Atom> atoms = ReportUtils.getGaugeMetricAtoms(getDevice()); 118 final int userId = getDevice().getCurrentUser(); 119 for (AtomsProto.Atom atom : atoms) { 120 AtomsProto.UserLevelHibernatedApps apps = atom.getUserLevelHibernatedApps(); 121 if (apps.getUserId() == userId) { 122 assertThat(apps.getHibernatedAppCount()).isAtLeast(1); 123 return; 124 } 125 } 126 fail(String.format("Did not find a matching atom for user %d", userId)); 127 } 128 testGlobalHibernatedApps()129 public void testGlobalHibernatedApps() throws Exception { 130 ConfigUtils.uploadConfigForPulledAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, 131 AtomsProto.Atom.GLOBAL_HIBERNATED_APPS_FIELD_NUMBER); 132 getDevice().executeShellCommand( 133 getHibernationCommand(DeviceUtils.STATSD_ATOM_TEST_PKG, 134 /* isGlobal */ true, /* isHibernating */ true)); 135 136 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice()); 137 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 138 139 final List<AtomsProto.Atom> atoms = ReportUtils.getGaugeMetricAtoms(getDevice()); 140 assertThat(atoms.size()).isEqualTo(1); 141 AtomsProto.GlobalHibernatedApps apps = atoms.get(0).getGlobalHibernatedApps(); 142 assertThat(apps.getHibernatedAppCount()).isAtLeast(1); 143 } 144 assertUserLevelHibernationStateChangedEvent( List<StatsLog.EventMetricData> data, boolean isHibernating, int currentUser)145 private static void assertUserLevelHibernationStateChangedEvent( 146 List<StatsLog.EventMetricData> data, boolean isHibernating, int currentUser) { 147 for (StatsLog.EventMetricData d : data) { 148 AtomsProto.UserLevelHibernationStateChanged atom = 149 d.getAtom().getUserLevelHibernationStateChanged(); 150 if (atom.getPackageName().equals(DeviceUtils.STATSD_ATOM_TEST_PKG)) { 151 assertThat(atom.getUserId()).isEqualTo(currentUser); 152 assertThat(atom.getIsHibernating()).isEqualTo(isHibernating); 153 return; 154 } 155 } 156 fail(String.format("Did not find a matching event for package %s", 157 DeviceUtils.STATSD_ATOM_TEST_PKG)); 158 } 159 getHibernationCommand( String packageName, boolean isGlobal, boolean isHibernating)160 private static String getHibernationCommand( 161 String packageName, boolean isGlobal, boolean isHibernating) { 162 return String.format(CMD_APP_HIBERNATION_SET_STATE, 163 (isGlobal ? GLOBAL_OPTION : ""), packageName, isHibernating); 164 } 165 } 166