Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60f0024e authored by Nino Jagar's avatar Nino Jagar Committed by Android (Google) Code Review
Browse files

Merge "Remove old blocklist code, prepare for changes" into main

parents b620800b c2fb3a3b
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -363,14 +363,6 @@ public final class ContentCaptureManager {
    public static final String DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER =
            "enable_content_protection_receiver";

    /**
     * Sets the size of the app blocklist for the content protection flow.
     *
     * @hide
     */
    public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE =
            "content_protection_apps_blocklist_size";

    /**
     * Sets the size of the in-memory ring buffer for the content protection flow.
     *
@@ -440,8 +432,6 @@ public final class ContentCaptureManager {
    /** @hide */
    public static final boolean DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER = false;
    /** @hide */
    public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 5000;
    /** @hide */
    public static final int DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE = 150;
    /** @hide */
    public static final List<List<String>> DEFAULT_CONTENT_PROTECTION_REQUIRED_GROUPS =
+10 −32
Original line number Diff line number Diff line
@@ -103,9 +103,8 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.contentprotection.ContentProtectionBlocklistManager;
import com.android.server.contentprotection.ContentProtectionAllowlistManager;
import com.android.server.contentprotection.ContentProtectionConsentManager;
import com.android.server.contentprotection.ContentProtectionPackageManager;
import com.android.server.contentprotection.RemoteContentProtectionService;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -206,9 +205,6 @@ public class ContentCaptureManagerService extends
    @GuardedBy("mLock")
    boolean mDevCfgEnableContentProtectionReceiver;

    @GuardedBy("mLock")
    int mDevCfgContentProtectionAppsBlocklistSize;

    @GuardedBy("mLock")
    int mDevCfgContentProtectionBufferSize;

@@ -237,7 +233,7 @@ public class ContentCaptureManagerService extends

    @Nullable private final ComponentName mContentProtectionServiceComponentName;

    @Nullable private final ContentProtectionBlocklistManager mContentProtectionBlocklistManager;
    @Nullable private final ContentProtectionAllowlistManager mContentProtectionAllowlistManager;

    @Nullable private final ContentProtectionConsentManager mContentProtectionConsentManager;

@@ -287,17 +283,15 @@ public class ContentCaptureManagerService extends
        if (getEnableContentProtectionReceiverLocked()) {
            mContentProtectionServiceComponentName = getContentProtectionServiceComponentName();
            if (mContentProtectionServiceComponentName != null) {
                mContentProtectionBlocklistManager = createContentProtectionBlocklistManager();
                mContentProtectionBlocklistManager.updateBlocklist(
                        mDevCfgContentProtectionAppsBlocklistSize);
                mContentProtectionAllowlistManager = createContentProtectionAllowlistManager();
                mContentProtectionConsentManager = createContentProtectionConsentManager();
            } else {
                mContentProtectionBlocklistManager = null;
                mContentProtectionAllowlistManager = null;
                mContentProtectionConsentManager = null;
            }
        } else {
            mContentProtectionServiceComponentName = null;
            mContentProtectionBlocklistManager = null;
            mContentProtectionAllowlistManager = null;
            mContentProtectionConsentManager = null;
        }
    }
@@ -445,8 +439,6 @@ public class ContentCaptureManagerService extends
                case ContentCaptureManager
                        .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER:
                case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE:
                case ContentCaptureManager
                        .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE:
                case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_REQUIRED_GROUPS_CONFIG:
                case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_CONFIG:
                case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_THRESHOLD:
