573 lines
26 KiB
Java
573 lines
26 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2022 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package android.adservices.adselection;
|
||
|
|
||
|
import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_SELECTION;
|
||
|
import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE;
|
||
|
import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_PROTECTED_SIGNALS;
|
||
|
|
||
|
import android.adservices.common.AdServicesStatusUtils;
|
||
|
import android.adservices.common.FledgeErrorResponse;
|
||
|
import android.annotation.CallbackExecutor;
|
||
|
import android.annotation.NonNull;
|
||
|
import android.annotation.RequiresPermission;
|
||
|
import android.os.Build;
|
||
|
import android.os.OutcomeReceiver;
|
||
|
import android.os.RemoteException;
|
||
|
|
||
|
import androidx.annotation.RequiresApi;
|
||
|
|
||
|
import com.android.adservices.LoggerFactory;
|
||
|
|
||
|
import java.util.Objects;
|
||
|
import java.util.concurrent.Executor;
|
||
|
|
||
|
/**
|
||
|
* {@link TestAdSelectionManager} provides APIs for apps and ad SDKs to test ad selection processes.
|
||
|
*
|
||
|
* <p>These APIs are intended to be used for end-to-end testing. They are enabled only for
|
||
|
* debuggable apps on phones running a debuggable OS build with developer options enabled.
|
||
|
*/
|
||
|
@RequiresApi(Build.VERSION_CODES.S)
|
||
|
public class TestAdSelectionManager {
|
||
|
private static final LoggerFactory.Logger sLogger = LoggerFactory.getFledgeLogger();
|
||
|
|
||
|
private final AdSelectionManager mAdSelectionManager;
|
||
|
|
||
|
TestAdSelectionManager(@NonNull AdSelectionManager adSelectionManager) {
|
||
|
Objects.requireNonNull(adSelectionManager);
|
||
|
|
||
|
mAdSelectionManager = adSelectionManager;
|
||
|
}
|
||
|
|
||
|
// TODO(b/289362476): Add override APIs for server auction key fetch
|
||
|
|
||
|
/**
|
||
|
* Overrides the AdSelection API for a given {@link AdSelectionConfig} to avoid fetching data
|
||
|
* from remote servers and use the data provided in {@link AddAdSelectionOverrideRequest}
|
||
|
* instead. The {@link AddAdSelectionOverrideRequest} is provided by the Ads SDK.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* <p>The receiver either returns a {@code void} for a successful run, or an {@link
|
||
|
* Exception} indicates the error.
|
||
|
*/
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void overrideAdSelectionConfigRemoteInfo(
|
||
|
@NonNull AddAdSelectionOverrideRequest request,
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> receiver) {
|
||
|
Objects.requireNonNull(request);
|
||
|
Objects.requireNonNull(executor);
|
||
|
Objects.requireNonNull(receiver);
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
mAdSelectionManager.getServiceProvider().getService();
|
||
|
service.overrideAdSelectionConfigRemoteInfo(
|
||
|
request.getAdSelectionConfig(),
|
||
|
request.getDecisionLogicJs(),
|
||
|
request.getTrustedScoringSignals(),
|
||
|
request.getPerBuyerDecisionLogic(),
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> receiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
receiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service.");
|
||
|
receiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service.", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Exception");
|
||
|
receiver.onError(new IllegalStateException("Failure of AdSelection service.", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes an override for {@link AdSelectionConfig} in the Ad Selection API with associated the
|
||
|
* data in {@link RemoveAdSelectionOverrideRequest}. The {@link
|
||
|
* RemoveAdSelectionOverrideRequest} is provided by the Ads SDK.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* <p>The receiver either returns a {@code void} for a successful run, or an {@link
|
||
|
* Exception} indicates the error.
|
||
|
*/
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void removeAdSelectionConfigRemoteInfoOverride(
|
||
|
@NonNull RemoveAdSelectionOverrideRequest request,
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> receiver) {
|
||
|
Objects.requireNonNull(request);
|
||
|
Objects.requireNonNull(executor);
|
||
|
Objects.requireNonNull(receiver);
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
mAdSelectionManager.getServiceProvider().getService();
|
||
|
service.removeAdSelectionConfigRemoteInfoOverride(
|
||
|
request.getAdSelectionConfig(),
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> receiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
receiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service.");
|
||
|
receiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service.", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Exception");
|
||
|
receiver.onError(new IllegalStateException("Failure of AdSelection service.", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes all override data for {@link AdSelectionConfig} in the Ad Selection API.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* <p>The receiver either returns a {@code void} for a successful run, or an {@link
|
||
|
* Exception} indicates the error.
|
||
|
*/
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void resetAllAdSelectionConfigRemoteOverrides(
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> receiver) {
|
||
|
Objects.requireNonNull(executor);
|
||
|
Objects.requireNonNull(receiver);
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
mAdSelectionManager.getServiceProvider().getService();
|
||
|
service.resetAllAdSelectionConfigRemoteOverrides(
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> receiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
receiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service.");
|
||
|
receiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service.", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Exception");
|
||
|
receiver.onError(new IllegalStateException("Failure of AdSelection service.", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Overrides the AdSelection API for {@link AdSelectionFromOutcomesConfig} to avoid fetching
|
||
|
* data from remote servers and use the data provided in {@link
|
||
|
* AddAdSelectionFromOutcomesOverrideRequest} instead. The {@link
|
||
|
* AddAdSelectionFromOutcomesOverrideRequest} is provided by the Ads SDK.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* <p>The receiver either returns a {@code void} for a successful run, or an {@link
|
||
|
* Exception} indicates the error.
|
||
|
*/
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void overrideAdSelectionFromOutcomesConfigRemoteInfo(
|
||
|
@NonNull AddAdSelectionFromOutcomesOverrideRequest request,
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> receiver) {
|
||
|
Objects.requireNonNull(request);
|
||
|
Objects.requireNonNull(executor);
|
||
|
Objects.requireNonNull(receiver);
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
mAdSelectionManager.getServiceProvider().getService();
|
||
|
service.overrideAdSelectionFromOutcomesConfigRemoteInfo(
|
||
|
request.getAdSelectionFromOutcomesConfig(),
|
||
|
request.getOutcomeSelectionLogicJs(),
|
||
|
request.getOutcomeSelectionTrustedSignals(),
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> receiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
receiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service.");
|
||
|
receiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service.", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Exception");
|
||
|
receiver.onError(new IllegalStateException("Failure of AdSelection service.", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes an override for {@link AdSelectionFromOutcomesConfig} in th Ad Selection API with
|
||
|
* associated the data in {@link RemoveAdSelectionOverrideRequest}. The {@link
|
||
|
* RemoveAdSelectionOverrideRequest} is provided by the Ads SDK.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* <p>The receiver either returns a {@code void} for a successful run, or an {@link
|
||
|
* Exception} indicates the error.
|
||
|
*/
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void removeAdSelectionFromOutcomesConfigRemoteInfoOverride(
|
||
|
@NonNull RemoveAdSelectionFromOutcomesOverrideRequest request,
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> receiver) {
|
||
|
Objects.requireNonNull(request);
|
||
|
Objects.requireNonNull(executor);
|
||
|
Objects.requireNonNull(receiver);
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
mAdSelectionManager.getServiceProvider().getService();
|
||
|
service.removeAdSelectionFromOutcomesConfigRemoteInfoOverride(
|
||
|
request.getAdSelectionFromOutcomesConfig(),
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> receiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
receiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service.");
|
||
|
receiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service.", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Exception");
|
||
|
receiver.onError(new IllegalStateException("Failure of AdSelection service.", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes all override data for {@link AdSelectionFromOutcomesConfig} in the Ad Selection API.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* <p>The receiver either returns a {@code void} for a successful run, or an {@link
|
||
|
* Exception} indicates the error.
|
||
|
*/
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void resetAllAdSelectionFromOutcomesConfigRemoteOverrides(
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> receiver) {
|
||
|
Objects.requireNonNull(executor);
|
||
|
Objects.requireNonNull(receiver);
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
mAdSelectionManager.getServiceProvider().getService();
|
||
|
service.resetAllAdSelectionFromOutcomesConfigRemoteOverrides(
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> receiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
receiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service.");
|
||
|
receiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service.", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Exception");
|
||
|
receiver.onError(new IllegalStateException("Failure of AdSelection service.", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the override for event histogram data, which is used in frequency cap filtering during
|
||
|
* ad selection.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* <p>The given {@code outcomeReceiver} either returns an empty {@link Object} if successful or
|
||
|
* an {@link Exception} which indicates the error.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* @hide
|
||
|
*/
|
||
|
// TODO(b/265204820): Unhide for frequency cap dev override API review
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void setAdCounterHistogramOverride(
|
||
|
@NonNull SetAdCounterHistogramOverrideRequest setRequest,
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> outcomeReceiver) {
|
||
|
Objects.requireNonNull(setRequest, "Request must not be null");
|
||
|
Objects.requireNonNull(executor, "Executor must not be null");
|
||
|
Objects.requireNonNull(outcomeReceiver, "Outcome receiver must not be null");
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
Objects.requireNonNull(mAdSelectionManager.getServiceProvider().getService());
|
||
|
service.setAdCounterHistogramOverride(
|
||
|
new SetAdCounterHistogramOverrideInput.Builder()
|
||
|
.setAdEventType(setRequest.getAdEventType())
|
||
|
.setAdCounterKey(setRequest.getAdCounterKey())
|
||
|
.setHistogramTimestamps(setRequest.getHistogramTimestamps())
|
||
|
.setBuyer(setRequest.getBuyer())
|
||
|
.setCustomAudienceOwner(setRequest.getCustomAudienceOwner())
|
||
|
.setCustomAudienceName(setRequest.getCustomAudienceName())
|
||
|
.build(),
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> outcomeReceiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
outcomeReceiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service");
|
||
|
outcomeReceiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Remote exception encountered while updating ad counter histogram");
|
||
|
outcomeReceiver.onError(new IllegalStateException("Failure of AdSelection service", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes an override for event histogram data, which is used in frequency cap filtering during
|
||
|
* ad selection.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* <p>The given {@code outcomeReceiver} either returns an empty {@link Object} if successful or
|
||
|
* an {@link Exception} which indicates the error.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* @hide
|
||
|
*/
|
||
|
// TODO(b/265204820): Unhide for frequency cap dev override API review
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void removeAdCounterHistogramOverride(
|
||
|
@NonNull RemoveAdCounterHistogramOverrideRequest removeRequest,
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> outcomeReceiver) {
|
||
|
Objects.requireNonNull(removeRequest, "Request must not be null");
|
||
|
Objects.requireNonNull(executor, "Executor must not be null");
|
||
|
Objects.requireNonNull(outcomeReceiver, "Outcome receiver must not be null");
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
Objects.requireNonNull(mAdSelectionManager.getServiceProvider().getService());
|
||
|
service.removeAdCounterHistogramOverride(
|
||
|
new RemoveAdCounterHistogramOverrideInput.Builder()
|
||
|
.setAdEventType(removeRequest.getAdEventType())
|
||
|
.setAdCounterKey(removeRequest.getAdCounterKey())
|
||
|
.setBuyer(removeRequest.getBuyer())
|
||
|
.build(),
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> outcomeReceiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
outcomeReceiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service");
|
||
|
outcomeReceiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Remote exception encountered while updating ad counter histogram");
|
||
|
outcomeReceiver.onError(new IllegalStateException("Failure of AdSelection service", e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes all previously set histogram overrides used in ad selection which were set by the
|
||
|
* caller application.
|
||
|
*
|
||
|
* <p>This method is intended to be used for end-to-end testing. This API is enabled only for
|
||
|
* apps in debug mode with developer options enabled.
|
||
|
*
|
||
|
* <p>The given {@code outcomeReceiver} either returns an empty {@link Object} if successful or
|
||
|
* an {@link Exception} which indicates the error.
|
||
|
*
|
||
|
* @throws IllegalStateException if this API is not enabled for the caller
|
||
|
* @hide
|
||
|
*/
|
||
|
// TODO(b/265204820): Unhide for frequency cap dev override API review
|
||
|
@RequiresPermission(
|
||
|
anyOf = {
|
||
|
ACCESS_ADSERVICES_CUSTOM_AUDIENCE,
|
||
|
ACCESS_ADSERVICES_PROTECTED_SIGNALS,
|
||
|
ACCESS_ADSERVICES_AD_SELECTION
|
||
|
})
|
||
|
public void resetAllAdCounterHistogramOverrides(
|
||
|
@NonNull @CallbackExecutor Executor executor,
|
||
|
@NonNull OutcomeReceiver<Object, Exception> outcomeReceiver) {
|
||
|
Objects.requireNonNull(executor, "Executor must not be null");
|
||
|
Objects.requireNonNull(outcomeReceiver, "Outcome receiver must not be null");
|
||
|
|
||
|
try {
|
||
|
final AdSelectionService service =
|
||
|
Objects.requireNonNull(mAdSelectionManager.getServiceProvider().getService());
|
||
|
service.resetAllAdCounterHistogramOverrides(
|
||
|
new AdSelectionOverrideCallback.Stub() {
|
||
|
@Override
|
||
|
public void onSuccess() {
|
||
|
executor.execute(() -> outcomeReceiver.onResult(new Object()));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFailure(FledgeErrorResponse failureParcel) {
|
||
|
executor.execute(
|
||
|
() ->
|
||
|
outcomeReceiver.onError(
|
||
|
AdServicesStatusUtils.asException(
|
||
|
failureParcel)));
|
||
|
}
|
||
|
});
|
||
|
} catch (NullPointerException e) {
|
||
|
sLogger.e(e, "Unable to find the AdSelection service");
|
||
|
outcomeReceiver.onError(
|
||
|
new IllegalStateException("Unable to find the AdSelection service", e));
|
||
|
} catch (RemoteException e) {
|
||
|
sLogger.e(e, "Remote exception encountered while updating ad counter histogram");
|
||
|
outcomeReceiver.onError(new IllegalStateException("Failure of AdSelection service", e));
|
||
|
}
|
||
|
}
|
||
|
}
|