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