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

Commit 790be046 authored by Felipe Leme's avatar Felipe Leme
Browse files

Defined new APIs to whitelist content capture for specific URLs.

Test: m update-api # not implemented yet
Fixes: 129267994

Change-Id: Ibd83368ce79e8dfe901164f921304091c41428fc
parent c1bb6ae5
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -53046,6 +53046,16 @@ package android.view.autofill {
package android.view.contentcapture {
  public final class ContentCaptureCondition implements android.os.Parcelable {
    ctor public ContentCaptureCondition(@NonNull android.content.LocusId, int);
    method public int describeContents();
    method public int getFlags();
    method @NonNull public android.content.LocusId getLocusId();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureCondition> CREATOR;
    field public static final int FLAG_IS_REGEX = 2; // 0x2
  }
  public final class ContentCaptureContext implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public static android.view.contentcapture.ContentCaptureContext forLocusId(@NonNull String);
@@ -53062,6 +53072,7 @@ package android.view.contentcapture {
  }
  public final class ContentCaptureManager {
    method @Nullable public java.util.Set<android.view.contentcapture.ContentCaptureCondition> getContentCaptureConditions();
    method @Nullable public android.content.ComponentName getServiceComponentName();
    method public boolean isContentCaptureEnabled();
    method public void removeUserData(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+1 −0
Original line number Diff line number Diff line
@@ -6444,6 +6444,7 @@ package android.service.contentcapture {
    method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
    method public void onDisconnected();
    method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
    method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
    method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
    field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
    field public static final String SERVICE_META_DATA = "android.content_capture";
+1 −0
Original line number Diff line number Diff line
@@ -2457,6 +2457,7 @@ package android.service.contentcapture {
    method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
    method public void onDisconnected();
    method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
    method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
    method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
    field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
    field public static final String SERVICE_META_DATA = "android.content_capture";
+27 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.service.autofill.AutofillService;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.view.contentcapture.ContentCaptureCondition;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureManager;
@@ -216,6 +217,32 @@ public abstract class ContentCaptureService extends Service {
        }
    }

    /**
     * Explicitly sets the conditions for which content capture should be available by an app.
     *
     * <p>Typically used to restrict content capture to a few websites on browser apps. Example:
     *
     * <code>
     *   ArraySet<ContentCaptureCondition> conditions = new ArraySet<>(1);
     *   conditions.add(new ContentCaptureCondition(new LocusId("^https://.*\\.example\\.com$"),
     *       ContentCaptureCondition.FLAG_IS_REGEX));
     *   service.setContentCaptureConditions("com.example.browser_app", conditions);
     *
     * </code>
     *
     * <p>NOTE: </p> this method doesn't automatically disable content capture for the given
     * conditions; it's up to the {@code packageName} implementation to call
     * {@link ContentCaptureManager#getContentCaptureConditions()} and disable it accordingly.
     *
     * @param packageName name of the packages where the restrictions are set.
     * @param conditions list of conditions, or {@code null} to reset the conditions for the
     * package.
     */
    public final void setContentCaptureConditions(@NonNull String packageName,
            @Nullable Set<ContentCaptureCondition> conditions) {
        // TODO(b/129267994): implement
    }

    private <T> ArrayList<T> toList(@Nullable Set<T> set) {
        return set == null ? null : new ArrayList<T>(set);
    }
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.view.contentcapture;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.LocusId;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Defines a condition for when content capture should be allowed.
 *
 * <p>See {@link ContentCaptureManager#getContentCaptureConditions()} for more.
 */
public final class ContentCaptureCondition implements Parcelable {

    /**
     * When set, package should use the {@link LocusId#getId()} as a regular expression.
     */
    public static final int FLAG_IS_REGEX = 0x2;

    /** @hide */
    @IntDef(prefix = { "FLAG" }, flag = true, value = {
            FLAG_IS_REGEX
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Flags {}

    private final @NonNull LocusId mLocusId;
    private final @Flags int mFlags;

    /**
     * Default constructor.
     *
     * @param locusId id of the condition, as defined by
     * {@link ContentCaptureContext#getLocusId()}.
     * @param flags either {@link ContentCaptureCondition#FLAG_IS_REGEX} or {@code 0}.
     */
    public ContentCaptureCondition(@NonNull LocusId locusId, @Flags int flags) {
        this.mLocusId = Preconditions.checkNotNull(locusId);
        this.mFlags = flags;
        // TODO(b/129267994): check flags, add test case for null and invalid flags
    }

    /**
     * Gets the {@code LocusId} per se.
     */
    @NonNull
    public LocusId getLocusId() {
        return mLocusId;
    }

    /**
     * Gets the flags associates with this condition.
     *
     * @return either {@link ContentCaptureCondition#FLAG_IS_REGEX} or {@code 0}.
     */
    public @Flags int getFlags() {
        return mFlags;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int flags) {
        parcel.writeParcelable(mLocusId, flags);
        parcel.writeInt(mFlags);
    }

    public static final @NonNull Parcelable.Creator<ContentCaptureCondition> CREATOR =
            new Parcelable.Creator<ContentCaptureCondition>() {

                @Override
                public ContentCaptureCondition createFromParcel(@NonNull Parcel parcel) {
                    return new ContentCaptureCondition(parcel.readParcelable(null),
                            parcel.readInt());
                }

                @Override
                public ContentCaptureCondition[] newArray(int size) {
                    return new ContentCaptureCondition[size];
                }
    };
}
Loading