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 android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.UiThread; 22 import android.graphics.Matrix; 23 import android.graphics.Point; 24 import android.graphics.Rect; 25 26 import com.android.internal.util.FastMath; 27 28 /** 29 * A target collects the set of contextual information for a ScrollCaptureHandler discovered during 30 * a {@link View#dispatchScrollCaptureSearch scroll capture search}. 31 * 32 * @hide 33 */ 34 public final class ScrollCaptureTarget { 35 private final View mContainingView; 36 private final ScrollCaptureCallback mCallback; 37 private final Rect mLocalVisibleRect; 38 private final Point mPositionInWindow; 39 private final int mHint; 40 private Rect mScrollBounds; 41 42 private final float[] mTmpFloatArr = new float[2]; 43 private final Matrix mMatrixViewLocalToWindow = new Matrix(); 44 private final Rect mTmpRect = new Rect(); 45 ScrollCaptureTarget(@onNull View scrollTarget, @NonNull Rect localVisibleRect, @NonNull Point positionInWindow, @NonNull ScrollCaptureCallback callback)46 public ScrollCaptureTarget(@NonNull View scrollTarget, @NonNull Rect localVisibleRect, 47 @NonNull Point positionInWindow, @NonNull ScrollCaptureCallback callback) { 48 mContainingView = scrollTarget; 49 mHint = mContainingView.getScrollCaptureHint(); 50 mCallback = callback; 51 mLocalVisibleRect = localVisibleRect; 52 mPositionInWindow = positionInWindow; 53 } 54 55 /** @return the hint that the {@code containing view} had during the scroll capture search */ 56 @View.ScrollCaptureHint getHint()57 public int getHint() { 58 return mHint; 59 } 60 61 /** @return the {@link ScrollCaptureCallback} for this target */ 62 @NonNull getCallback()63 public ScrollCaptureCallback getCallback() { 64 return mCallback; 65 } 66 67 /** @return the {@code containing view} for this {@link ScrollCaptureCallback callback} */ 68 @NonNull getContainingView()69 public View getContainingView() { 70 return mContainingView; 71 } 72 73 /** 74 * Returns the un-clipped, visible bounds of the containing view during the scroll capture 75 * search. This is used to determine on-screen area to assist in selecting the primary target. 76 * 77 * @return the visible bounds of the {@code containing view} in view-local coordinates 78 */ 79 @NonNull getLocalVisibleRect()80 public Rect getLocalVisibleRect() { 81 return mLocalVisibleRect; 82 } 83 84 /** @return the position of the {@code containing view} within the window */ 85 @NonNull getPositionInWindow()86 public Point getPositionInWindow() { 87 return mPositionInWindow; 88 } 89 90 /** @return the {@code scroll bounds} for this {@link ScrollCaptureCallback callback} */ 91 @Nullable getScrollBounds()92 public Rect getScrollBounds() { 93 return mScrollBounds; 94 } 95 96 /** 97 * Sets the scroll bounds rect to the intersection of provided rect and the current bounds of 98 * the {@code containing view}. 99 */ setScrollBounds(@ullable Rect scrollBounds)100 public void setScrollBounds(@Nullable Rect scrollBounds) { 101 mScrollBounds = Rect.copyOrNull(scrollBounds); 102 if (mScrollBounds == null) { 103 return; 104 } 105 if (!mScrollBounds.intersect(0, 0, 106 mContainingView.getWidth(), mContainingView.getHeight())) { 107 mScrollBounds.setEmpty(); 108 } 109 } 110 zero(float[] pointArray)111 private static void zero(float[] pointArray) { 112 pointArray[0] = 0; 113 pointArray[1] = 0; 114 } 115 roundIntoPoint(Point pointObj, float[] pointArray)116 private static void roundIntoPoint(Point pointObj, float[] pointArray) { 117 pointObj.x = FastMath.round(pointArray[0]); 118 pointObj.y = FastMath.round(pointArray[1]); 119 } 120 121 /** 122 * Refresh the value of {@link #mLocalVisibleRect} and {@link #mPositionInWindow} based on the 123 * current state of the {@code containing view}. 124 */ 125 @UiThread updatePositionInWindow()126 public void updatePositionInWindow() { 127 mMatrixViewLocalToWindow.reset(); 128 mContainingView.transformMatrixToGlobal(mMatrixViewLocalToWindow); 129 130 zero(mTmpFloatArr); 131 mMatrixViewLocalToWindow.mapPoints(mTmpFloatArr); 132 roundIntoPoint(mPositionInWindow, mTmpFloatArr); 133 } 134 135 } 136