1 /*
2  * Copyright (C) 2015 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.internal.policy;
18 
19 import static android.view.WindowManager.DOCKED_BOTTOM;
20 import static android.view.WindowManager.DOCKED_INVALID;
21 import static android.view.WindowManager.DOCKED_LEFT;
22 import static android.view.WindowManager.DOCKED_RIGHT;
23 import static android.view.WindowManager.DOCKED_TOP;
24 
25 import android.content.res.Resources;
26 import android.graphics.Rect;
27 
28 /**
29  * Utility functions for docked stack divider used by both window manager and System UI.
30  *
31  * @hide
32  */
33 public class DockedDividerUtils {
34 
calculateBoundsForPosition(int position, int dockSide, Rect outRect, int displayWidth, int displayHeight, int dividerSize)35     public static void calculateBoundsForPosition(int position, int dockSide, Rect outRect,
36             int displayWidth, int displayHeight, int dividerSize) {
37         outRect.set(0, 0, displayWidth, displayHeight);
38         switch (dockSide) {
39             case DOCKED_LEFT:
40                 outRect.right = position;
41                 break;
42             case DOCKED_TOP:
43                 outRect.bottom = position;
44                 break;
45             case DOCKED_RIGHT:
46                 outRect.left = position + dividerSize;
47                 break;
48             case DOCKED_BOTTOM:
49                 outRect.top = position + dividerSize;
50                 break;
51         }
52         sanitizeStackBounds(outRect, dockSide == DOCKED_LEFT || dockSide == DOCKED_TOP);
53     }
54 
55     /**
56      * Makes sure that the bounds are always valid, i. e. they are at least one pixel high and wide.
57      *
58      * @param bounds The bounds to sanitize.
59      * @param topLeft Pass true if the bounds are at the top/left of the screen, false if they are
60      *                at the bottom/right. This is used to determine in which direction to extend
61      *                the bounds.
62      */
sanitizeStackBounds(Rect bounds, boolean topLeft)63     public static void sanitizeStackBounds(Rect bounds, boolean topLeft) {
64 
65         // If the bounds are either on the top or left of the screen, rather move it further to the
66         // left/top to make it more offscreen. If they are on the bottom or right, push them off the
67         // screen by moving it even more to the bottom/right.
68         if (topLeft) {
69             if (bounds.left >= bounds.right) {
70                 bounds.left = bounds.right - 1;
71             }
72             if (bounds.top >= bounds.bottom) {
73                 bounds.top = bounds.bottom - 1;
74             }
75         } else {
76             if (bounds.right <= bounds.left) {
77                 bounds.right = bounds.left + 1;
78             }
79             if (bounds.bottom <= bounds.top) {
80                 bounds.bottom = bounds.top + 1;
81             }
82         }
83     }
84 
calculatePositionForBounds(Rect bounds, int dockSide, int dividerSize)85     public static int calculatePositionForBounds(Rect bounds, int dockSide, int dividerSize) {
86         switch (dockSide) {
87             case DOCKED_LEFT:
88                 return bounds.right;
89             case DOCKED_TOP:
90                 return bounds.bottom;
91             case DOCKED_RIGHT:
92                 return bounds.left - dividerSize;
93             case DOCKED_BOTTOM:
94                 return bounds.top - dividerSize;
95             default:
96                 return 0;
97         }
98     }
99 
calculateMiddlePosition(boolean isHorizontalDivision, Rect insets, int displayWidth, int displayHeight, int dividerSize)100     public static int calculateMiddlePosition(boolean isHorizontalDivision, Rect insets,
101             int displayWidth, int displayHeight, int dividerSize) {
102         int start = isHorizontalDivision ? insets.top : insets.left;
103         int end = isHorizontalDivision
104                 ? displayHeight - insets.bottom
105                 : displayWidth - insets.right;
106         return start + (end - start) / 2 - dividerSize / 2;
107     }
108 
invertDockSide(int dockSide)109     public static int invertDockSide(int dockSide) {
110         switch (dockSide) {
111             case DOCKED_LEFT:
112                 return DOCKED_RIGHT;
113             case DOCKED_TOP:
114                 return DOCKED_BOTTOM;
115             case DOCKED_RIGHT:
116                 return DOCKED_LEFT;
117             case DOCKED_BOTTOM:
118                 return DOCKED_TOP;
119             default:
120                 return DOCKED_INVALID;
121         }
122     }
123 
124     /** Returns the inset distance from the divider window edge to the dividerview. */
getDividerInsets(Resources res)125     public static int getDividerInsets(Resources res) {
126         return res.getDimensionPixelSize(com.android.internal.R.dimen.docked_stack_divider_insets);
127     }
128 
129     /** Returns the size of the divider */
getDividerSize(Resources res, int dividerInsets)130     public static int getDividerSize(Resources res, int dividerInsets) {
131         final int windowWidth = res.getDimensionPixelSize(
132                 com.android.internal.R.dimen.docked_stack_divider_thickness);
133         return windowWidth - 2 * dividerInsets;
134     }
135 
136     /** Returns the docked-stack side */
getDockSide(int displayWidth, int displayHeight)137     public static int getDockSide(int displayWidth, int displayHeight) {
138         return displayWidth > displayHeight ? DOCKED_LEFT : DOCKED_TOP;
139     }
140 }
141