diff options
-rw-r--r-- | api/current.txt | 1 | ||||
-rwxr-xr-x | api/system-current.txt | 2 | ||||
-rw-r--r-- | api/test-current.txt | 2 | ||||
-rw-r--r-- | core/java/android/view/View.java | 35 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 4 | ||||
-rw-r--r-- | core/java/android/view/contentcapture/ChildContentCaptureSession.java | 6 | ||||
-rw-r--r-- | core/java/android/view/contentcapture/ContentCaptureEvent.java | 42 | ||||
-rw-r--r-- | core/java/android/view/contentcapture/ContentCaptureSession.java | 14 | ||||
-rw-r--r-- | core/java/android/view/contentcapture/MainContentCaptureSession.java | 13 | ||||
-rw-r--r-- | core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java | 6 |
10 files changed, 114 insertions, 11 deletions
diff --git a/api/current.txt b/api/current.txt index 7256461c41ca..1e61eefc97e5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -56741,6 +56741,7 @@ package android.view.contentcapture { method public final void notifySessionResumed(); method public final void notifyViewAppeared(@NonNull android.view.ViewStructure); method public final void notifyViewDisappeared(@NonNull android.view.autofill.AutofillId); + method public final void notifyViewInsetsChanged(@NonNull android.graphics.Insets); method public final void notifyViewTextChanged(@NonNull android.view.autofill.AutofillId, @Nullable CharSequence); method public final void notifyViewsDisappeared(@NonNull android.view.autofill.AutofillId, @NonNull long[]); method public final void setContentCaptureContext(@Nullable android.view.contentcapture.ContentCaptureContext); diff --git a/api/system-current.txt b/api/system-current.txt index 82a3ffa4b860..a044888c0901 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -13191,6 +13191,7 @@ package android.view.contentcapture { method public long getEventTime(); method @Nullable public android.view.autofill.AutofillId getId(); method @Nullable public java.util.List<android.view.autofill.AutofillId> getIds(); + method @Nullable public android.graphics.Insets getInsets(); method @Nullable public CharSequence getText(); method public int getType(); method @Nullable public android.view.contentcapture.ViewNode getViewNode(); @@ -13201,6 +13202,7 @@ package android.view.contentcapture { field public static final int TYPE_SESSION_RESUMED = 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_INSETS_CHANGED = 9; // 0x9 field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3 field public static final int TYPE_VIEW_TREE_APPEARED = 5; // 0x5 field public static final int TYPE_VIEW_TREE_APPEARING = 4; // 0x4 diff --git a/api/test-current.txt b/api/test-current.txt index 6353edc51a6f..1403b69afca3 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5085,6 +5085,7 @@ package android.view.contentcapture { method public long getEventTime(); method @Nullable public android.view.autofill.AutofillId getId(); method @Nullable public java.util.List<android.view.autofill.AutofillId> getIds(); + method @Nullable public android.graphics.Insets getInsets(); method @Nullable public CharSequence getText(); method public int getType(); method @Nullable public android.view.contentcapture.ViewNode getViewNode(); @@ -5095,6 +5096,7 @@ package android.view.contentcapture { field public static final int TYPE_SESSION_RESUMED = 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_INSETS_CHANGED = 9; // 0x9 field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3 field public static final int TYPE_VIEW_TREE_APPEARED = 5; // 0x5 field public static final int TYPE_VIEW_TREE_APPEARING = 4; // 0x4 diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index e665f065d952..708a09467247 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -29099,8 +29099,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTreeObserver = new ViewTreeObserver(context); } + @Nullable + ContentCaptureManager getContentCaptureManager(@NonNull Context context) { + if (mContentCaptureManager != null) { + return mContentCaptureManager; + } + mContentCaptureManager = context.getSystemService(ContentCaptureManager.class); + return mContentCaptureManager; + } + + void delayNotifyContentCaptureInsetsEvent(@NonNull Insets insets) { + if (mContentCaptureManager == null) { + return; + } + + ArrayList<Object> events = ensureEvents( + mContentCaptureManager.getMainContentCaptureSession()); + events.add(insets); + } + private void delayNotifyContentCaptureEvent(@NonNull ContentCaptureSession session, @NonNull View view, boolean appeared) { + ArrayList<Object> events = ensureEvents(session); + events.add(appeared ? view : view.getAutofillId()); + } + + @NonNull + private ArrayList<Object> ensureEvents(@NonNull ContentCaptureSession session) { if (mContentCaptureEvents == null) { // Most of the time there will be just one session, so intial capacity is 1 mContentCaptureEvents = new SparseArray<>(1); @@ -29112,16 +29137,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, events = new ArrayList<>(); mContentCaptureEvents.put(sessionId, events); } - events.add(appeared ? view : view.getAutofillId()); - } - @Nullable - ContentCaptureManager getContentCaptureManager(@NonNull Context context) { - if (mContentCaptureManager != null) { - return mContentCaptureManager; - } - mContentCaptureManager = context.getSystemService(ContentCaptureManager.class); - return mContentCaptureManager; + return events; } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 26ac4fc4ddc2..dd34bcb018b9 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -81,6 +81,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.FrameInfo; import android.graphics.HardwareRenderer.FrameDrawingCallback; +import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Point; @@ -2254,6 +2255,7 @@ public final class ViewRootImpl implements ViewParent, insets = insets.consumeDisplayCutout(); } host.dispatchApplyWindowInsets(insets); + mAttachInfo.delayNotifyContentCaptureInsetsEvent(insets.getInsets(Type.all())); Trace.traceEnd(Trace.TRACE_TAG_VIEW); } @@ -3118,6 +3120,8 @@ public final class ViewRootImpl implements ViewParent, ViewStructure structure = session.newViewStructure(view); view.onProvideContentCaptureStructure(structure, /* flags= */ 0); session.notifyViewAppeared(structure); + } else if (event instanceof Insets) { + mainSession.notifyViewInsetsChanged(sessionId, (Insets) event); } else { Log.w(mTag, "invalid content capture event: " + event); } diff --git a/core/java/android/view/contentcapture/ChildContentCaptureSession.java b/core/java/android/view/contentcapture/ChildContentCaptureSession.java index 7487ec4d921c..44b4353871a2 100644 --- a/core/java/android/view/contentcapture/ChildContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ChildContentCaptureSession.java @@ -17,6 +17,7 @@ package android.view.contentcapture; import android.annotation.NonNull; import android.annotation.Nullable; +import android.graphics.Insets; import android.view.autofill.AutofillId; import android.view.contentcapture.ViewNode.ViewStructureImpl; @@ -84,6 +85,11 @@ final class ChildContentCaptureSession extends ContentCaptureSession { } @Override + void internalNotifyViewInsetsChanged(@NonNull Insets viewInsets) { + getMainCaptureSession().notifyViewInsetsChanged(mId, viewInsets); + } + + @Override public void internalNotifyViewTreeEvent(boolean started) { getMainCaptureSession().notifyViewTreeEvent(mId, started); } diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java index c29d251e6535..ea34d948c91a 100644 --- a/core/java/android/view/contentcapture/ContentCaptureEvent.java +++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; +import android.graphics.Insets; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -112,6 +113,11 @@ public final class ContentCaptureEvent implements Parcelable { */ public static final int TYPE_SESSION_PAUSED = 8; + /** + * Called when the view's insets are changed. The new insets associated with the + * event may then be retrieved by calling {@link #getInsets()} + */ + public static final int TYPE_VIEW_INSETS_CHANGED = 9; /** @hide */ @IntDef(prefix = { "TYPE_" }, value = { @@ -122,7 +128,8 @@ public final class ContentCaptureEvent implements Parcelable { TYPE_VIEW_TREE_APPEARED, TYPE_CONTEXT_UPDATED, TYPE_SESSION_PAUSED, - TYPE_SESSION_RESUMED + TYPE_SESSION_RESUMED, + TYPE_VIEW_INSETS_CHANGED }) @Retention(RetentionPolicy.SOURCE) public @interface EventType{} @@ -136,6 +143,7 @@ public final class ContentCaptureEvent implements Parcelable { private @Nullable CharSequence mText; private int mParentSessionId = NO_SESSION_ID; private @Nullable ContentCaptureContext mClientContext; + private @Nullable Insets mInsets; /** @hide */ public ContentCaptureEvent(int sessionId, int type, long eventTime) { @@ -242,6 +250,13 @@ public final class ContentCaptureEvent implements Parcelable { return this; } + /** @hide */ + @NonNull + public ContentCaptureEvent setInsets(@NonNull Insets insets) { + mInsets = insets; + return this; + } + /** * Gets the type of the event. * @@ -305,6 +320,16 @@ public final class ContentCaptureEvent implements Parcelable { } /** + * Gets the rectangle of the insets associated with the event. Valid insets will only be + * returned if the type of the event is {@link #TYPE_VIEW_INSETS_CHANGED}, otherwise they + * will be null. + */ + @Nullable + public Insets getInsets() { + return mInsets; + } + + /** * Merges event of the same type, either {@link #TYPE_VIEW_TEXT_CHANGED} * or {@link #TYPE_VIEW_DISAPPEARED}. * @@ -369,7 +394,9 @@ public final class ContentCaptureEvent implements Parcelable { } if (mClientContext != null) { pw.print(", context="); mClientContext.dump(pw); pw.println(); - + } + if (mInsets != null) { + pw.print(", insets="); pw.println(mInsets); } } @@ -401,6 +428,9 @@ public final class ContentCaptureEvent implements Parcelable { if (mClientContext != null) { string.append(", context=").append(mClientContext); } + if (mInsets != null) { + string.append(", insets=").append(mInsets); + } return string.append(']').toString(); } @@ -424,6 +454,9 @@ public final class ContentCaptureEvent implements Parcelable { if (mType == TYPE_SESSION_STARTED || mType == TYPE_CONTEXT_UPDATED) { parcel.writeParcelable(mClientContext, flags); } + if (mType == TYPE_VIEW_INSETS_CHANGED) { + parcel.writeParcelable(mInsets, flags); + } } public static final @android.annotation.NonNull Parcelable.Creator<ContentCaptureEvent> CREATOR = @@ -455,6 +488,9 @@ public final class ContentCaptureEvent implements Parcelable { if (type == TYPE_SESSION_STARTED || type == TYPE_CONTEXT_UPDATED) { event.setClientContext(parcel.readParcelable(null)); } + if (type == TYPE_VIEW_INSETS_CHANGED) { + event.setInsets(parcel.readParcelable(null)); + } return event; } @@ -488,6 +524,8 @@ public final class ContentCaptureEvent implements Parcelable { return "VIEW_TREE_APPEARED"; case TYPE_CONTEXT_UPDATED: return "CONTEXT_UPDATED"; + case TYPE_VIEW_INSETS_CHANGED: + return "VIEW_INSETS_CHANGED"; default: return "UKNOWN_TYPE: " + type; } diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 2134dab7986b..012f5e6d3507 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -23,6 +23,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.graphics.Insets; import android.util.DebugUtils; import android.util.Log; import android.view.View; @@ -440,6 +441,19 @@ public abstract class ContentCaptureSession implements AutoCloseable { abstract void internalNotifyViewTextChanged(@NonNull AutofillId id, @Nullable CharSequence text); + /** + * Notifies the Intelligence Service that the insets of a view have changed. + */ + public final void notifyViewInsetsChanged(@NonNull Insets viewInsets) { + Preconditions.checkNotNull(viewInsets); + + if (!isContentCaptureEnabled()) return; + + internalNotifyViewInsetsChanged(viewInsets); + } + + abstract void internalNotifyViewInsetsChanged(@NonNull Insets viewInsets); + /** @hide */ public abstract void internalNotifyViewTreeEvent(boolean started); diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 96f224fef251..893d38dcfde7 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -22,6 +22,7 @@ import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_RESUM import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED; import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED; import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED; +import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_INSETS_CHANGED; import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED; import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TREE_APPEARED; import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TREE_APPEARING; @@ -36,6 +37,7 @@ import android.annotation.UiThread; import android.content.ComponentName; import android.content.Context; import android.content.pm.ParceledListSlice; +import android.graphics.Insets; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -578,6 +580,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } @Override + void internalNotifyViewInsetsChanged(@NonNull Insets viewInsets) { + notifyViewInsetsChanged(mId, viewInsets); + } + + @Override public void internalNotifyViewTreeEvent(boolean started) { notifyViewTreeEvent(mId, started); } @@ -642,6 +649,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } /** Public because is also used by ViewRootImpl */ + public void notifyViewInsetsChanged(int sessionId, @NonNull Insets viewInsets) { + sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_INSETS_CHANGED) + .setInsets(viewInsets)); + } + + /** Public because is also used by ViewRootImpl */ public void notifyViewTreeEvent(int sessionId, boolean started) { final int type = started ? TYPE_VIEW_TREE_APPEARING : TYPE_VIEW_TREE_APPEARED; sendEvent(new ContentCaptureEvent(sessionId, type), FORCE_FLUSH); diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java index 02a88fc8aecb..5ea071835de2 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.testng.Assert.assertThrows; +import android.graphics.Insets; import android.view.View; import android.view.ViewStructure; import android.view.autofill.AutofillId; @@ -172,6 +173,11 @@ public class ContentCaptureSessionTest { } @Override + void internalNotifyViewInsetsChanged(Insets viewInsets) { + throw new UnsupportedOperationException("should not have been called"); + } + + @Override public void updateContentCaptureContext(ContentCaptureContext context) { throw new UnsupportedOperationException("should not have been called"); } |