• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.launcher3.touch;
18 
19 import android.content.res.Resources;
20 import android.graphics.Canvas;
21 import android.graphics.Matrix;
22 import android.graphics.PointF;
23 import android.graphics.Rect;
24 import android.graphics.RectF;
25 import android.graphics.drawable.ShapeDrawable;
26 import android.util.FloatProperty;
27 import android.util.Pair;
28 import android.view.MotionEvent;
29 import android.view.VelocityTracker;
30 import android.view.View;
31 import android.view.accessibility.AccessibilityEvent;
32 import android.widget.FrameLayout;
33 import android.widget.LinearLayout;
34 
35 import com.android.launcher3.DeviceProfile;
36 import com.android.launcher3.util.SplitConfigurationOptions;
37 import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
38 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
39 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
40 
41 import java.util.List;
42 
43 /**
44  * Abstraction layer to separate horizontal and vertical specific implementations
45  * for {@link com.android.launcher3.PagedView}. Majority of these implementations are (should be) as
46  * simple as choosing the correct X and Y analogous methods.
47  */
48 public interface PagedOrientationHandler {
49 
50     PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
51     PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
52     PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
53 
54     interface Int2DAction<T> {
call(T target, int x, int y)55         void call(T target, int x, int y);
56     }
57     interface Float2DAction<T> {
call(T target, float x, float y)58         void call(T target, float x, float y);
59     }
60     Int2DAction<View> VIEW_SCROLL_BY = View::scrollBy;
61     Int2DAction<View> VIEW_SCROLL_TO = View::scrollTo;
62     Float2DAction<Canvas> CANVAS_TRANSLATE = Canvas::translate;
63     Float2DAction<Matrix> MATRIX_POST_TRANSLATE = Matrix::postTranslate;
64 
setPrimary(T target, Int2DAction<T> action, int param)65     <T> void setPrimary(T target, Int2DAction<T> action, int param);
setPrimary(T target, Float2DAction<T> action, float param)66     <T> void setPrimary(T target, Float2DAction<T> action, float param);
setSecondary(T target, Float2DAction<T> action, float param)67     <T> void setSecondary(T target, Float2DAction<T> action, float param);
set(T target, Int2DAction<T> action, int primaryParam, int secondaryParam)68     <T> void set(T target, Int2DAction<T> action, int primaryParam, int secondaryParam);
getPrimaryDirection(MotionEvent event, int pointerIndex)69     float getPrimaryDirection(MotionEvent event, int pointerIndex);
getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId)70     float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId);
getMeasuredSize(View view)71     int getMeasuredSize(View view);
getPrimarySize(View view)72     int getPrimarySize(View view);
getPrimarySize(RectF rect)73     float getPrimarySize(RectF rect);
getStart(RectF rect)74     float getStart(RectF rect);
getEnd(RectF rect)75     float getEnd(RectF rect);
getClearAllSidePadding(View view, boolean isRtl)76     int getClearAllSidePadding(View view, boolean isRtl);
getSecondaryDimension(View view)77     int getSecondaryDimension(View view);
getPrimaryViewTranslate()78     FloatProperty<View> getPrimaryViewTranslate();
getSecondaryViewTranslate()79     FloatProperty<View> getSecondaryViewTranslate();
80 
getPrimaryScroll(View view)81     int getPrimaryScroll(View view);
getPrimaryScale(View view)82     float getPrimaryScale(View view);
getChildStart(View view)83     int getChildStart(View view);
getCenterForPage(View view, Rect insets)84     int getCenterForPage(View view, Rect insets);
getScrollOffsetStart(View view, Rect insets)85     int getScrollOffsetStart(View view, Rect insets);
getScrollOffsetEnd(View view, Rect insets)86     int getScrollOffsetEnd(View view, Rect insets);
getSecondaryTranslationDirectionFactor()87     int getSecondaryTranslationDirectionFactor();
getSplitTranslationDirectionFactor(@tagePosition int stagePosition, DeviceProfile deviceProfile)88     int getSplitTranslationDirectionFactor(@StagePosition int stagePosition,
89             DeviceProfile deviceProfile);
getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild)90     ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild);
setMaxScroll(AccessibilityEvent event, int maxScroll)91     void setMaxScroll(AccessibilityEvent event, int maxScroll);
getRecentsRtlSetting(Resources resources)92     boolean getRecentsRtlSetting(Resources resources);
getDegreesRotated()93     float getDegreesRotated();
getRotation()94     int getRotation();
setPrimaryScale(View view, float scale)95     void setPrimaryScale(View view, float scale);
setSecondaryScale(View view, float scale)96     void setSecondaryScale(View view, float scale);
97 
getPrimaryValue(T x, T y)98     <T> T getPrimaryValue(T x, T y);
getSecondaryValue(T x, T y)99     <T> T getSecondaryValue(T x, T y);
100 
getPrimaryValue(int x, int y)101     int getPrimaryValue(int x, int y);
getSecondaryValue(int x, int y)102     int getSecondaryValue(int x, int y);
103 
getPrimaryValue(float x, float y)104     float getPrimaryValue(float x, float y);
getSecondaryValue(float x, float y)105     float getSecondaryValue(float x, float y);
106 
isLayoutNaturalToLauncher()107     boolean isLayoutNaturalToLauncher();
getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary, DeviceProfile deviceProfile)108     Pair<FloatProperty, FloatProperty> getSplitSelectTaskOffset(FloatProperty primary,
109             FloatProperty secondary, DeviceProfile deviceProfile);
getDistanceToBottomOfRect(DeviceProfile dp, Rect rect)110     int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect);
getSplitPositionOptions(DeviceProfile dp)111     List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp);
112     /**
113      * @param placeholderHeight height of placeholder view in portrait, width in landscape
114      */
getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset, DeviceProfile dp, @StagePosition int stagePosition, Rect out)115     void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
116             DeviceProfile dp, @StagePosition int stagePosition, Rect out);
117 
118     /**
119      * Centers an icon in the split staging area, accounting for insets.
120      * @param out The icon that needs to be centered.
121      * @param onScreenRectCenterX The x-center of the on-screen staging area (most of the Rect is
122      *                        offscreen).
123      * @param onScreenRectCenterY The y-center of the on-screen staging area (most of the Rect is
124      *                        offscreen).
125      * @param fullscreenScaleX A x-scaling factor used to convert coordinates back into pixels.
126      * @param fullscreenScaleY A y-scaling factor used to convert coordinates back into pixels.
127      * @param drawableWidth The icon's drawable (final) width.
128      * @param drawableHeight The icon's drawable (final) height.
129      * @param dp The device profile, used to report rotation and hardware insets.
130      * @param stagePosition 0 if the staging area is pinned to top/left, 1 for bottom/right.
131      */
updateSplitIconParams(View out, float onScreenRectCenterX, float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY, int drawableWidth, int drawableHeight, DeviceProfile dp, @StagePosition int stagePosition)132     void updateSplitIconParams(View out, float onScreenRectCenterX,
133             float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY,
134             int drawableWidth, int drawableHeight, DeviceProfile dp,
135             @StagePosition int stagePosition);
136 
137     /**
138      * Sets positioning and rotation for a SplitInstructionsView.
139      * @param out The SplitInstructionsView that needs to be positioned.
140      * @param dp The device profile, used to report rotation and device type.
141      * @param splitInstructionsHeight The SplitInstructionView's height.
142      * @param splitInstructionsWidth  The SplitInstructionView's width.
143      */
setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight, int splitInstructionsWidth)144     void setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight,
145             int splitInstructionsWidth);
146 
147     /**
148      * @param splitDividerSize height of split screen drag handle in portrait, width in landscape
149      * @param stagePosition the split position option (top/left, bottom/right) of the first
150      *                           task selected for entering split
151      * @param out1 the bounds for where the first selected app will be
152      * @param out2 the bounds for where the second selected app will be, complimentary to
153      *             {@param out1} based on {@param initialSplitOption}
154      */
getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp, @StagePosition int stagePosition, Rect out1, Rect out2)155     void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
156             @StagePosition int stagePosition, Rect out1, Rect out2);
157 
getDefaultSplitPosition(DeviceProfile deviceProfile)158     int getDefaultSplitPosition(DeviceProfile deviceProfile);
159 
160     /**
161      * @param outRect This is expected to be the rect that has the dimensions for a non-split,
162      *                fullscreen task in overview. This will directly be modified.
163      * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize
164      *                           outRect for
165      */
setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect, SplitBounds splitInfo, @SplitConfigurationOptions.StagePosition int desiredStagePosition)166     void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect, SplitBounds splitInfo,
167             @SplitConfigurationOptions.StagePosition int desiredStagePosition);
168 
measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, int parentWidth, int parentHeight, SplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl)169     void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
170             int parentWidth, int parentHeight,
171             SplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl);
172 
173     // Overview TaskMenuView methods
setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl)174     void setTaskIconParams(FrameLayout.LayoutParams iconParams,
175             int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
setSplitIconParams(View primaryIconView, View secondaryIconView, int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight, int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl, DeviceProfile deviceProfile, SplitBounds splitConfig)176     void setSplitIconParams(View primaryIconView, View secondaryIconView,
177             int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
178             int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
179             DeviceProfile deviceProfile, SplitBounds splitConfig);
180 
181     /*
182      * The following two methods try to center the TaskMenuView in landscape by finding the center
183      * of the thumbnail view and then subtracting half of the taskMenu width. In this case, the
184      * taskMenu width is the same size as the thumbnail width (what got set below in
185      * getTaskMenuWidth()), so we directly use that in the calculations.
186      */
getTaskMenuX(float x, View thumbnailView, DeviceProfile deviceProfile, float taskInsetMargin)187     float getTaskMenuX(float x, View thumbnailView, DeviceProfile deviceProfile,
188             float taskInsetMargin);
getTaskMenuY(float y, View thumbnailView, int stagePosition, View taskMenuView, float taskInsetMargin)189     float getTaskMenuY(float y, View thumbnailView, int stagePosition,
190             View taskMenuView, float taskInsetMargin);
getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile, @StagePosition int stagePosition)191     int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile,
192             @StagePosition int stagePosition);
193     /**
194      * Sets linear layout orientation for {@link com.android.launcher3.popup.SystemShortcut} items
195      * inside task menu view.
196      */
setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile, LinearLayout taskMenuLayout, int dividerSpacing, ShapeDrawable dividerDrawable)197     void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile,
198             LinearLayout taskMenuLayout, int dividerSpacing,
199             ShapeDrawable dividerDrawable);
200     /**
201      * Sets layout param attributes for {@link com.android.launcher3.popup.SystemShortcut} child
202      * views inside task menu view.
203      */
setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp, LinearLayout viewGroup, DeviceProfile deviceProfile)204     void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
205             LinearLayout viewGroup, DeviceProfile deviceProfile);
206 
207     /**
208      * Calculates the position where a Digital Wellbeing Banner should be placed on its parent
209      * TaskView.
210      * @return A Pair of Floats representing the proper x and y translations.
211      */
getDwbLayoutTranslations(int taskViewWidth, int taskViewHeight, SplitBounds splitBounds, DeviceProfile deviceProfile, View[] thumbnailViews, int desiredTaskId, View banner)212     Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
213             int taskViewHeight, SplitBounds splitBounds, DeviceProfile deviceProfile,
214             View[] thumbnailViews, int desiredTaskId, View banner);
215 
216     // The following are only used by TaskViewTouchHandler.
217     /** @return Either VERTICAL or HORIZONTAL. */
getUpDownSwipeDirection()218     SingleAxisSwipeDetector.Direction getUpDownSwipeDirection();
219     /** @return Given {@link #getUpDownSwipeDirection()}, whether POSITIVE or NEGATIVE is up. */
getUpDirection(boolean isRtl)220     int getUpDirection(boolean isRtl);
221     /** @return Whether the displacement is going towards the top of the screen. */
isGoingUp(float displacement, boolean isRtl)222     boolean isGoingUp(float displacement, boolean isRtl);
223     /** @return Either 1 or -1, a factor to multiply by so the animation goes the correct way. */
getTaskDragDisplacementFactor(boolean isRtl)224     int getTaskDragDisplacementFactor(boolean isRtl);
225 
226     /**
227      * Maps the velocity from the coordinate plane of the foreground app to that
228      * of Launcher's (which now will always be portrait)
229      */
adjustFloatingIconStartVelocity(PointF velocity)230     void adjustFloatingIconStartVelocity(PointF velocity);
231 
232     /**
233      * Ensures that outStartRect left bound is within the DeviceProfile's visual boundaries
234      * @param outStartRect The start rect that will directly be modified
235      */
fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile)236     void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile);
237 
238     /**
239      * Determine the target translation for animating the FloatingTaskView out. This value could
240      * either be an x-coordinate or a y-coordinate, depending on which way the FloatingTaskView was
241      * docked.
242      *
243      * @param floatingTask The FloatingTaskView.
244      * @param onScreenRect The current on-screen dimensions of the FloatingTaskView.
245      * @param stagePosition STAGE_POSITION_TOP_OR_LEFT or STAGE_POSITION_BOTTOM_OR_RIGHT.
246      * @param dp The device profile.
247      * @return A float. When an animation translates the FloatingTaskView to this position, it will
248      * appear to tuck away off the edge of the screen.
249      */
getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect, @StagePosition int stagePosition, DeviceProfile dp)250     float getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect,
251             @StagePosition int stagePosition, DeviceProfile dp);
252 
253     /**
254      * Sets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be
255      * either x or y), depending on how the view is oriented.
256      *
257      * @param floatingTask The FloatingTaskView to be translated.
258      * @param translation The target translation value.
259      * @param dp The current device profile.
260      */
setFloatingTaskPrimaryTranslation(View floatingTask, float translation, DeviceProfile dp)261     void setFloatingTaskPrimaryTranslation(View floatingTask, float translation, DeviceProfile dp);
262 
263     /**
264      * Gets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be
265      * either x or y), depending on how the view is oriented.
266      *
267      * @param floatingTask The FloatingTaskView in question.
268      * @param dp The current device profile.
269      * @return The current translation value.
270      */
getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp)271     Float getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp);
272 
273     class ChildBounds {
274 
275         public final int primaryDimension;
276         public final int secondaryDimension;
277         public final int childPrimaryEnd;
278         public final int childSecondaryEnd;
279 
ChildBounds(int primaryDimension, int secondaryDimension, int childPrimaryEnd, int childSecondaryEnd)280         ChildBounds(int primaryDimension, int secondaryDimension, int childPrimaryEnd,
281             int childSecondaryEnd) {
282             this.primaryDimension = primaryDimension;
283             this.secondaryDimension = secondaryDimension;
284             this.childPrimaryEnd = childPrimaryEnd;
285             this.childSecondaryEnd = childSecondaryEnd;
286         }
287     }
288 }
289