blob: 46251cff73b622404aa4cf39377c361d5eb1b145 [file] [log] [blame]
/*
* 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.customaudience;
import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE;
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;
/** TestCustomAudienceManager provides APIs for app and ad-SDKs to test custom audiences. */
// TODO(b/269798827): Enable for R.
@RequiresApi(Build.VERSION_CODES.S)
public class TestCustomAudienceManager {
private static final LoggerFactory.Logger sLogger = LoggerFactory.getFledgeLogger();
private final CustomAudienceManager mCustomAudienceManager;
private final String mCallerPackageName;
TestCustomAudienceManager(
@NonNull CustomAudienceManager customAudienceManager,
@NonNull String callerPackageName) {
Objects.requireNonNull(customAudienceManager);
Objects.requireNonNull(callerPackageName);
mCustomAudienceManager = customAudienceManager;
mCallerPackageName = callerPackageName;
}
/**
* Overrides the Custom Audience API to avoid fetching data from remote servers and use the data
* provided in {@link AddCustomAudienceOverrideRequest} instead. The {@link
* AddCustomAudienceOverrideRequest} 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.
*
* <p>This call will fail silently if the {@code owner} in the {@code request} is not the
* calling app's package name.
*
* @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(ACCESS_ADSERVICES_CUSTOM_AUDIENCE)
public void overrideCustomAudienceRemoteInfo(
@NonNull AddCustomAudienceOverrideRequest request,
@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Object, Exception> receiver) {
Objects.requireNonNull(request);
Objects.requireNonNull(executor);
Objects.requireNonNull(receiver);
try {
final ICustomAudienceService service = mCustomAudienceManager.getService();
service.overrideCustomAudienceRemoteInfo(
mCallerPackageName,
request.getBuyer(),
request.getName(),
request.getBiddingLogicJs(),
request.getBiddingLogicJsVersion(),
request.getTrustedBiddingSignals(),
new CustomAudienceOverrideCallback.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 (RemoteException e) {
sLogger.e(e, "Exception");
receiver.onError(new IllegalStateException("Internal Error!", e));
}
}
/**
* Removes an override in th Custom Audience API with associated the data in {@link
* RemoveCustomAudienceOverrideRequest}.
*
* <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 {@link RemoveCustomAudienceOverrideRequest} is provided by the Ads SDK. The
* receiver either returns a {@code void} for a successful run, or an {@link Exception}
* indicates the error.
*/
@RequiresPermission(ACCESS_ADSERVICES_CUSTOM_AUDIENCE)
public void removeCustomAudienceRemoteInfoOverride(
@NonNull RemoveCustomAudienceOverrideRequest request,
@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Object, Exception> receiver) {
Objects.requireNonNull(request);
Objects.requireNonNull(executor);
Objects.requireNonNull(receiver);
try {
final ICustomAudienceService service = mCustomAudienceManager.getService();
service.removeCustomAudienceRemoteInfoOverride(
mCallerPackageName,
request.getBuyer(),
request.getName(),
new CustomAudienceOverrideCallback.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 (RemoteException e) {
sLogger.e(e, "Exception");
receiver.onError(new IllegalStateException("Internal Error!", e));
}
}
/**
* Removes all override data in the Custom Audience 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(ACCESS_ADSERVICES_CUSTOM_AUDIENCE)
public void resetAllCustomAudienceOverrides(
@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Object, Exception> receiver) {
Objects.requireNonNull(executor);
Objects.requireNonNull(receiver);
try {
final ICustomAudienceService service = mCustomAudienceManager.getService();
service.resetAllCustomAudienceOverrides(
new CustomAudienceOverrideCallback.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 (RemoteException e) {
sLogger.e(e, "Exception");
receiver.onError(new IllegalStateException("Internal Error!", e));
}
}
}