1 /* 2 * Copyright (C) 2018 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 package android.cts.statsd.uidmap; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import android.cts.statsd.metric.MetricsUtils; 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.compatibility.common.tradefed.build.CompatibilityBuildHelper; 27 import com.android.internal.os.StatsdConfigProto; 28 import com.android.os.AtomsProto; 29 import com.android.os.StatsLog.ConfigMetricsReportList; 30 import com.android.os.StatsLog.ConfigMetricsReport; 31 import com.android.os.StatsLog.UidMapping; 32 import com.android.os.StatsLog.UidMapping.PackageInfoSnapshot; 33 import com.android.tradefed.build.IBuildInfo; 34 import com.android.tradefed.log.LogUtil; 35 import com.android.tradefed.testtype.DeviceTestCase; 36 import com.android.tradefed.testtype.IBuildReceiver; 37 import com.android.tradefed.util.RunUtil; 38 39 import com.google.protobuf.ExtensionRegistry; 40 41 public class UidMapTests extends DeviceTestCase implements IBuildReceiver { 42 43 private static final long DEVICE_SIDE_TEST_PKG_HASH = 44 Long.parseUnsignedLong("15694052924544098582"); 45 46 private IBuildInfo mCtsBuild; 47 48 @Override setUp()49 protected void setUp() throws Exception { 50 super.setUp(); 51 assertThat(mCtsBuild).isNotNull(); 52 ConfigUtils.removeConfig(getDevice()); 53 ReportUtils.clearReports(getDevice()); 54 DeviceUtils.installTestApp(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_APK, 55 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, mCtsBuild); 56 RunUtil.getDefault().sleep(1000); 57 } 58 59 @Override tearDown()60 protected void tearDown() throws Exception { 61 ConfigUtils.removeConfig(getDevice()); 62 ReportUtils.clearReports(getDevice()); 63 DeviceUtils.uninstallTestApp(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 64 super.tearDown(); 65 } 66 67 @Override setBuild(IBuildInfo buildInfo)68 public void setBuild(IBuildInfo buildInfo) { 69 mCtsBuild = buildInfo; 70 } 71 72 // Tests that every report has at least one snapshot. testUidSnapshotIncluded()73 public void testUidSnapshotIncluded() throws Exception { 74 // There should be at least the test app installed during the test setup. 75 ConfigUtils.uploadConfigForPushedAtom(getDevice(), 76 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, 77 AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER); 78 79 ConfigMetricsReportList reports = ReportUtils.getReportList(getDevice(), 80 ExtensionRegistry.getEmptyRegistry()); 81 assertThat(reports.getReportsCount()).isGreaterThan(0); 82 83 for (ConfigMetricsReport report : reports.getReportsList()) { 84 UidMapping uidmap = report.getUidMap(); 85 assertThat(uidmap.getSnapshotsCount()).isGreaterThan(0); 86 for (PackageInfoSnapshot snapshot : uidmap.getSnapshotsList()) { 87 // There must be at least one element in each snapshot (at least one package is 88 // installed). 89 assertThat(snapshot.getPackageInfoCount()).isGreaterThan(0); 90 } 91 } 92 } 93 hasMatchingChange(UidMapping uidmap, int uid, boolean expectDeletion)94 private boolean hasMatchingChange(UidMapping uidmap, int uid, boolean expectDeletion) { 95 LogUtil.CLog.d("The uid we are looking for is " + uid); 96 for (UidMapping.Change change : uidmap.getChangesList()) { 97 if (change.getAppHash() == DEVICE_SIDE_TEST_PKG_HASH && change.getUid() == uid) { 98 if (change.getDeletion() == expectDeletion) { 99 return true; 100 } 101 } 102 } 103 return false; 104 } 105 106 // Tests that delta event included during app installation. testChangeFromInstallation()107 public void testChangeFromInstallation() throws Exception { 108 getDevice().uninstallPackage(MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 109 ConfigUtils.uploadConfigForPushedAtom(getDevice(), 110 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, 111 AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER); 112 // Install the package after the config is sent to statsd. The uid map is not guaranteed to 113 // be updated if there's no config in statsd. 114 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); 115 final String result = getDevice().installPackage( 116 buildHelper.getTestFile(MetricsUtils.DEVICE_SIDE_TEST_APK), false, true); 117 118 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 119 120 ConfigMetricsReportList reports = ReportUtils.getReportList(getDevice(), 121 ExtensionRegistry.getEmptyRegistry()); 122 assertThat(reports.getReportsCount()).isGreaterThan(0); 123 124 boolean found = false; 125 int uid = DeviceUtils.getAppUid(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 126 for (ConfigMetricsReport report : reports.getReportsList()) { 127 LogUtil.CLog.d("Got the following report: \n" + report.toString()); 128 if (hasMatchingChange(report.getUidMap(), uid, false)) { 129 found = true; 130 } 131 } 132 assertThat(found).isTrue(); 133 } 134 135 // We check that a re-installation gives a change event (similar to an app upgrade). testChangeFromReinstall()136 public void testChangeFromReinstall() throws Exception { 137 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); 138 getDevice().installPackage(buildHelper.getTestFile(MetricsUtils.DEVICE_SIDE_TEST_APK), 139 false, true); 140 ConfigUtils.uploadConfigForPushedAtom(getDevice(), 141 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, 142 AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER); 143 // Now enable re-installation. 144 getDevice().installPackage(buildHelper.getTestFile(MetricsUtils.DEVICE_SIDE_TEST_APK), true, 145 true); 146 147 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 148 149 ConfigMetricsReportList reports = ReportUtils.getReportList(getDevice(), 150 ExtensionRegistry.getEmptyRegistry()); 151 assertThat(reports.getReportsCount()).isGreaterThan(0); 152 153 boolean found = false; 154 int uid = DeviceUtils.getAppUid(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 155 for (ConfigMetricsReport report : reports.getReportsList()) { 156 LogUtil.CLog.d("Got the following report: \n" + report.toString()); 157 if (hasMatchingChange(report.getUidMap(), uid, false)) { 158 found = true; 159 } 160 } 161 assertThat(found).isTrue(); 162 } 163 testChangeFromUninstall()164 public void testChangeFromUninstall() throws Exception { 165 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); 166 getDevice().installPackage(buildHelper.getTestFile(MetricsUtils.DEVICE_SIDE_TEST_APK), true, 167 true); 168 169 ConfigUtils.uploadConfigForPushedAtom(getDevice(), 170 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, 171 AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER); 172 int uid = DeviceUtils.getAppUid(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 173 getDevice().uninstallPackage(MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 174 175 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); 176 177 ConfigMetricsReportList reports = ReportUtils.getReportList(getDevice(), 178 ExtensionRegistry.getEmptyRegistry()); 179 assertThat(reports.getReportsCount()).isGreaterThan(0); 180 181 boolean found = false; 182 for (ConfigMetricsReport report : reports.getReportsList()) { 183 LogUtil.CLog.d("Got the following report: \n" + report.toString()); 184 if (hasMatchingChange(report.getUidMap(), uid, true)) { 185 found = true; 186 } 187 } 188 assertThat(found).isTrue(); 189 } 190 } 191