1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view; 18 19 import static java.util.Objects.requireNonNull; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.UiThread; 24 import android.graphics.Point; 25 import android.graphics.Rect; 26 import android.os.CancellationSignal; 27 28 import java.io.PrintWriter; 29 import java.util.function.Consumer; 30 31 /** 32 * A target collects the set of contextual information for a ScrollCaptureHandler discovered during 33 * a {@link View#dispatchScrollCaptureSearch scroll capture search}. 34 */ 35 public final class ScrollCaptureTarget { 36 private final View mContainingView; 37 private final ScrollCaptureCallback mCallback; 38 private final Rect mLocalVisibleRect; 39 private final Point mPositionInWindow; 40 private final int mHint; 41 private Rect mScrollBounds; 42 43 private final int[] mTmpIntArr = new int[2]; 44 ScrollCaptureTarget(@onNull View scrollTarget, @NonNull Rect localVisibleRect, @NonNull Point positionInWindow, @NonNull ScrollCaptureCallback callback)45 public ScrollCaptureTarget(@NonNull View scrollTarget, @NonNull Rect localVisibleRect, 46 @NonNull Point positionInWindow, @NonNull ScrollCaptureCallback callback) { 47 mContainingView = requireNonNull(scrollTarget); 48 mHint = mContainingView.getScrollCaptureHint(); 49 mCallback = requireNonNull(callback); 50 mLocalVisibleRect = requireNonNull(localVisibleRect); 51 mPositionInWindow = requireNonNull(positionInWindow); 52 } 53 54 /** 55 * @return the hint that the {@code containing view} had during the scroll capture search 56 * @see View#getScrollCaptureHint() 57 */ 58 @View.ScrollCaptureHint getHint()59 public int getHint() { 60 return mHint; 61 } 62 63 /** @return the {@link ScrollCaptureCallback} for this target */ 64 @NonNull getCallback()65 public ScrollCaptureCallback getCallback() { 66 return mCallback; 67 } 68 69 /** @return the {@code containing view} for this {@link ScrollCaptureCallback callback} */ 70 @NonNull getContainingView()71 public View getContainingView() { 72 return mContainingView; 73 } 74 75 /** 76 * Returns the visible bounds of the containing view. 77 * 78 * @return the visible bounds of the {@code containing view} in view-local coordinates 79 */ 80 @NonNull getLocalVisibleRect()81 public Rect getLocalVisibleRect() { 82 return mLocalVisibleRect; 83 } 84 85 /** @return the position of the visible bounds of the containing view within the window */ 86 @NonNull getPositionInWindow()87 public Point getPositionInWindow() { 88 return mPositionInWindow; 89 } 90 91 /** 92 * @return the {@code scroll bounds} for this {@link ScrollCaptureCallback callback} 93 * 94 * @see ScrollCaptureCallback#onScrollCaptureSearch(CancellationSignal, Consumer) 95 */ 96 @Nullable getScrollBounds()97 public Rect getScrollBounds() { 98 return mScrollBounds; 99 } 100 101 /** 102 * Sets the scroll bounds rect to the intersection of provided rect and the current bounds of 103 * the {@code containing view}. 104 */ setScrollBounds(@ullable Rect scrollBounds)105 public void setScrollBounds(@Nullable Rect scrollBounds) { 106 mScrollBounds = Rect.copyOrNull(scrollBounds); 107 if (mScrollBounds == null) { 108 return; 109 } 110 if (!mScrollBounds.intersect(0, 0, 111 mContainingView.getWidth(), mContainingView.getHeight())) { 112 mScrollBounds.setEmpty(); 113 } 114 } 115 116 /** 117 * Refresh the local visible bounds and its offset within the window, based on the current 118 * state of the {@code containing view}. 119 */ 120 @UiThread updatePositionInWindow()121 public void updatePositionInWindow() { 122 mContainingView.getLocationInWindow(mTmpIntArr); 123 mPositionInWindow.x = mTmpIntArr[0]; 124 mPositionInWindow.y = mTmpIntArr[1]; 125 } 126 toString()127 public String toString() { 128 return "ScrollCaptureTarget{" + "view=" + mContainingView 129 + ", callback=" + mCallback 130 + ", scrollBounds=" + mScrollBounds 131 + ", localVisibleRect=" + mLocalVisibleRect 132 + ", positionInWindow=" + mPositionInWindow 133 + "}"; 134 } 135 dump(@onNull PrintWriter writer)136 void dump(@NonNull PrintWriter writer) { 137 View view = getContainingView(); 138 writer.println("view: " + view); 139 writer.println("hint: " + mHint); 140 writer.println("callback: " + mCallback); 141 writer.println("scrollBounds: " 142 + (mScrollBounds == null ? "null" : mScrollBounds.toShortString())); 143 Point inWindow = getPositionInWindow(); 144 writer.println("positionInWindow: " 145 + ((inWindow == null) ? "null" : "[" + inWindow.x + "," + inWindow.y + "]")); 146 Rect localVisible = getLocalVisibleRect(); 147 writer.println("localVisibleRect: " 148 + (localVisible == null ? "null" : localVisible.toShortString())); 149 } 150 } 151