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

Commit 6079d151 authored by Adam He's avatar Adam He Committed by Felipe Leme
Browse files

Implement setContentCaptureEnabled for manually enabling content capture

Change-Id: Id660aebac0b35a33b39a7c74da0f11c0958549ee
Fixes: 121047183
Test: atest CtsContentCaptureServiceTestCases
Test: atest android.contentcapture.cts.ChildlessActivityTest#testDisabledByApp
parent 53ee650b
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -1048,9 +1048,8 @@ public class Activity extends ContextThemeWrapper

    private void notifyContentCaptureManagerIfNeeded(@ContentCaptureNotificationType int type) {
        final ContentCaptureManager cm = getContentCaptureManager();
        if (cm == null) {
            return;
        }
        if (cm == null) return;

        switch (type) {
            case CONTENT_CAPTURE_START:
                //TODO(b/111276913): decide whether the InteractionSessionId should be
+5 −0
Original line number Diff line number Diff line
@@ -329,6 +329,11 @@ public abstract class ContentCaptureService extends Service {
                    mClientInterface.asBinder());
            return;
        }
        if ((flags & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0) {
            setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_BY_APP,
                    mClientInterface.asBinder());
            return;
        }

        setClientState(clientReceiver, ContentCaptureSession.STATE_ACTIVE,
                mClientInterface.asBinder());
+44 −25
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.Preconditions;
import com.android.internal.util.SyncResultReceiver;
@@ -62,8 +63,10 @@ public final class ContentCaptureManager {
    static final boolean VERBOSE = false;
    static final boolean DEBUG = true; // STOPSHIP if not set to false

    @NonNull
    private final AtomicBoolean mDisabled = new AtomicBoolean();
    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private boolean mDisabled;

    @NonNull
    private final Context mContext;
@@ -71,11 +74,16 @@ public final class ContentCaptureManager {
    @Nullable
    private final IContentCaptureManager mService;

    // Flags used for starting session.
    @GuardedBy("mLock")
    private int mFlags;

    // TODO(b/119220549): use UI Thread directly (as calls are one-way) or a shared thread / handler
    // held at the Application level
    @NonNull
    private final Handler mHandler;

    @GuardedBy("mLock")
    private MainContentCaptureSession mMainSession;

    /** @hide */
@@ -114,20 +122,25 @@ public final class ContentCaptureManager {
    @NonNull
    @UiThread
    public MainContentCaptureSession getMainContentCaptureSession() {
        synchronized (mLock) {
            if (mMainSession == null) {
                mMainSession = new MainContentCaptureSession(mContext, mHandler, mService,
                    mDisabled);
                        new AtomicBoolean(mDisabled));
                if (VERBOSE) {
                    Log.v(TAG, "getDefaultContentCaptureSession(): created " + mMainSession);
                }
            }
            return mMainSession;
        }
    }

    /** @hide */
    public void onActivityStarted(@NonNull IBinder applicationToken,
            @NonNull ComponentName activityComponent, int flags) {
        getMainContentCaptureSession().start(applicationToken, activityComponent, flags);
        synchronized (mLock) {
            mFlags |= flags;
            getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags);
        }
    }

    /** @hide */
@@ -173,7 +186,9 @@ public final class ContentCaptureManager {
     * Checks whether content capture is enabled for this activity.
     */
    public boolean isContentCaptureEnabled() {
        return mService != null && !mDisabled.get();
        synchronized (mLock) {
            return mService != null && !mDisabled;
        }
    }

    /**
@@ -183,7 +198,9 @@ public final class ContentCaptureManager {
     * it on {@link android.app.Activity#onCreate(android.os.Bundle, android.os.PersistableBundle)}.
     */
    public void setContentCaptureEnabled(boolean enabled) {
        //TODO(b/111276913): implement (need to finish / disable all sessions)
        synchronized (mLock) {
            mFlags |= enabled ? 0 : ContentCaptureContext.FLAG_DISABLED_BY_APP;
        }
    }

    /**
@@ -198,14 +215,15 @@ public final class ContentCaptureManager {

    /** @hide */
    public void dump(String prefix, PrintWriter pw) {
        synchronized (mLock) {
            pw.print(prefix); pw.println("ContentCaptureManager");

        pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled.get());
            pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
            pw.print(prefix); pw.print("Context: "); pw.println(mContext);
            pw.print(prefix); pw.print("User: "); pw.println(mContext.getUserId());
            if (mService != null) {
                pw.print(prefix); pw.print("Service: "); pw.println(mService);
            }
            pw.print(prefix); pw.print("Flags: "); pw.println(mFlags);
            if (mMainSession != null) {
                final String prefix2 = prefix + "  ";
                pw.print(prefix); pw.println("Main session:");
@@ -214,6 +232,7 @@ public final class ContentCaptureManager {
                pw.print(prefix); pw.println("No sessions");
            }
        }
    }


    /** Retrieves the component name of the target content capture service through system_server. */
+9 −0
Original line number Diff line number Diff line
@@ -93,6 +93,13 @@ public abstract class ContentCaptureSession implements AutoCloseable {
     */
    public static final int STATE_DISABLED_BY_FLAG_SECURE = 5;

    /**
     * Session is disabled manually by the specific app.
     *
     * @hide
     */
    public static final int STATE_DISABLED_BY_APP = 6;

    private static final int INITIAL_CHILDREN_CAPACITY = 5;

    private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -395,6 +402,8 @@ public abstract class ContentCaptureSession implements AutoCloseable {
                return "DISABLED_DUPLICATED_ID";
            case STATE_DISABLED_BY_FLAG_SECURE:
                return "DISABLED_FLAG_SECURE";
            case STATE_DISABLED_BY_APP:
                return "DISABLED_BY_APP";
            default:
                return "INVALID:" + state;
        }
+2 −1
Original line number Diff line number Diff line
@@ -250,7 +250,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
        // TODO(b/111276913): change the resultCode to use flags so there's just one flag for
        // disabled stuff
        if (resultCode == STATE_DISABLED_NO_SERVICE || resultCode == STATE_DISABLED_DUPLICATED_ID
                || resultCode == STATE_DISABLED_BY_FLAG_SECURE) {
                || resultCode == STATE_DISABLED_BY_FLAG_SECURE
                || resultCode == STATE_DISABLED_BY_APP) {
            mDisabled.set(true);
            handleResetSession(/* resetState= */ false);
        } else {