@@ -502,14 +494,6 @@ public class ContentCaptureManagerService extends
                            ContentCaptureManager
                                    .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                            ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER);
            mDevCfgContentProtectionAppsBlocklistSize =
                    DeviceConfig.getInt(
                            DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                            ContentCaptureManager
                                    .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE,
                            ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE);
            // mContentProtectionBlocklistManager.updateBlocklist not called on purpose here to keep
            // it immutable at this point
            mDevCfgContentProtectionBufferSize =
                    DeviceConfig.getInt(
                            DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
@@ -542,7 +526,7 @@ public class ContentCaptureManagerService extends
                                + mDevCfgMaxBufferSize
                                + ", idleFlush="
                                + mDevCfgIdleFlushingFrequencyMs
                                + ", textFluxh="
                                + ", textFlush="
                                + mDevCfgTextChangeFlushingFrequencyMs
                                + ", logHistory="
                                + mDevCfgLogHistorySize
@@ -552,8 +536,6 @@ public class ContentCaptureManagerService extends
                                + mDevCfgDisableFlushForViewTreeAppearing
                                + ", enableContentProtectionReceiver="
                                + mDevCfgEnableContentProtectionReceiver
                                + ", contentProtectionAppsBlocklistSize="
                                + mDevCfgContentProtectionAppsBlocklistSize
                                + ", contentProtectionBufferSize="
                                + mDevCfgContentProtectionBufferSize
                                + ", contentProtectionRequiredGroupsConfig="
@@ -844,9 +826,6 @@ public class ContentCaptureManagerService extends
        pw.print("enableContentProtectionReceiver: ");
        pw.println(mDevCfgEnableContentProtectionReceiver);
        pw.print(prefix2);
        pw.print("contentProtectionAppsBlocklistSize: ");
        pw.println(mDevCfgContentProtectionAppsBlocklistSize);
        pw.print(prefix2);
        pw.print("contentProtectionBufferSize: ");
        pw.println(mDevCfgContentProtectionBufferSize);
        pw.print(prefix2);
@@ -877,9 +856,8 @@ public class ContentCaptureManagerService extends
    /** @hide */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    @NonNull
    protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager() {
        return new ContentProtectionBlocklistManager(
                new ContentProtectionPackageManager(getContext()));
    protected ContentProtectionAllowlistManager createContentProtectionAllowlistManager() {
        return new ContentProtectionAllowlistManager();
    }

    /** @hide */
@@ -1429,7 +1407,7 @@ public class ContentCaptureManagerService extends
        private boolean isContentProtectionReceiverEnabled(
                @UserIdInt int userId, @NonNull String packageName) {
            if (mContentProtectionServiceComponentName == null
                    || mContentProtectionBlocklistManager == null
                    || mContentProtectionAllowlistManager == null
                    || mContentProtectionConsentManager == null) {
                return false;
            }
@@ -1443,7 +1421,7 @@ public class ContentCaptureManagerService extends
                }
            }
            return mContentProtectionConsentManager.isConsentGranted(userId)
                    && mContentProtectionBlocklistManager.isAllowed(packageName);
                    && mContentProtectionAllowlistManager.isAllowed(packageName);
        }
    }

+38 −0
Original line number Diff line number Diff line
/*
 * 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.util.Slog;

/**
 * Manages whether the content protection is enabled for an app using a allowlist.
 *
 * @hide
 */
public class ContentProtectionAllowlistManager {

    private static final String TAG = "ContentProtectionAllowlistManager";

    public ContentProtectionAllowlistManager() {}

    /** Returns true if the package is allowed. */
    public boolean isAllowed(@NonNull String packageName) {
        Slog.v(TAG, packageName);
        return false;
    }
}
+0 −111
Original line number Diff line number Diff line
/*
 * 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.Nullable;
import android.content.pm.PackageInfo;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Manages whether the content protection is enabled for an app using a blocklist.
 *
 * @hide
 */
public class ContentProtectionBlocklistManager {

    private static final String TAG = "ContentProtectionBlocklistManager";

    private static final String PACKAGE_NAME_BLOCKLIST_FILENAME =
            "/product/etc/res/raw/content_protection/package_name_blocklist.txt";

    @NonNull private final ContentProtectionPackageManager mContentProtectionPackageManager;

    @Nullable private Set<String> mPackageNameBlocklist;

    public ContentProtectionBlocklistManager(
            @NonNull ContentProtectionPackageManager contentProtectionPackageManager) {
        mContentProtectionPackageManager = contentProtectionPackageManager;
    }

