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

Commit 56208f49 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Another round of changes on Content Capture."

parents 34737365 aa5088ed
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -49567,6 +49567,7 @@ package android.view {
    method public android.graphics.Rect getClipBounds();
    method public boolean getClipBounds(android.graphics.Rect);
    method public final boolean getClipToOutline();
    method public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession();
    method public java.lang.CharSequence getContentDescription();
    method public final android.content.Context getContext();
    method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
@@ -49903,6 +49904,7 @@ package android.view {
    method public void setClickable(boolean);
    method public void setClipBounds(android.graphics.Rect);
    method public void setClipToOutline(boolean);
    method public void setContentCaptureSession(android.view.contentcapture.ContentCaptureSession);
    method public void setContentDescription(java.lang.CharSequence);
    method public void setContextClickable(boolean);
    method public void setDefaultFocusHighlightEnabled(boolean);
@@ -52163,17 +52165,56 @@ package android.view.autofill {
package android.view.contentcapture {
  public final class ContentCaptureContext implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureContext> CREATOR;
  }
  public static final class ContentCaptureContext.Builder {
    ctor public ContentCaptureContext.Builder();
    method public android.view.contentcapture.ContentCaptureContext build();
    method public android.view.contentcapture.ContentCaptureContext.Builder setExtras(android.os.Bundle);
    method public android.view.contentcapture.ContentCaptureContext.Builder setUri(android.net.Uri);
  }
  public final class ContentCaptureManager {
    method public android.view.contentcapture.ContentCaptureSession createContentCaptureSession(android.view.contentcapture.ContentCaptureContext);
    method public android.content.ComponentName getServiceComponentName();
    method public boolean isContentCaptureEnabled();
    method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int);
    method public void removeUserData(android.view.contentcapture.UserDataRemovalRequest);
    method public void setContentCaptureEnabled(boolean);
  }
  public final class ContentCaptureSession implements java.lang.AutoCloseable {
    method public void close();
    method public void destroy();
    method public android.view.contentcapture.ContentCaptureSessionId getContentCaptureSessionId();
    method public void notifyViewAppeared(android.view.ViewStructure);
    method public void notifyViewDisappeared(android.view.autofill.AutofillId);
    method public void notifyViewTextChanged(android.view.autofill.AutofillId, java.lang.CharSequence, int);
    method public void setContentCaptureEnabled(boolean);
    field public static final int FLAG_USER_INPUT = 1; // 0x1
  }
  public final class ContentCaptureSessionId implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureSessionId> CREATOR;
  }
  public final class UserDataRemovalRequest implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.contentcapture.UserDataRemovalRequest> CREATOR;
  }
  public static final class UserDataRemovalRequest.Builder {
    ctor public UserDataRemovalRequest.Builder();
    method public android.view.contentcapture.UserDataRemovalRequest.Builder addUri(android.net.Uri, boolean);
    method public android.view.contentcapture.UserDataRemovalRequest build();
    method public android.view.contentcapture.UserDataRemovalRequest.Builder forEverything();
  }
}
package android.view.inputmethod {
+29 −29
Original line number Diff line number Diff line
@@ -5006,34 +5006,16 @@ package android.service.contentcapture {
    ctor public ContentCaptureService();
    method public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
    method public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
    method public void onActivitySnapshot(android.service.contentcapture.InteractionSessionId, android.service.contentcapture.SnapshotData);
    method public abstract void onContentCaptureEventsRequest(android.service.contentcapture.InteractionSessionId, android.service.contentcapture.ContentCaptureEventsRequest);
    method public void onCreateInteractionSession(android.service.contentcapture.InteractionContext, android.service.contentcapture.InteractionSessionId);
    method public void onDestroyInteractionSession(android.service.contentcapture.InteractionSessionId);
    method public void onActivitySnapshot(android.view.contentcapture.ContentCaptureSessionId, android.service.contentcapture.SnapshotData);
    method public abstract void onContentCaptureEventsRequest(android.view.contentcapture.ContentCaptureSessionId, android.service.contentcapture.ContentCaptureEventsRequest);
    method public void onCreateContentCaptureSession(android.view.contentcapture.ContentCaptureContext, android.view.contentcapture.ContentCaptureSessionId);
    method public void onDestroyContentCaptureSession(android.view.contentcapture.ContentCaptureSessionId);
    method public final void setActivityContentCaptureEnabled(android.content.ComponentName, boolean);
    method public final void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>);
    method public final void setPackageContentCaptureEnabled(java.lang.String, boolean);
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
  }

  public final class InteractionContext implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.ComponentName getActivityComponent();
    method public int getDisplayId();
    method public int getFlags();
    method public int getTaskId();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.service.contentcapture.InteractionContext> CREATOR;
    field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
    field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
  }

  public final class InteractionSessionId implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.service.contentcapture.InteractionSessionId> CREATOR;
  }

  public final class SnapshotData implements android.os.Parcelable {
    method public int describeContents();
    method public android.app.assist.AssistContent getAssistContent();
@@ -7301,6 +7283,17 @@ package android.view.accessibility {

package android.view.contentcapture {

  public final class ContentCaptureContext implements android.os.Parcelable {
    method public android.content.ComponentName getActivityComponent();
    method public int getDisplayId();
    method public android.os.Bundle getExtras();
    method public int getFlags();
    method public int getTaskId();
    method public android.net.Uri getUri();
    field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
    field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
  }

  public final class ContentCaptureEvent implements android.os.Parcelable {
    method public int describeContents();
    method public long getEventTime();
@@ -7311,13 +7304,20 @@ package android.view.contentcapture {
    method public android.view.contentcapture.ViewNode getViewNode();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureEvent> CREATOR;
    field public static final deprecated int TYPE_ACTIVITY_PAUSED = 3; // 0x3
    field public static final deprecated int TYPE_ACTIVITY_RESUMED = 2; // 0x2
    field public static final deprecated int TYPE_ACTIVITY_STARTED = 1; // 0x1
    field public static final deprecated int TYPE_ACTIVITY_STOPPED = 4; // 0x4
    field public static final int TYPE_VIEW_APPEARED = 5; // 0x5
    field public static final int TYPE_VIEW_DISAPPEARED = 6; // 0x6
    field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7
    field public static final int TYPE_VIEW_APPEARED = 1; // 0x1
    field public static final int TYPE_VIEW_DISAPPEARED = 2; // 0x2
    field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3
  }

  public final class UserDataRemovalRequest implements android.os.Parcelable {
    method public java.lang.String getPackageName();
    method public java.util.List<android.view.contentcapture.UserDataRemovalRequest.UriRequest> getUriRequests();
    method public boolean isForEverything();
  }

  public final class UserDataRemovalRequest.UriRequest {
    method public android.net.Uri getUri();
    method public boolean isRecursive();
  }

  public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
+28 −22
Original line number Diff line number Diff line
@@ -121,7 +121,6 @@ import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillManager.AutofillClient;
import android.view.autofill.AutofillPopupWindow;
import android.view.autofill.IAutofillWindowPresenter;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureManager;
import android.widget.AdapterView;
import android.widget.Toast;
@@ -1027,28 +1026,39 @@ public class Activity extends ContextThemeWrapper
        return mContentCaptureManager;
    }

    private void notifyContentCaptureManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
    /** @hide */ private static final int CONTENT_CAPTURE_START = 1;
    /** @hide */ private static final int CONTENT_CAPTURE_FLUSH = 2;
    /** @hide */ private static final int CONTENT_CAPTURE_STOP = 3;

    /** @hide */
    @IntDef(prefix = { "CONTENT_CAPTURE_" }, value = {
            CONTENT_CAPTURE_START,
            CONTENT_CAPTURE_FLUSH,
            CONTENT_CAPTURE_STOP
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface ContentCaptureNotificationType{}


    private void notifyContentCaptureManagerIfNeeded(@ContentCaptureNotificationType int type) {
        final ContentCaptureManager cm = getContentCaptureManager();
        if (cm == null || !cm.isContentCaptureEnabled()) {
            return;
        }
        switch (event) {
            case ContentCaptureEvent.TYPE_ACTIVITY_CREATED:
        switch (type) {
            case CONTENT_CAPTURE_START:
                //TODO(b/111276913): decide whether the InteractionSessionId should be
                // saved / restored in the activity bundle.
                cm.onActivityCreated(mToken, getComponentName());
                // saved / restored in the activity bundle - probably not
                cm.onActivityStarted(mToken, getComponentName());
                break;
            case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED:
                cm.onActivityDestroyed();
            case CONTENT_CAPTURE_FLUSH:
                cm.flush();
                break;
            case ContentCaptureEvent.TYPE_ACTIVITY_STARTED:
            case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED:
            case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED:
            case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED:
                cm.onActivityLifecycleEvent(event);
            case CONTENT_CAPTURE_STOP:
                cm.onActivityStopped();
                break;
            default:
                Log.w(TAG, "notifyContentCaptureManagerIfNeeded(): invalid type " + event);
                Log.wtf(TAG, "Invalid @ContentCaptureNotificationType: " + type);
        }
    }

@@ -1417,7 +1427,6 @@ public class Activity extends ContextThemeWrapper
        mRestoredFromBundle = savedInstanceState != null;
        mCalled = true;

        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
    }

    /**
@@ -1651,7 +1660,7 @@ public class Activity extends ContextThemeWrapper
        if (mAutoFillResetNeeded) {
            getAutofillManager().onVisibleForAutofill();
        }
        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_START);
    }

    /**
@@ -1734,8 +1743,8 @@ public class Activity extends ContextThemeWrapper
                }
            }
        }
        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
        mCalled = true;
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_FLUSH);
    }

    /**
@@ -2128,8 +2137,8 @@ public class Activity extends ContextThemeWrapper
                mAutoFillIgnoreFirstResumePause = false;
            }
        }
        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
        mCalled = true;
        notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_FLUSH);
    }

    /**
@@ -2317,7 +2326,7 @@ public class Activity extends ContextThemeWrapper
                getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
                        mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
            }
            notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
            notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP);
        }
    }

@@ -2388,9 +2397,6 @@ public class Activity extends ContextThemeWrapper
        }

        dispatchActivityDestroyed();

        notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);

    }

    /**
+11 −0
Original line number Diff line number Diff line
@@ -191,6 +191,17 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co
        pw.print(className);
    }

    /**
     * Helper to get {@link #flattenToShortString()} in a {@link ComponentName} reference that can
     * be {@code null}.
     *
     * @hide
     */
    @Nullable
    public static String flattenToShortString(@Nullable ComponentName componentName) {
        return componentName == null ? null : componentName.flattenToShortString();
    }

    /**
     * Return a String that unambiguously describes both the package and
     * class names contained in the ComponentName.  You can later recover
+22 −20
Original line number Diff line number Diff line
@@ -29,7 +29,9 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureSessionId;

import java.util.List;
import java.util.Set;
@@ -45,7 +47,7 @@ public abstract class ContentCaptureService extends Service {

    private static final String TAG = ContentCaptureService.class.getSimpleName();

    // TODO(b/111330312): STOPSHIP use dynamic value, or change to false
    // TODO(b/121044306): STOPSHIP use dynamic value, or change to false
    static final boolean DEBUG = true;
    static final boolean VERBOSE = false;

@@ -64,15 +66,15 @@ public abstract class ContentCaptureService extends Service {
    private final IContentCaptureService mInterface = new IContentCaptureService.Stub() {

        @Override
        public void onSessionLifecycle(InteractionContext context, String sessionId)
        public void onSessionLifecycle(ContentCaptureContext context, String sessionId)
                throws RemoteException {
            if (context != null) {
                mHandler.sendMessage(
                        obtainMessage(ContentCaptureService::handleOnCreateInteractionSession,
                        obtainMessage(ContentCaptureService::handleOnCreateSession,
                                ContentCaptureService.this, context, sessionId));
            } else {
                mHandler.sendMessage(
                        obtainMessage(ContentCaptureService::handleOnDestroyInteractionSession,
                        obtainMessage(ContentCaptureService::handleOnDestroySession,
                                ContentCaptureService.this, sessionId));
            }
        }
@@ -175,15 +177,15 @@ public abstract class ContentCaptureService extends Service {
    }

    /**
     * Creates a new interaction session.
     * Creates a new content capture session.
     *
     * @param context interaction context
     * @param context content capture context
     * @param sessionId the session's Id
     */
    public void onCreateInteractionSession(@NonNull InteractionContext context,
            @NonNull InteractionSessionId sessionId) {
    public void onCreateContentCaptureSession(@NonNull ContentCaptureContext context,
            @NonNull ContentCaptureSessionId sessionId) {
        if (VERBOSE) {
            Log.v(TAG, "onCreateInteractionSession(id=" + sessionId + ", ctx=" + context + ")");
            Log.v(TAG, "onCreateContentCaptureSession(id=" + sessionId + ", ctx=" + context + ")");
        }
    }

@@ -194,7 +196,7 @@ public abstract class ContentCaptureService extends Service {
     * @param sessionId the session's Id
     * @param request the events
     */
    public abstract void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId,
    public abstract void onContentCaptureEventsRequest(@NonNull ContentCaptureSessionId sessionId,
            @NonNull ContentCaptureEventsRequest request);

    /**
@@ -203,39 +205,39 @@ public abstract class ContentCaptureService extends Service {
     * @param sessionId the session's Id
     * @param snapshotData the data
     */
    public void onActivitySnapshot(@NonNull InteractionSessionId sessionId,
    public void onActivitySnapshot(@NonNull ContentCaptureSessionId sessionId,
            @NonNull SnapshotData snapshotData) {}

    /**
     * Destroys the interaction session.
     * Destroys the content capture session.
     *
     * @param sessionId the id of the session to destroy
     */
    public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {
    public void onDestroyContentCaptureSession(@NonNull ContentCaptureSessionId sessionId) {
        if (VERBOSE) {
            Log.v(TAG, "onDestroyInteractionSession(id=" + sessionId + ")");
            Log.v(TAG, "onDestroyContentCaptureSession(id=" + sessionId + ")");
        }
    }

    //TODO(b/111276913): consider caching the InteractionSessionId for the lifetime of the session,
    // so we don't need to create a temporary InteractionSessionId for each event.

    private void handleOnCreateInteractionSession(@NonNull InteractionContext context,
    private void handleOnCreateSession(@NonNull ContentCaptureContext context,
            @NonNull String sessionId) {
        onCreateInteractionSession(context, new InteractionSessionId(sessionId));
        onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId));
    }

    private void handleOnContentCaptureEventsRequest(@NonNull String sessionId,
            @NonNull ContentCaptureEventsRequest request) {
        onContentCaptureEventsRequest(new InteractionSessionId(sessionId), request);
        onContentCaptureEventsRequest(new ContentCaptureSessionId(sessionId), request);
    }

    private void handleOnActivitySnapshot(@NonNull String sessionId,
            @NonNull SnapshotData snapshotData) {
        onActivitySnapshot(new InteractionSessionId(sessionId), snapshotData);
        onActivitySnapshot(new ContentCaptureSessionId(sessionId), snapshotData);
    }

    private void handleOnDestroyInteractionSession(@NonNull String sessionId) {
        onDestroyInteractionSession(new InteractionSessionId(sessionId));
    private void handleOnDestroySession(@NonNull String sessionId) {
        onDestroyContentCaptureSession(new ContentCaptureSessionId(sessionId));
    }
}
Loading