1 /* 2 * Copyright (C) 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 package com.android.adservices; 17 18 import android.adservices.adid.AdIdProviderService; 19 import android.adservices.appsetid.AppSetIdProviderService; 20 import android.adservices.cobalt.AdServicesCobaltUploadService; 21 import android.adservices.extdata.AdServicesExtDataStorageService; 22 import android.annotation.Nullable; 23 import android.content.pm.ResolveInfo; 24 import android.content.pm.ServiceInfo; 25 26 import java.util.List; 27 import java.util.stream.Collectors; 28 29 // TODO(b/295321663): need to split constants into AdServicesCommonConstants so they can be used by 30 // host-side test artifacts. 31 32 /** 33 * Common constants for AdServices 34 * 35 * @hide 36 */ 37 public final class AdServicesCommon { AdServicesCommon()38 private AdServicesCommon() {} 39 40 /** Intent action to discover the Topics service in the APK. */ 41 public static final String ACTION_TOPICS_SERVICE = "android.adservices.TOPICS_SERVICE"; 42 43 /** Intent action to discover the Custom Audience service in the APK. */ 44 public static final String ACTION_CUSTOM_AUDIENCE_SERVICE = 45 "android.adservices.customaudience.CUSTOM_AUDIENCE_SERVICE"; 46 47 /** Intent action to discover the AdSelection service in the APK. */ 48 public static final String ACTION_AD_SELECTION_SERVICE = 49 "android.adservices.adselection.AD_SELECTION_SERVICE"; 50 51 /** Intent action to discover the protected signals service in the APK. */ 52 public static final String ACTION_PROTECTED_SIGNALS_SERVICE = 53 "android.adservices.signals.PROTECTED_SIGNALS_SERVICE"; 54 55 /** Intent action to discover the Measurement service in the APK. */ 56 public static final String ACTION_MEASUREMENT_SERVICE = 57 "android.adservices.MEASUREMENT_SERVICE"; 58 59 /** Intent action to discover the AdId service in the APK. */ 60 public static final String ACTION_ADID_SERVICE = "android.adservices.ADID_SERVICE"; 61 62 /** Intent action to discover the AdId Provider service. */ 63 public static final String ACTION_ADID_PROVIDER_SERVICE = AdIdProviderService.SERVICE_INTERFACE; 64 65 /** Intent action to discover the AppSetId service in the APK. */ 66 public static final String ACTION_APPSETID_SERVICE = "android.adservices.APPSETID_SERVICE"; 67 68 /** Intent action to discover the AppSetId Provider service. */ 69 public static final String ACTION_APPSETID_PROVIDER_SERVICE = 70 AppSetIdProviderService.SERVICE_INTERFACE; 71 72 /** Intent action to discover the AdServicesExtDataStorageService. */ 73 public static final String ACTION_AD_EXT_DATA_STORAGE_SERVICE = 74 AdServicesExtDataStorageService.SERVICE_INTERFACE; 75 76 /** Intent action to discover the AdServicesCommon service in the APK. */ 77 public static final String ACTION_AD_SERVICES_COMMON_SERVICE = 78 "android.adservices.AD_SERVICES_COMMON_SERVICE"; 79 80 /** Intent action to discover the AdServices Cobalt upload service. */ 81 public static final String ACTION_AD_SERVICES_COBALT_UPLOAD_SERVICE = 82 AdServicesCobaltUploadService.SERVICE_INTERFACE; 83 84 /** Intent action to discover the Shell Command service in the APK. */ 85 public static final String ACTION_SHELL_COMMAND_SERVICE = 86 "android.adservices.SHELL_COMMAND_SERVICE"; 87 88 // Used to differentiate between AdServices APK package name and AdExtServices APK package name. 89 // The AdExtServices APK package name suffix is android.ext.services. 90 public static final String ADSERVICES_APK_PACKAGE_NAME_SUFFIX = "android.adservices.api"; 91 92 /** The package name suffix of the ExtServices APK on R/S */ 93 public static final String ADEXTSERVICES_PACKAGE_NAME_SUFFIX = "android.ext.services"; 94 95 /** Suffix for the AdServices APEX package name. */ 96 public static final String ADSERVICES_APEX_NAME_SUFFIX = "android.adservices"; 97 98 /** 99 * Suffix for the ExtServices APEX Package name. Used to figure out the installed apex version. 100 */ 101 public static final String EXTSERVICES_APEX_NAME_SUFFIX = "android.extservices"; 102 103 /** 104 * Prefix for system properties used for debugging purposes (like simulating unsupported devices 105 * or change some behavior without changing a flag). 106 */ 107 public static final String SYSTEM_PROPERTY_FOR_DEBUGGING_PREFIX = "debug.adservices."; 108 109 /** System property used to simulate AdServices behavior on devices with low memory. */ 110 public static final String SYSTEM_PROPERTY_FOR_DEBUGGING_FEATURE_RAM_LOW = 111 SYSTEM_PROPERTY_FOR_DEBUGGING_PREFIX + "low_ram_device"; 112 113 /** The name of System Property for the binder timeout */ 114 public static final String BINDER_TIMEOUT_SYSTEM_PROPERTY_NAME = "binder_timeout"; 115 116 /** System property used to allow test to override the binder's timeout. */ 117 public static final String SYSTEM_PROPERTY_FOR_DEBUGGING_BINDER_TIMEOUT = 118 SYSTEM_PROPERTY_FOR_DEBUGGING_PREFIX + BINDER_TIMEOUT_SYSTEM_PROPERTY_NAME; 119 120 /** Path name for Adservice class names */ 121 public static final String ADSERVICES_CLASS_PATH_PREFIX = "com.android.adservices."; 122 123 /** The package name of the active AdServices APK on this device. */ resolveAdServicesService( @ullable List<ResolveInfo> intentResolveInfos, String intentAction)124 public static ServiceInfo resolveAdServicesService( 125 @Nullable List<ResolveInfo> intentResolveInfos, String intentAction) { 126 int size = intentResolveInfos == null ? 0 : intentResolveInfos.size(); 127 128 enforceSingleServiceForAdIdAndAppSetId(intentAction, size); 129 130 switch (size) { 131 case 0: 132 LogUtil.e( 133 "Failed to find resolveInfo for adServices service. Intent action: %s", 134 intentAction); 135 return null; 136 137 case 1: 138 return intentResolveInfos.get(0).serviceInfo; 139 140 case 2: 141 // On T+ devices, we may have two versions of the services present due to 142 // b/263904312. Only use the service that comes from AdServices APK. The package 143 // name of AdService is com.[google.]android.adservices.api while the package name 144 // of ExtServices APK is com.[google.]android.ext.services. 145 ServiceInfo serviceInfo = getServiceInfoIfAdServices(intentResolveInfos.get(0)); 146 return serviceInfo == null 147 ? getServiceInfoIfAdServices(intentResolveInfos.get(1)) 148 : serviceInfo; 149 150 default: 151 List<String> intents = 152 intentResolveInfos.stream() 153 .filter(s -> s != null && s.serviceInfo != null) 154 .map(s -> s.serviceInfo.packageName) 155 .collect(Collectors.toList()); 156 LogUtil.e("Found multiple services %s for %s", intents, intentAction); 157 return null; 158 } 159 } 160 getServiceInfoIfAdServices(@ullable ResolveInfo resolveInfo)161 private static ServiceInfo getServiceInfoIfAdServices(@Nullable ResolveInfo resolveInfo) { 162 if (resolveInfo == null) { 163 return null; 164 } 165 166 ServiceInfo serviceInfo = resolveInfo.serviceInfo; 167 if (serviceInfo == null || serviceInfo.packageName == null) { 168 return null; 169 } 170 171 return serviceInfo.packageName.endsWith(ADSERVICES_APK_PACKAGE_NAME_SUFFIX) 172 ? serviceInfo 173 : null; 174 } 175 176 // It was designed to allow OEM to override the AdId/AppSetId Provider Service in GMS Core. 177 // However, this is never available because if the device has both GMS Core and an 178 // overriding Provider, it falls into this case and returns null. Therefore, let it 179 // explicitly throw in case any OEM wants to actually override it, and we can apply 180 // a change to allow it if needed. enforceSingleServiceForAdIdAndAppSetId( String intentAction, int numberOfResolvedServices)181 private static void enforceSingleServiceForAdIdAndAppSetId( 182 String intentAction, int numberOfResolvedServices) { 183 if ((ACTION_ADID_PROVIDER_SERVICE.equals(intentAction) 184 || ACTION_APPSETID_PROVIDER_SERVICE.equals(intentAction)) 185 && numberOfResolvedServices > 1) { 186 throw new IllegalStateException("Found multiple services for " + intentAction); 187 } 188 } 189 } 190