    public boolean isAllowed(@NonNull String packageName) {
        if (mPackageNameBlocklist == null) {
            // List not loaded or failed to load, don't run on anything
            return false;
        }
        if (mPackageNameBlocklist.contains(packageName)) {
            return false;
        }
        PackageInfo packageInfo = mContentProtectionPackageManager.getPackageInfo(packageName);
        if (packageInfo == null) {
            return false;
        }
        if (!mContentProtectionPackageManager.hasRequestedInternetPermissions(packageInfo)) {
            return false;
        }
        if (mContentProtectionPackageManager.isSystemApp(packageInfo)) {
            return false;
        }
        if (mContentProtectionPackageManager.isUpdatedSystemApp(packageInfo)) {
            return false;
        }
        return true;
    }

    public void updateBlocklist(int blocklistSize) {
        Slog.i(TAG, "Blocklist size updating to: " + blocklistSize);
        mPackageNameBlocklist = readPackageNameBlocklist(blocklistSize);
    }

    @Nullable
    private Set<String> readPackageNameBlocklist(int blocklistSize) {
        if (blocklistSize <= 0) {
            // Explicitly requested an empty blocklist
            return Collections.emptySet();
        }
        List<String> lines = readLinesFromRawFile(PACKAGE_NAME_BLOCKLIST_FILENAME);
        if (lines == null) {
            return null;
        }
        return lines.stream().limit(blocklistSize).collect(Collectors.toSet());
    }

    @VisibleForTesting
    @Nullable
    protected List<String> readLinesFromRawFile(@NonNull String filename) {
        try (FileReader fileReader = new FileReader(filename);
                BufferedReader bufferedReader = new BufferedReader(fileReader)) {
            return bufferedReader
                    .lines()
                    .map(line -> line.trim())
                    .filter(line -> !line.isBlank())
                    .collect(Collectors.toList());
        } catch (Exception ex) {
            Slog.e(TAG, "Failed to read: " + filename, ex);
            return null;
        }
    }
}
+0 −82
Original line number Diff line number Diff line
/*
 * 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.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.PackageInfoFlags;
import android.util.Slog;

import java.util.Arrays;

/**
 * Basic package manager for content protection using content capture.
 *
 * @hide
 */
public class ContentProtectionPackageManager {

    private static final String TAG = "ContentProtectionPackageManager";

    private static final PackageInfoFlags PACKAGE_INFO_FLAGS =
            PackageInfoFlags.of(PackageManager.GET_PERMISSIONS);

    @NonNull private final PackageManager mPackageManager;

    public ContentProtectionPackageManager(@NonNull Context context) {
        mPackageManager = context.getPackageManager();
    }

    @Nullable
    public PackageInfo getPackageInfo(@NonNull String packageName) {
        try {
            return mPackageManager.getPackageInfo(packageName, PACKAGE_INFO_FLAGS);
        } catch (NameNotFoundException ex) {
            Slog.w(TAG, "Package info not found for: " + packageName, ex);
            return null;
        }
    }

    public boolean isSystemApp(@NonNull PackageInfo packageInfo) {
        return packageInfo.applicationInfo != null && isSystemApp(packageInfo.applicationInfo);
    }

    private boolean isSystemApp(@NonNull ApplicationInfo applicationInfo) {
        return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
    }

    public boolean isUpdatedSystemApp(@NonNull PackageInfo packageInfo) {
        return packageInfo.applicationInfo != null
                && isUpdatedSystemApp(packageInfo.applicationInfo);
    }

    private boolean isUpdatedSystemApp(@NonNull ApplicationInfo applicationInfo) {
        return (applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
    }

    public boolean hasRequestedInternetPermissions(@NonNull PackageInfo packageInfo) {
        return packageInfo.requestedPermissions != null
                && Arrays.asList(packageInfo.requestedPermissions)
                        .contains(Manifest.permission.INTERNET);
    }
}
Loading