/* * 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 com.android.server.contentprotection; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.admin.DevicePolicyManagerInternal; import android.content.ContentResolver; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; /** * Manages consent for content protection. * * @hide */ public class ContentProtectionConsentManager { private static final String TAG = "ContentProtectionConsentManager"; private static final String KEY_PACKAGE_VERIFIER_USER_CONSENT = "package_verifier_user_consent"; @NonNull private final ContentResolver mContentResolver; @NonNull private final DevicePolicyManagerInternal mDevicePolicyManagerInternal; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) @NonNull public final ContentObserver mContentObserver; private volatile boolean mCachedPackageVerifierConsent; public ContentProtectionConsentManager( @NonNull Handler handler, @NonNull ContentResolver contentResolver, @NonNull DevicePolicyManagerInternal devicePolicyManagerInternal) { mContentResolver = contentResolver; mDevicePolicyManagerInternal = devicePolicyManagerInternal; mContentObserver = new SettingsObserver(handler); contentResolver.registerContentObserver( Settings.Global.getUriFor(KEY_PACKAGE_VERIFIER_USER_CONSENT), /* notifyForDescendants= */ false, mContentObserver, UserHandle.USER_ALL); mCachedPackageVerifierConsent = isPackageVerifierConsentGranted(); } /** * Returns true if all the consents are granted */ public boolean isConsentGranted(@UserIdInt int userId) { return mCachedPackageVerifierConsent && !isUserOrganizationManaged(userId); } private boolean isPackageVerifierConsentGranted() { // Not always cached internally return Settings.Global.getInt( mContentResolver, KEY_PACKAGE_VERIFIER_USER_CONSENT, /* def= */ 0) >= 1; } private boolean isUserOrganizationManaged(@UserIdInt int userId) { // Cached internally return mDevicePolicyManagerInternal.isUserOrganizationManaged(userId); } private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { final String property = uri.getLastPathSegment(); if (property == null) { return; } switch (property) { case KEY_PACKAGE_VERIFIER_USER_CONSENT: mCachedPackageVerifierConsent = isPackageVerifierConsentGranted(); return; default: Slog.w(TAG, "Ignoring unexpected property: " + property); } } } }