blob: 1fba9ce5b78fe74de87f3c04a0371d3ce5a286c1 [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 com.android.server.adservices.consent;
import static com.android.server.adservices.consent.ConsentManager.NOTIFICATION_DISPLAYED_ONCE;
import static com.android.server.adservices.consent.ConsentManager.STORAGE_VERSION;
import static com.android.server.adservices.consent.ConsentManager.STORAGE_XML_IDENTIFIER;
import static com.android.server.adservices.consent.ConsentManager.VERSION_KEY;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import android.app.adservices.consent.ConsentParcel;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.server.adservices.common.BooleanFileDatastore;
import com.android.server.adservices.feature.PrivacySandboxFeatureType;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/** Tests for {@link ConsentManager} */
public class ConsentManagerTest {
private static final Context PPAPI_CONTEXT = ApplicationProvider.getApplicationContext();
private static final String BASE_DIR = PPAPI_CONTEXT.getFilesDir().getAbsolutePath();
private BooleanFileDatastore mDatastore;
@Before
public void setup() {
mDatastore =
new BooleanFileDatastore(
PPAPI_CONTEXT.getFilesDir().getAbsolutePath(),
STORAGE_XML_IDENTIFIER,
STORAGE_VERSION,
VERSION_KEY);
}
@After
public void tearDown() {
mDatastore.tearDownForTesting();
}
@Test
public void testGetConsentDataStoreDir() {
// The Data store is in folder with the following format.
// /data/system/adservices/user_id/consent/
assertThat(
ConsentDatastoreLocationHelper.getConsentDataStoreDir(
/* baseDir */ "/data/system/adservices", /* userIdentifier */ 0))
.isEqualTo("/data/system/adservices/0/consent");
assertThat(
ConsentDatastoreLocationHelper.getConsentDataStoreDir(
/* baseDir */ "/data/system/adservices", /* userIdentifier */ 1))
.isEqualTo("/data/system/adservices/1/consent");
assertThrows(
NullPointerException.class,
() -> ConsentDatastoreLocationHelper.getConsentDataStoreDir(null, 0));
}
@Test
public void testCreateAndInitBooleanFileDatastore() {
BooleanFileDatastore datastore = null;
try {
datastore = ConsentManager.createAndInitBooleanFileDatastore(BASE_DIR);
} catch (IOException e) {
Assert.fail("Fail to create the DataStore");
}
// Assert that the DataStore is created and initialized with NOTIFICATION_DISPLAYED_ONCE
// is false.
assertThat(datastore.get(NOTIFICATION_DISPLAYED_ONCE)).isFalse();
}
@Test
public void testGetConsent_unSet() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// Newly initialized ConsentManager has consent = false.
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
assertThat(consentManager.getConsent(ConsentParcel.TOPICS).isIsGiven()).isFalse();
assertThat(consentManager.getConsent(ConsentParcel.FLEDGE).isIsGiven()).isFalse();
assertThat(consentManager.getConsent(ConsentParcel.MEASUREMENT).isIsGiven()).isFalse();
}
@Test
public void testGetAndSetConsent_null() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
consentManager.setConsent(
new ConsentParcel.Builder()
.setConsentApiType(ConsentParcel.ALL_API)
.setIsGiven(null)
.build());
// null means the consent is not given (false).
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
consentManager.setConsent(
new ConsentParcel.Builder()
.setConsentApiType(ConsentParcel.TOPICS)
.setIsGiven(null)
.build());
// null means the consent is not given (false).
assertThat(consentManager.getConsent(ConsentParcel.TOPICS).isIsGiven()).isFalse();
consentManager.setConsent(
new ConsentParcel.Builder()
.setConsentApiType(ConsentParcel.FLEDGE)
.setIsGiven(null)
.build());
// null means the consent is not given (false).
assertThat(consentManager.getConsent(ConsentParcel.FLEDGE).isIsGiven()).isFalse();
consentManager.setConsent(
new ConsentParcel.Builder()
.setConsentApiType(ConsentParcel.MEASUREMENT)
.setIsGiven(null)
.build());
// null means the consent is not given (false).
assertThat(consentManager.getConsent(ConsentParcel.MEASUREMENT).isIsGiven()).isFalse();
}
@Test
public void testGetAndSetConsent_nonNull() throws IOException {
// Create a ConsentManager for user 0.
ConsentManager consentManager0 =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
consentManager0.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.ALL_API));
assertThat(consentManager0.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
consentManager0.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.ALL_API));
assertThat(consentManager0.getConsent(ConsentParcel.ALL_API).isIsGiven()).isTrue();
consentManager0.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.TOPICS));
assertThat(consentManager0.getConsent(ConsentParcel.TOPICS).isIsGiven()).isFalse();
consentManager0.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.TOPICS));
assertThat(consentManager0.getConsent(ConsentParcel.TOPICS).isIsGiven()).isTrue();
consentManager0.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.FLEDGE));
assertThat(consentManager0.getConsent(ConsentParcel.FLEDGE).isIsGiven()).isFalse();
consentManager0.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.FLEDGE));
assertThat(consentManager0.getConsent(ConsentParcel.FLEDGE).isIsGiven()).isTrue();
consentManager0.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.MEASUREMENT));
assertThat(consentManager0.getConsent(ConsentParcel.MEASUREMENT).isIsGiven()).isFalse();
consentManager0.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.MEASUREMENT));
assertThat(consentManager0.getConsent(ConsentParcel.MEASUREMENT).isIsGiven()).isTrue();
// Create another ConsentManager for user 1 to make sure ConsentManagers
// are isolated by users.
ConsentManager consentManager1 =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 1);
// By default, this ConsentManager has isGiven false.
assertThat(consentManager1.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
// Set the user 0 to revoked.
consentManager0.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.ALL_API));
assertThat(consentManager0.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
// Set the user 1 to given.
consentManager1.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.ALL_API));
assertThat(consentManager1.getConsent(ConsentParcel.ALL_API).isIsGiven()).isTrue();
// This validates that the consentManager for user 0 was not changed when updating
// ConsentManager for user 1.
assertThat(consentManager0.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
}
@Test
public void testGetAndSetConsent_upgrade() throws IOException {
// Create a ConsentManager for user 0.
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// Test upgrading from 1 consent to 3 consents.
consentManager.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.ALL_API));
assertThat(consentManager.getConsent(ConsentParcel.TOPICS).isIsGiven()).isFalse();
assertThat(consentManager.getConsent(ConsentParcel.FLEDGE).isIsGiven()).isFalse();
assertThat(consentManager.getConsent(ConsentParcel.MEASUREMENT).isIsGiven()).isFalse();
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.ALL_API));
assertThat(consentManager.getConsent(ConsentParcel.TOPICS).isIsGiven()).isTrue();
assertThat(consentManager.getConsent(ConsentParcel.FLEDGE).isIsGiven()).isTrue();
assertThat(consentManager.getConsent(ConsentParcel.MEASUREMENT).isIsGiven()).isTrue();
}
@Test
public void testGetAndSetConsent_downgrade() throws IOException {
// Create a ConsentManager for user 0.
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// Test downgrading from 3 consents to 1 consent.
// For Topics.
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.ALL_API));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isTrue();
// Now even setting only Topics to false, the ALL_API will get false value too.
consentManager.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.TOPICS));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
// For FLEDGE
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.ALL_API));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isTrue();
// Now even setting only FLEDGE to false, the ALL_API will get false value too.
consentManager.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.FLEDGE));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
// For Measurement
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.ALL_API));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isTrue();
// Now even setting only Measurement to false, the ALL_API will get false value too.
consentManager.setConsent(ConsentParcel.createRevokedConsent(ConsentParcel.MEASUREMENT));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isFalse();
// Now setting 3 consents to true and the ALL_API will be true too.
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.TOPICS));
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.FLEDGE));
consentManager.setConsent(ConsentParcel.createGivenConsent(ConsentParcel.MEASUREMENT));
assertThat(consentManager.getConsent(ConsentParcel.ALL_API).isIsGiven()).isTrue();
}
@Test
public void testGetConsent_unSetConsentApiType() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// Newly initialized ConsentManager has consent = false.
assertThrows(
IllegalArgumentException.class,
() -> {
consentManager.setConsent(
new ConsentParcel.Builder()
// Not set the ConsentApiType.
// .setConsentApiType(xxx)
.setIsGiven(true)
.build());
});
}
@Test
public void testRecordNotificationDisplayed() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// First, the notification displayed is false.
assertThat(consentManager.wasNotificationDisplayed()).isFalse();
consentManager.recordNotificationDisplayed();
assertThat(consentManager.wasNotificationDisplayed()).isTrue();
}
@Test
public void testGaUxRecordNotificationDisplayed() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// First, the notification displayed is false.
assertThat(consentManager.wasGaUxNotificationDisplayed()).isFalse();
consentManager.recordGaUxNotificationDisplayed();
assertThat(consentManager.wasGaUxNotificationDisplayed()).isTrue();
}
@Test
public void testDeleteConsentDataStoreDir() throws IOException {
int userIdentifier = 0;
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, userIdentifier);
String consentDataStoreDir =
ConsentDatastoreLocationHelper.getConsentDataStoreDirAndCreateDir(
BASE_DIR, userIdentifier);
Path packageDir = Paths.get(consentDataStoreDir);
assertThat(Files.exists(packageDir)).isTrue();
String userDirectoryPath = BASE_DIR + "/" + userIdentifier;
assertThat(consentManager.deleteUserDirectory(new File(userDirectoryPath))).isTrue();
assertThat(Files.exists(packageDir)).isFalse();
}
@Test
public void testSetUserManualInteractionWithConsentToTrue() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
consentManager.recordUserManualInteractionWithConsent(1);
assertThat(consentManager.getUserManualInteractionWithConsent()).isEqualTo(1);
}
@Test
public void testSetUserManualInteractionWithConsentToFalse() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
consentManager.recordUserManualInteractionWithConsent(-1);
assertThat(consentManager.getUserManualInteractionWithConsent()).isEqualTo(-1);
}
@Test
public void testSetUserManualInteractionWithConsentToUnknown() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
consentManager.recordUserManualInteractionWithConsent(0);
assertThat(consentManager.getUserManualInteractionWithConsent()).isEqualTo(0);
}
@Test
public void testSetCurrentPrivacySandboxFeature() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
// All bits are fall in the beginning.
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_UNSUPPORTED))
.isEqualTo(false);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_FIRST_CONSENT))
.isEqualTo(false);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_RECONSENT))
.isEqualTo(false);
consentManager.setCurrentPrivacySandboxFeature(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_FIRST_CONSENT.name());
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_FIRST_CONSENT))
.isEqualTo(true);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_UNSUPPORTED))
.isEqualTo(false);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_RECONSENT))
.isEqualTo(false);
consentManager.setCurrentPrivacySandboxFeature(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_RECONSENT.name());
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_RECONSENT))
.isEqualTo(true);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_FIRST_CONSENT))
.isEqualTo(false);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_UNSUPPORTED))
.isEqualTo(false);
consentManager.setCurrentPrivacySandboxFeature(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_UNSUPPORTED.name());
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_UNSUPPORTED))
.isEqualTo(true);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_FIRST_CONSENT))
.isEqualTo(false);
assertThat(
consentManager.isPrivacySandboxFeatureEnabled(
PrivacySandboxFeatureType.PRIVACY_SANDBOX_RECONSENT))
.isEqualTo(false);
}
@Test
public void testDeleteConsentDataStoreDirUserIdentifierNotPresent() throws IOException {
int userIdentifier = 0;
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, userIdentifier);
String consentDataStoreDir =
ConsentDatastoreLocationHelper.getConsentDataStoreDirAndCreateDir(
BASE_DIR, userIdentifier);
Path packageDir = Paths.get(consentDataStoreDir);
int userIdentifierNotPresent = 3;
// Try deleting with non-existent user id. Nothing should happen and ensure userIdentifier
// is present.
assertThat(
consentManager.deleteUserDirectory(
new File(BASE_DIR + userIdentifierNotPresent)))
.isFalse();
assertThat(Files.exists(packageDir)).isTrue();
}
@Test
public void isU18AccountTest() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
assertThat(consentManager.isU18Account()).isFalse();
consentManager.setU18Account(true);
assertThat(consentManager.isU18Account()).isTrue();
}
@Test
public void isEntryPointEnabledTest() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
assertThat(consentManager.isEntryPointEnabled()).isFalse();
consentManager.setEntryPointEnabled(true);
assertThat(consentManager.isEntryPointEnabled()).isTrue();
}
@Test
public void isAdultAccountTest() throws IOException {
ConsentManager consentManager =
ConsentManager.createConsentManager(BASE_DIR, /* userIdentifier */ 0);
assertThat(consentManager.isAdultAccount()).isFalse();
consentManager.setAdultAccount(true);
assertThat(consentManager.isAdultAccount()).isTrue();
}
}