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; 18 19 import android.app.Instrumentation; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.pm.ResolveInfo; 23 import android.content.pm.ServiceInfo; 24 import android.os.Build; 25 import android.util.Log; 26 27 import androidx.core.os.BuildCompat; 28 import androidx.test.core.app.ApplicationProvider; 29 30 import java.util.List; 31 import java.util.stream.Collectors; 32 33 // TODO(b/299104530): replace device_config usage by AdServicesFlagSetterRule 34 public class TestUtil { 35 private Instrumentation mInstrumentation; 36 private String mTag; 37 // Used to get the package name. Copied over from com.android.adservices.AdServicesCommon 38 private static final String MEASUREMENT_SERVICE_NAME = "android.adservices.MEASUREMENT_SERVICE"; 39 private static final String EXT_SERVICES_PACKAGE_NAME = "ext.adservices"; 40 // The JobId of the Epoch Computation. 41 private static final int EPOCH_JOB_ID = 2; 42 TestUtil(Instrumentation instrumentation, String tag)43 public TestUtil(Instrumentation instrumentation, String tag) { 44 mInstrumentation = instrumentation; 45 mTag = tag; 46 } 47 // Run shell command. runShellCommand(String command)48 private void runShellCommand(String command) { 49 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 50 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 51 mInstrumentation.getUiAutomation().executeShellCommand(command); 52 } 53 } 54 } 55 overrideKillSwitches(boolean override)56 public void overrideKillSwitches(boolean override) { 57 if (override) { 58 runShellCommand("device_config put adservices global_kill_switch " + false); 59 runShellCommand("device_config put adservices topics_kill_switch " + false); 60 } else { 61 runShellCommand("device_config put adservices global_kill_switch " + null); 62 runShellCommand("device_config put adservices topics_kill_switch " + null); 63 } 64 } 65 enableEnrollmentCheck(boolean enable)66 public void enableEnrollmentCheck(boolean enable) { 67 runShellCommand("device_config put adservices disable_topics_enrollment_check " + enable); 68 } 69 70 // Override the Epoch Period to shorten the Epoch Length in the test. overrideEpochPeriod(long overrideEpochPeriod)71 public void overrideEpochPeriod(long overrideEpochPeriod) { 72 runShellCommand( 73 "device_config put adservices topics_epoch_job_period_ms " + overrideEpochPeriod); 74 } 75 76 // Override the Percentage For Random Topic in the test. overridePercentageForRandomTopic(long overridePercentage)77 public void overridePercentageForRandomTopic(long overridePercentage) { 78 runShellCommand( 79 "device_config put adservices topics_percentage_for_random_topics " 80 + overridePercentage); 81 } 82 83 /** Forces JobScheduler to run the Epoch Computation job */ forceEpochComputationJob()84 public void forceEpochComputationJob() { 85 runShellCommand( 86 "cmd jobscheduler run -f" + " " + getAdServicesPackageName() + " " + EPOCH_JOB_ID); 87 } 88 overrideConsentManagerDebugMode(boolean override)89 public void overrideConsentManagerDebugMode(boolean override) { 90 String overrideStr = override ? "true" : "null"; 91 runShellCommand("setprop debug.adservices.consent_manager_debug_mode " + overrideStr); 92 } 93 overrideAllowlists(boolean override)94 public void overrideAllowlists(boolean override) { 95 String overrideStr = override ? "*" : "null"; 96 runShellCommand("device_config put adservices ppapi_app_allow_list " + overrideStr); 97 runShellCommand("device_config put adservices msmt_api_app_allow_list " + overrideStr); 98 runShellCommand( 99 "device_config put adservices ppapi_app_signature_allow_list " + overrideStr); 100 runShellCommand( 101 "device_config put adservices web_context_client_allow_list " + overrideStr); 102 } 103 overrideAdIdKillSwitch(boolean override)104 public void overrideAdIdKillSwitch(boolean override) { 105 if (override) { 106 runShellCommand("device_config put adservices adid_kill_switch " + false); 107 } else { 108 runShellCommand("device_config put adservices adid_kill_switch " + null); 109 } 110 } 111 overrideAppSetIdKillSwitch(boolean override)112 public void overrideAppSetIdKillSwitch(boolean override) { 113 if (override) { 114 runShellCommand("device_config put adservices appsetid_kill_switch " + false); 115 } else { 116 runShellCommand("device_config put adservices appsetid_kill_switch " + null); 117 } 118 } 119 120 // Override measurement related kill switch to ignore the effect of actual PH values. 121 // If isOverride = true, override measurement related kill switch to OFF to allow adservices 122 // If isOverride = false, override measurement related kill switch to meaningless value so that 123 // PhFlags will use the default value. overrideMeasurementKillSwitches(boolean isOverride)124 public void overrideMeasurementKillSwitches(boolean isOverride) { 125 String overrideString = isOverride ? "false" : "null"; 126 runShellCommand("device_config put adservices global_kill_switch " + overrideString); 127 runShellCommand("device_config put adservices measurement_kill_switch " + overrideString); 128 runShellCommand( 129 "device_config put adservices measurement_api_register_source_kill_switch " 130 + overrideString); 131 runShellCommand( 132 "device_config put adservices measurement_api_register_trigger_kill_switch " 133 + overrideString); 134 runShellCommand( 135 "device_config put adservices measurement_api_register_web_source_kill_switch " 136 + overrideString); 137 runShellCommand( 138 "device_config put adservices measurement_api_register_web_trigger_kill_switch " 139 + overrideString); 140 runShellCommand( 141 "device_config put adservices measurement_api_delete_registrations_kill_switch " 142 + overrideString); 143 runShellCommand( 144 "device_config put adservices measurement_api_status_kill_switch " 145 + overrideString); 146 } 147 148 // Override the flag to disable Measurement enrollment check. Setting to 1 disables enforcement. overrideDisableMeasurementEnrollmentCheck(String val)149 public void overrideDisableMeasurementEnrollmentCheck(String val) { 150 runShellCommand("device_config put adservices disable_measurement_enrollment_check " + val); 151 } 152 resetOverrideDisableMeasurementEnrollmentCheck()153 public void resetOverrideDisableMeasurementEnrollmentCheck() { 154 runShellCommand("device_config put adservices disable_measurement_enrollment_check null"); 155 } 156 157 // Force using bundled files instead of using MDD downloaded files. This helps to make the test 158 // results deterministic. shouldForceUseBundledFiles(boolean shouldUse)159 public void shouldForceUseBundledFiles(boolean shouldUse) { 160 if (shouldUse) { 161 runShellCommand("device_config put adservices classifier_force_use_bundled_files true"); 162 } else { 163 runShellCommand("device_config delete adservices classifier_force_use_bundled_files"); 164 } 165 } 166 enableVerboseLogging()167 public void enableVerboseLogging() { 168 runShellCommand("setprop log.tag.adservices VERBOSE"); 169 } 170 overrideFledgeSelectAdsKillSwitch(boolean override)171 public void overrideFledgeSelectAdsKillSwitch(boolean override) { 172 if (override) { 173 runShellCommand("device_config put adservices fledge_select_ads_kill_switch " + false); 174 } else { 175 runShellCommand("device_config put adservices fledge_select_ads_kill_switch " + null); 176 } 177 } 178 overrideFledgeCustomAudienceServiceKillSwitch(boolean override)179 public void overrideFledgeCustomAudienceServiceKillSwitch(boolean override) { 180 if (override) { 181 runShellCommand( 182 "device_config put adservices fledge_custom_audience_service_kill_switch " 183 + false); 184 } else { 185 runShellCommand( 186 "device_config put adservices fledge_custom_audience_service_kill_switch " 187 + null); 188 } 189 } 190 overrideSdkRequestPermitsPerSecond(long maxRequests)191 public void overrideSdkRequestPermitsPerSecond(long maxRequests) { 192 runShellCommand( 193 "device_config put adservices sdk_request_permits_per_second " + maxRequests); 194 } 195 disableDeviceConfigSyncForTests(boolean disabled)196 public void disableDeviceConfigSyncForTests(boolean disabled) { 197 if (disabled) { 198 runShellCommand("device_config set_sync_disabled_for_tests persistent"); 199 } else { 200 runShellCommand("device_config set_sync_disabled_for_tests none"); 201 } 202 } 203 disableFledgeEnrollmentCheck(boolean disabled)204 public void disableFledgeEnrollmentCheck(boolean disabled) { 205 if (disabled) { 206 runShellCommand("device_config put adservices disable_fledge_enrollment_check true"); 207 } else { 208 runShellCommand("device_config put adservices disable_fledge_enrollment_check false"); 209 } 210 } 211 enableAdServiceSystemService(boolean enabled)212 public void enableAdServiceSystemService(boolean enabled) { 213 if (enabled) { 214 runShellCommand( 215 "device_config put adservices adservice_system_service_enabled " + "\"true\""); 216 } else { 217 runShellCommand( 218 "device_config put adservices adservice_system_service_enabled " + "\"false\""); 219 } 220 } 221 222 @SuppressWarnings("deprecation") 223 // Used to get the package name. Copied over from com.android.adservices.AndroidServiceBinder getAdServicesPackageName()224 public String getAdServicesPackageName() { 225 final Intent intent = new Intent(MEASUREMENT_SERVICE_NAME); 226 List<ResolveInfo> resolveInfos = 227 ApplicationProvider.getApplicationContext() 228 .getPackageManager() 229 .queryIntentServices(intent, PackageManager.MATCH_SYSTEM_ONLY); 230 231 // TODO: b/271866693 avoid hardcoding package names 232 if (resolveInfos != null && BuildCompat.isAtLeastT()) { 233 resolveInfos = 234 resolveInfos.stream() 235 .filter( 236 info -> 237 !info.serviceInfo.packageName.contains( 238 EXT_SERVICES_PACKAGE_NAME)) 239 .collect(Collectors.toList()); 240 } 241 242 if (resolveInfos == null || resolveInfos.isEmpty()) { 243 Log.d( 244 mTag, 245 "Failed to find resolveInfo for adServices service. Intent action: " 246 + MEASUREMENT_SERVICE_NAME); 247 return null; 248 } 249 250 if (resolveInfos.size() > 1) { 251 String str = 252 String.format( 253 "Found multiple services (%1$s) for the same intent action (%2$s)", 254 MEASUREMENT_SERVICE_NAME, resolveInfos); 255 Log.d(mTag, str); 256 return null; 257 } 258 259 final ServiceInfo serviceInfo = resolveInfos.get(0).serviceInfo; 260 if (serviceInfo == null) { 261 Log.d(mTag, "Failed to find serviceInfo for adServices service"); 262 return null; 263 } 264 265 return serviceInfo.packageName; 266 } 267 } 268