1 /* 2 * Copyright (C) 2023 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.adservices.cts; 18 19 import static com.android.adservices.service.DebugFlagsConstants.KEY_CONSENT_MANAGER_DEBUG_MODE; 20 import static com.android.adservices.service.FlagsConstants.KEY_ADSERVICES_ENABLED; 21 import static com.android.adservices.service.FlagsConstants.KEY_DISABLE_TOPICS_ENROLLMENT_CHECK; 22 import static com.android.adservices.service.FlagsConstants.KEY_GA_UX_FEATURE_ENABLED; 23 import static com.android.adservices.service.FlagsConstants.KEY_MDD_BACKGROUND_TASK_KILL_SWITCH; 24 import static com.android.adservices.service.FlagsConstants.KEY_TOPICS_KILL_SWITCH; 25 import static com.android.os.adservices.AdservicesExtensionAtoms.AD_SERVICES_SETTINGS_USAGE_REPORTED_FIELD_NUMBER; 26 27 import static com.google.common.truth.Truth.assertThat; 28 29 import static org.junit.Assert.assertNotNull; 30 31 import android.cts.statsdatom.lib.ConfigUtils; 32 import android.cts.statsdatom.lib.ReportUtils; 33 34 import com.android.adservices.common.AdServicesHostSideTestCase; 35 import com.android.adservices.shared.testing.BackgroundLogReceiver; 36 import com.android.adservices.shared.testing.annotations.EnableDebugFlag; 37 import com.android.adservices.shared.testing.annotations.SetFlagDisabled; 38 import com.android.adservices.shared.testing.annotations.SetFlagEnabled; 39 import com.android.internal.os.StatsdConfigProto.StatsdConfig; 40 import com.android.os.StatsLog.EventMetricData; 41 import com.android.os.adservices.AdServicesSettingsUsageReported; 42 import com.android.os.adservices.AdservicesExtensionAtoms; 43 import com.android.tradefed.device.DeviceNotAvailableException; 44 import com.android.tradefed.device.ITestDevice; 45 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 46 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics; 47 48 import com.google.protobuf.ExtensionRegistry; 49 50 import org.junit.After; 51 import org.junit.Before; 52 import org.junit.Rule; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 56 import java.util.Arrays; 57 import java.util.List; 58 import java.util.function.Predicate; 59 60 /** 61 * Test to check that Ui API logging to StatsD 62 * 63 * <p>The activity simply called Ui Settings Page which trigger the log event, and then check it in 64 * statsD. 65 */ 66 @RunWith(DeviceJUnit4ClassRunner.class) 67 @SetFlagDisabled(KEY_TOPICS_KILL_SWITCH) 68 @SetFlagDisabled(KEY_MDD_BACKGROUND_TASK_KILL_SWITCH) 69 @SetFlagEnabled(KEY_ADSERVICES_ENABLED) 70 @SetFlagEnabled(KEY_DISABLE_TOPICS_ENROLLMENT_CHECK) 71 @SetFlagEnabled(KEY_GA_UX_FEATURE_ENABLED) 72 @EnableDebugFlag(KEY_CONSENT_MANAGER_DEBUG_MODE) 73 public final class UiApiLoggingHostTest extends AdServicesHostSideTestCase { 74 private static final String CLASS = 75 "com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity"; 76 private static final String TARGET_PACKAGE_SUFFIX_TPLUS = "android.adservices.api"; 77 private static final String TARGET_PACKAGE_SUFFIX_SMINUS = "android.ext.services"; 78 private static final String LOGCAT_COMMAND = "logcat -s adservices"; 79 private static final String LOG_FROM_BOOTCOMPLETE_RECEIVER = 80 "AdExtBootCompletedReceiver onReceive invoked"; 81 public static final int WAIT_TIME_LONG = 2000; 82 83 private static final String TARGET_EXT_ADSERVICES_PACKAGE = 84 "com.google.android.ext.adservices.api"; 85 private static final String TARGET_EXT_ADSERVICES_PACKAGE_AOSP = 86 "com.android.ext.adservices.api"; 87 private static final String LOW_RAM_DEVICE_CONFIG = "ro.config.low_ram"; 88 private static final int PPAPI_AND_SYSTEM_SERVER_SOURCE_OF_TRUTH = 2; 89 private static final int APPSEARCH_ONLY = 3; 90 private int mApiLevel; 91 92 private String mTargetPackage; 93 94 @Rule(order = 10) 95 public TestMetrics metricsRule = new TestMetrics(); 96 97 @Before setUp()98 public void setUp() throws Exception { 99 ConfigUtils.removeConfig(getDevice()); 100 ReportUtils.clearReports(getDevice()); 101 102 // Set flags for test to run on devices with api level lower than 33 (S-) 103 String suffix = 104 sdkLevel.isAtLeastT() ? TARGET_PACKAGE_SUFFIX_TPLUS : TARGET_PACKAGE_SUFFIX_SMINUS; 105 mTargetPackage = findPackageName(suffix); 106 assertThat(mTargetPackage).isNotNull(); 107 restartAdservices(getDevice()); 108 } 109 @After tearDown()110 public void tearDown() throws Exception { 111 ConfigUtils.removeConfig(getDevice()); 112 ReportUtils.clearReports(getDevice()); 113 } 114 115 @Test testStartSettingMainActivityAndGetUiLog()116 public void testStartSettingMainActivityAndGetUiLog() throws Exception { 117 ITestDevice device = getDevice(); 118 ExtensionRegistry registry = ExtensionRegistry.newInstance(); 119 AdservicesExtensionAtoms.registerAllExtensions(registry); 120 assertNotNull("Device not set", device); 121 122 rebootIfSMinus(); 123 startSettingMainActivity(mTargetPackage, device); 124 125 // Fetch a list of happened log events and their data 126 List<EventMetricData> data = ReportUtils.getEventMetricDataList(device, registry); 127 128 // We trigger only one event from activity, should only see one event in the list 129 assertThat(data).hasSize(1); 130 131 // Verify the log event data 132 AdServicesSettingsUsageReported adServicesSettingsUsageReported = 133 data.get(0) 134 .getAtom() 135 .getExtension(AdservicesExtensionAtoms.adServicesSettingsUsageReported); 136 assertThat(adServicesSettingsUsageReported.getAction()) 137 .isEqualTo( 138 AdServicesSettingsUsageReported.AdServiceSettingsName 139 .PRIVACY_SANDBOX_SETTINGS_PAGE_DISPLAYED); 140 } 141 rebootIfSMinus()142 private void rebootIfSMinus() throws DeviceNotAvailableException, InterruptedException { 143 if (sdkLevel.isAtLeastT()) { 144 return; 145 } 146 147 ITestDevice device = getDevice(); 148 device.reboot(); 149 device.waitForDeviceAvailable(); 150 151 // Start log collection, keep going until the boot complete receiver runs or times out. 152 // Wait for up to 5 minutes for AdBootCompletedReceiver execution 153 BackgroundLogReceiver logcatReceiver = 154 new BackgroundLogReceiver.Builder() 155 .setDevice(mDevice) 156 .setLogCatCommand(LOGCAT_COMMAND) 157 .setEarlyStopCondition(stopIfBootCompleteReceiverLogOccurs()) 158 .build(); 159 logcatReceiver.collectLogs(/* timeoutMilliseconds= */ 5 * 60 * 1000); 160 } 161 stopIfBootCompleteReceiverLogOccurs()162 private Predicate<String[]> stopIfBootCompleteReceiverLogOccurs() { 163 return (s) -> Arrays.stream(s).anyMatch(t -> t.contains(LOG_FROM_BOOTCOMPLETE_RECEIVER)); 164 } 165 startSettingMainActivity(String apiName, ITestDevice device)166 private void startSettingMainActivity(String apiName, ITestDevice device) throws Exception { 167 // Upload the config. 168 final StatsdConfig.Builder config = ConfigUtils.createConfigBuilder(apiName); 169 170 ConfigUtils.addEventMetric(config, AD_SERVICES_SETTINGS_USAGE_REPORTED_FIELD_NUMBER); 171 ConfigUtils.uploadConfig(device, config); 172 // Start the ui main activity, it will make a ui log call 173 startUiMainActivity(device); 174 Thread.sleep(WAIT_TIME_LONG); 175 } 176 startUiMainActivity(ITestDevice device)177 public void startUiMainActivity(ITestDevice device) throws DeviceNotAvailableException { 178 device.executeShellCommand("am start -n " + mTargetPackage + "/" + CLASS); 179 } 180 findPackageName(String suffix)181 private String findPackageName(String suffix) throws DeviceNotAvailableException { 182 return mDevice.getInstalledPackageNames().stream() 183 .filter(s -> s.endsWith(suffix)) 184 .findFirst() 185 .orElse(null); 186 } 187 restartAdservices(ITestDevice device)188 private void restartAdservices(ITestDevice device) throws DeviceNotAvailableException { 189 device.executeShellCommand("am force-stop com.google.android.adservices.api"); 190 device.executeShellCommand("am force-stop com.android.adservices.api"); 191 device.executeShellCommand("am force-stop com.google.android.ext.adservices.api"); 192 device.executeShellCommand("am force-stop com.android.ext.adservices.api"); 193 } 194 } 195