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 enforceFledgeJsIsolateMaxHeapSize(boolean enforce)222 public void enforceFledgeJsIsolateMaxHeapSize(boolean enforce) { 223 if (enforce) { 224 runShellCommand( 225 "device_config put adservices fledge_js_isolate_enforce_max_heap_size" 226 + " true"); 227 } else { 228 runShellCommand( 229 "device_config put adservices fledge_js_isolate_enforce_max_heap_size" 230 + " false"); 231 } 232 } 233 234 @SuppressWarnings("deprecation") 235 // Used to get the package name. Copied over from com.android.adservices.AndroidServiceBinder getAdServicesPackageName()236 public String getAdServicesPackageName() { 237 final Intent intent = new Intent(MEASUREMENT_SERVICE_NAME); 238 List<ResolveInfo> resolveInfos = 239 ApplicationProvider.getApplicationContext() 240 .getPackageManager() 241 .queryIntentServices(intent, PackageManager.MATCH_SYSTEM_ONLY); 242 243 // TODO: b/271866693 avoid hardcoding package names 244 if (resolveInfos != null && BuildCompat.isAtLeastT()) { 245 resolveInfos = 246 resolveInfos.stream() 247 .filter( 248 info -> 249 !info.serviceInfo.packageName.contains( 250 EXT_SERVICES_PACKAGE_NAME)) 251 .collect(Collectors.toList()); 252 } 253 254 if (resolveInfos == null || resolveInfos.isEmpty()) { 255 Log.d( 256 mTag, 257 "Failed to find resolveInfo for adServices service. Intent action: " 258 + MEASUREMENT_SERVICE_NAME); 259 return null; 260 } 261 262 if (resolveInfos.size() > 1) { 263 String str = 264 String.format( 265 "Found multiple services (%1$s) for the same intent action (%2$s)", 266 MEASUREMENT_SERVICE_NAME, resolveInfos); 267 Log.d(mTag, str); 268 return null; 269 } 270 271 final ServiceInfo serviceInfo = resolveInfos.get(0).serviceInfo; 272 if (serviceInfo == null) { 273 Log.d(mTag, "Failed to find serviceInfo for adServices service"); 274 return null; 275 } 276 277 return serviceInfo.packageName; 278 } 279 } 280