blob: e87653aae1e9f15aea5c50e7c28c829c9abeb999 [file] [log] [blame]
/*
* Copyright (C) 2023 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.common;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.adservices.AdServicesParcelableUtil;
import com.android.internal.annotations.VisibleForTesting;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Objects;
/**
* A container class for filters which are associated with an ad.
*
* <p>If any of the filters in an {@link AdFilters} instance are not satisfied, the associated ad
* will not be eligible for ad selection. Filters are optional ad parameters and are not required as
* part of {@link AdData}.
*/
public final class AdFilters implements Parcelable {
/** @hide */
@VisibleForTesting public static final String FREQUENCY_CAP_FIELD_NAME = "frequency_cap";
/** @hide */
@VisibleForTesting public static final String APP_INSTALL_FIELD_NAME = "app_install";
/** @hide */
@Nullable private final FrequencyCapFilters mFrequencyCapFilters;
@Nullable private final AppInstallFilters mAppInstallFilters;
@NonNull
public static final Creator<AdFilters> CREATOR =
new Creator<AdFilters>() {
@Override
public AdFilters createFromParcel(@NonNull Parcel in) {
Objects.requireNonNull(in);
return new AdFilters(in);
}
@Override
public AdFilters[] newArray(int size) {
return new AdFilters[size];
}
};
private AdFilters(@NonNull Builder builder) {
Objects.requireNonNull(builder);
mFrequencyCapFilters = builder.mFrequencyCapFilters;
mAppInstallFilters = builder.mAppInstallFilters;
}
private AdFilters(@NonNull Parcel in) {
Objects.requireNonNull(in);
mFrequencyCapFilters =
AdServicesParcelableUtil.readNullableFromParcel(
in, FrequencyCapFilters.CREATOR::createFromParcel);
mAppInstallFilters =
AdServicesParcelableUtil.readNullableFromParcel(
in, AppInstallFilters.CREATOR::createFromParcel);
}
/**
* Gets the {@link FrequencyCapFilters} instance that represents all frequency cap filters for
* the ad.
*
* <p>If {@code null}, there are no frequency cap filters which apply to the ad.
*/
@Nullable
public FrequencyCapFilters getFrequencyCapFilters() {
return mFrequencyCapFilters;
}
/**
* Gets the {@link AppInstallFilters} instance that represents all app install filters for the
* ad.
*
* <p>If {@code null}, there are no app install filters which apply to the ad.
*
* @hide
*/
@Nullable
public AppInstallFilters getAppInstallFilters() {
return mAppInstallFilters;
}
/**
* @return The estimated size of this object, in bytes.
* @hide
*/
public int getSizeInBytes() {
int size = 0;
if (mFrequencyCapFilters != null) {
size += mFrequencyCapFilters.getSizeInBytes();
}
if (mAppInstallFilters != null) {
size += mAppInstallFilters.getSizeInBytes();
}
return size;
}
/**
* A JSON serializer.
*
* @return A JSON serialization of this object.
* @hide
*/
public JSONObject toJson() throws JSONException {
JSONObject toReturn = new JSONObject();
if (mFrequencyCapFilters != null) {
toReturn.put(FREQUENCY_CAP_FIELD_NAME, mFrequencyCapFilters.toJson());
}
if (mAppInstallFilters != null) {
toReturn.put(APP_INSTALL_FIELD_NAME, mAppInstallFilters.toJson());
}
return toReturn;
}
/**
* A JSON de-serializer.
*
* @param json A JSON representation of an {@link AdFilters} object as would be generated by
* {@link #toJson()}.
* @return An {@link AdFilters} object generated from the given JSON.
* @hide
*/
public static AdFilters fromJson(JSONObject json) throws JSONException {
Builder builder = new Builder();
if (json.has(FREQUENCY_CAP_FIELD_NAME)) {
builder.setFrequencyCapFilters(
FrequencyCapFilters.fromJson(json.getJSONObject(FREQUENCY_CAP_FIELD_NAME)));
}
if (json.has(APP_INSTALL_FIELD_NAME)) {
builder.setAppInstallFilters(
AppInstallFilters.fromJson(json.getJSONObject(APP_INSTALL_FIELD_NAME)));
}
return builder.build();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
Objects.requireNonNull(dest);
AdServicesParcelableUtil.writeNullableToParcel(
dest,
mFrequencyCapFilters,
(targetParcel, sourceFilters) -> sourceFilters.writeToParcel(targetParcel, flags));
AdServicesParcelableUtil.writeNullableToParcel(
dest,
mAppInstallFilters,
(targetParcel, sourceFilters) -> sourceFilters.writeToParcel(targetParcel, flags));
}
/** @hide */
@Override
public int describeContents() {
return 0;
}
/** Checks whether the {@link AdFilters} objects represent the same set of filters. */
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AdFilters)) return false;
AdFilters adFilters = (AdFilters) o;
return Objects.equals(mFrequencyCapFilters, adFilters.mFrequencyCapFilters)
&& Objects.equals(mAppInstallFilters, adFilters.mAppInstallFilters);
}
/** Returns the hash of the {@link AdFilters} object's data. */
@Override
public int hashCode() {
return Objects.hash(mFrequencyCapFilters, mAppInstallFilters);
}
@Override
public String toString() {
return "AdFilters{" + generateFrequencyCapString() + generateAppInstallString() + "}";
}
private String generateFrequencyCapString() {
// TODO(b/221876775) Add fcap once it is unhidden
return "";
}
private String generateAppInstallString() {
// TODO(b/266837113) Add app install once it is unhidden
return "";
}
/** Builder for creating {@link AdFilters} objects. */
public static final class Builder {
@Nullable private FrequencyCapFilters mFrequencyCapFilters;
@Nullable private AppInstallFilters mAppInstallFilters;
public Builder() {}
/**
* Sets the {@link FrequencyCapFilters} which will apply to the ad.
*
* <p>If set to {@code null} or not set, no frequency cap filters will be associated with
* the ad.
*/
@NonNull
public Builder setFrequencyCapFilters(@Nullable FrequencyCapFilters frequencyCapFilters) {
mFrequencyCapFilters = frequencyCapFilters;
return this;
}
/**
* Sets the {@link AppInstallFilters} which will apply to the ad.
*
* <p>If set to {@code null} or not set, no app install filters will be associated with the
* ad.
*
* @hide
*/
@NonNull
public Builder setAppInstallFilters(@Nullable AppInstallFilters appInstallFilters) {
mAppInstallFilters = appInstallFilters;
return this;
}
/** Builds and returns an {@link AdFilters} instance. */
@NonNull
public AdFilters build() {
return new AdFilters(this);
}
}
}