1 /* 2 * Copyright (C) 2024 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.service.adselection.debug; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.os.Build; 22 23 import androidx.annotation.RequiresApi; 24 25 import com.android.adservices.LoggerFactory; 26 import com.android.adservices.data.adselection.AdSelectionDebugReportDao; 27 import com.android.adservices.service.Flags; 28 import com.android.adservices.service.adselection.AdIdFetcher; 29 import com.android.adservices.service.common.httpclient.AdServicesHttpsClient; 30 import com.android.adservices.service.devapi.DevContext; 31 32 import com.google.common.util.concurrent.FluentFuture; 33 import com.google.common.util.concurrent.Futures; 34 import com.google.common.util.concurrent.ListenableFuture; 35 36 import java.util.concurrent.ExecutorService; 37 38 /** 39 * Event-level debug reporting for ad selection. 40 * 41 * <p>Protected Audience debug reporting allows ad tech developers to declare remote URLs to receive 42 * a GET request from devices when an auction is won / lost. This allows the following use-cases: 43 * 44 * <ul> 45 * <li>See if auctions are being won / lost 46 * <li>Understand why auctions are being lost (e.g. understand if it’s an issue with a bidding / 47 * scoring script implementation or a core logic issue) 48 * <li>Monitor roll-outs of new JavaScript logic to clients 49 * </ul> 50 * 51 * <p>Debug reporting consists of two JS APIs available for usage, both of which take a URL string: 52 * <li>forDebuggingOnly.reportAdAuctionWin(String url) 53 * <li>forDebuggingOnly.reportAdAuctionWin(String url) 54 * 55 * <p>For the classes that wrap JavaScript code, see {@link DebugReportingScriptStrategy}. 56 * 57 * <p>For the classes that send events, see {@link DebugReportSenderStrategy}. 58 * 59 * <p>For the business logic processing events, see {@link DebugReportProcessor}. 60 */ 61 @RequiresApi(Build.VERSION_CODES.S) 62 public abstract class DebugReporting { 63 private static final LoggerFactory.Logger sLogger = LoggerFactory.getFledgeLogger(); 64 65 /** 66 * @return an instance of debug reporting after checking for is limited ad tracking is enabled 67 * or not. 68 */ 69 @SuppressWarnings("AvoidStaticContext") // Factory method createInstance( @onNull Context context, @NonNull Flags flags, @NonNull AdServicesHttpsClient adServicesHttpsClient, @NonNull DevContext devContext, @NonNull AdSelectionDebugReportDao adSelectionDebugReportDao, @NonNull ExecutorService lightweightExecutorService, @NonNull AdIdFetcher adIdFetcher, @NonNull String packageName, int callingUid)70 public static ListenableFuture<DebugReporting> createInstance( 71 @NonNull Context context, 72 @NonNull Flags flags, 73 @NonNull AdServicesHttpsClient adServicesHttpsClient, 74 @NonNull DevContext devContext, 75 @NonNull AdSelectionDebugReportDao adSelectionDebugReportDao, 76 @NonNull ExecutorService lightweightExecutorService, 77 @NonNull AdIdFetcher adIdFetcher, 78 @NonNull String packageName, 79 int callingUid) { 80 if (!getEnablementStatus(flags)) { 81 return Futures.immediateFuture(new DebugReportingDisabled()); 82 } 83 long adIdFetchTimeoutMs = flags.getAdIdFetcherTimeoutMs(); 84 return FluentFuture.from( 85 adIdFetcher.isLimitedAdTrackingEnabled( 86 packageName, callingUid, adIdFetchTimeoutMs)) 87 .transform( 88 isLatEnabled -> { 89 if (isLatEnabled) { 90 return new DebugReportingDisabled(); 91 } else { 92 return new DebugReportingEnabled( 93 context, 94 flags, 95 adServicesHttpsClient, 96 devContext, 97 adSelectionDebugReportDao); 98 } 99 }, 100 lightweightExecutorService); 101 } 102 103 /** 104 * @return DebugReportingScriptStrategy to be used while running on device ad selection. 105 */ 106 @NonNull 107 public abstract DebugReportingScriptStrategy getScriptStrategy(); 108 109 /** 110 * @return DebugReportSenderStrategy to be used while running on device ad selection. 111 */ 112 @NonNull 113 public abstract DebugReportSenderStrategy getSenderStrategy(); 114 115 /** 116 * @return returns status of debug reporting 117 */ 118 public abstract boolean isEnabled(); 119 120 private static boolean getEnablementStatus(Flags flags) { 121 if (flags.getAdIdKillSwitch()) { 122 sLogger.v("AdIdService kill switch is enabled, disabling event level debug reporting"); 123 return false; 124 } 125 return flags.getFledgeEventLevelDebugReportingEnabled(); 126 } 127 } 128