blob: b354750bc8c41ccff9f768ef0da51fe0cdbf304b [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.app.adservices;
import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_MANAGER;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.adservices.consent.ConsentParcel;
import android.app.adservices.topics.TopicParcel;
import android.app.sdksandbox.SdkSandboxManager;
import android.content.Context;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Objects;
/**
* AdServices Manager to handle the internal communication between PPAPI process and AdServices
* System Service.
*
* @hide
*/
public final class AdServicesManager {
@GuardedBy("SINGLETON_LOCK")
private static AdServicesManager sSingleton;
private final IAdServicesManager mService;
private static final Object SINGLETON_LOCK = new Object();
@IntDef(value = {MEASUREMENT_DELETION})
@Retention(RetentionPolicy.SOURCE)
public @interface DeletionApiType {}
public static final int MEASUREMENT_DELETION = 0;
// TODO(b/267789077): Create bit for other APIs.
@VisibleForTesting
public AdServicesManager(@NonNull IAdServicesManager iAdServicesManager) {
Objects.requireNonNull(iAdServicesManager, "AdServicesManager is NULL!");
mService = iAdServicesManager;
}
/** Get the singleton of AdServicesManager. Only used on T+ */
@Nullable
public static AdServicesManager getInstance(@NonNull Context context) {
synchronized (SINGLETON_LOCK) {
if (sSingleton == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// TODO(b/262282035): Fix this work around in U+.
// Get the AdServicesManagerService's Binder from the SdkSandboxManager.
// This is a workaround for b/262282035.
IBinder iBinder =
context.getSystemService(SdkSandboxManager.class).getAdServicesManager();
sSingleton = new AdServicesManager(IAdServicesManager.Stub.asInterface(iBinder));
}
}
return sSingleton;
}
/** Return the User Consent */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public ConsentParcel getConsent(@ConsentParcel.ConsentApiType int consentApiType) {
try {
return mService.getConsent(consentApiType);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Set the User Consent */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void setConsent(@NonNull ConsentParcel consentParcel) {
Objects.requireNonNull(consentParcel);
try {
mService.setConsent(consentParcel);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Saves information to the storage that notification was displayed for the first time to the
* user.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordNotificationDisplayed() {
try {
mService.recordNotificationDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns information whether Consent Notification was displayed or not.
*
* @return true if Consent Notification was displayed, otherwise false.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean wasNotificationDisplayed() {
try {
return mService.wasNotificationDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Saves information to the storage that notification was displayed for the first time to the
* user.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordGaUxNotificationDisplayed() {
try {
mService.recordGaUxNotificationDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns information whether Consent GA UX Notification was displayed or not.
*
* @return true if Consent GA UX Notification was displayed, otherwise false.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean wasGaUxNotificationDisplayed() {
try {
return mService.wasGaUxNotificationDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Saves information to the storage that topics consent page was displayed for the first time to
* the user.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordTopicsConsentPageDisplayed() {
try {
mService.recordTopicsConsentPageDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Record a blocked topic.
*
* @param blockedTopicParcels the blocked topic to record
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordBlockedTopic(@NonNull List<TopicParcel> blockedTopicParcels) {
try {
mService.recordBlockedTopic(blockedTopicParcels);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Remove a blocked topic.
*
* @param blockedTopicParcel the blocked topic to remove
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void removeBlockedTopic(@NonNull TopicParcel blockedTopicParcel) {
try {
mService.removeBlockedTopic(blockedTopicParcel);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Get all blocked topics.
*
* @return a {@code List} of all blocked topics.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public List<TopicParcel> retrieveAllBlockedTopics() {
try {
return mService.retrieveAllBlockedTopics();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Clear all Blocked Topics */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void clearAllBlockedTopics() {
try {
mService.clearAllBlockedTopics();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns information whether topics Consent page was displayed or not.
*
* @return true if topics consent page was displayed, otherwise false.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean wasTopicsConsentPageDisplayed() {
try {
return mService.wasTopicsConsentPageDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Saves information to the storage that fledge and msmt consent page was displayed for the
* first time to the user.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordFledgeAndMsmtConsentPageDisplayed() {
try {
mService.recordFledgeAndMsmtConsentPageDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns information whether fledge and msmt Consent page was displayed or not.
*
* @return true if fledge and msmt consent page was displayed, otherwise false.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean wasFledgeAndMsmtConsentPageDisplayed() {
try {
return mService.wasFledgeAndMsmtConsentPageDisplayed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Returns the list of apps with consent. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public List<String> getKnownAppsWithConsent(List<String> installedPackages) {
try {
return mService.getKnownAppsWithConsent(installedPackages);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Returns the list of apps with revoked consent. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public List<String> getAppsWithRevokedConsent(List<String> installedPackages) {
try {
return mService.getAppsWithRevokedConsent(installedPackages);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Set user consent for an app */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void setConsentForApp(String packageName, int packageUid, boolean isConsentRevoked) {
try {
mService.setConsentForApp(packageName, packageUid, isConsentRevoked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Reset all apps and blocked apps. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void clearKnownAppsWithConsent() {
try {
mService.clearKnownAppsWithConsent();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Reset all apps consent. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void clearAllAppConsentData() {
try {
mService.clearAllAppConsentData();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Get if user consent is revoked for a given app.
*
* @return {@code true} if the user consent was revoked.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean isConsentRevokedForApp(String packageName, int packageUid) {
try {
return mService.isConsentRevokedForApp(packageName, packageUid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Set user consent if the app first time request access and/or return consent value for the
* app.
*
* @return {@code true} if user consent was given.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean setConsentForAppIfNew(
String packageName, int packageUid, boolean isConsentRevoked) {
try {
return mService.setConsentForAppIfNew(packageName, packageUid, isConsentRevoked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Clear the app consent entry for uninstalled app. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void clearConsentForUninstalledApp(String packageName, int packageUid) {
try {
mService.clearConsentForUninstalledApp(packageName, packageUid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Saves information to the storage that a deletion of measurement data occurred. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordAdServicesDeletionOccurred(@DeletionApiType int deletionType) {
try {
mService.recordAdServicesDeletionOccurred(deletionType);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Saves the PP API default consent of a user. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordDefaultConsent(boolean defaultConsent) {
try {
mService.recordDefaultConsent(defaultConsent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Saves the topics default consent of a user. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordTopicsDefaultConsent(boolean defaultConsent) {
try {
mService.recordTopicsDefaultConsent(defaultConsent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Saves the FLEDGE default consent of a user. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordFledgeDefaultConsent(boolean defaultConsent) {
try {
mService.recordFledgeDefaultConsent(defaultConsent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Saves the measurement default consent of a user. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordMeasurementDefaultConsent(boolean defaultConsent) {
try {
mService.recordMeasurementDefaultConsent(defaultConsent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Saves the default AdId state of a user. */
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public void recordDefaultAdIdState(boolean defaultAdIdState) {
try {
mService.recordDefaultAdIdState(defaultAdIdState);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Checks whether the AdServices module needs to handle data reconciliation after a rollback.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean needsToHandleRollbackReconciliation(@DeletionApiType int deletionType) {
try {
return mService.needsToHandleRollbackReconciliation(deletionType);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the PP API default consent of a user.
*
* @return true if the PP API default consent is given, false otherwise.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean getDefaultConsent() {
try {
return mService.getDefaultConsent();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the topics default consent of a user.
*
* @return true if the topics default consent is given, false otherwise.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean getTopicsDefaultConsent() {
try {
return mService.getTopicsDefaultConsent();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the FLEDGE default consent of a user.
*
* @return true if the FLEDGE default consent is given, false otherwise.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean getFledgeDefaultConsent() {
try {
return mService.getFledgeDefaultConsent();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the measurement default consent of a user.
*
* @return true if the measurement default consent is given, false otherwise.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean getMeasurementDefaultConsent() {
try {
return mService.getMeasurementDefaultConsent();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the default AdId state of a user.
*
* @return true if the default AdId State is enabled, false otherwise.
*/
@RequiresPermission(ACCESS_ADSERVICES_MANAGER)
public boolean getDefaultAdIdState() {
try {
return mService.getDefaultAdIdState();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}