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