1 /*
2  * Copyright (C) 2018 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.server.wm.utils;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.graphics.Rect;
22 import android.view.Surface;
23 
24 
25 /**
26  * Utility methods to handle insets represented as rects.
27  */
28 public class InsetUtils {
29 
InsetUtils()30     private InsetUtils() {
31     }
32 
33     /**
34      * Transforms insets given in one rotation into insets in a different rotation.
35      *
36      * @param inOutInsets the insets to transform, is set to the transformed insets
37      * @param rotationDelta the delta between the new and old rotation.
38      *                      Must be one of Surface.ROTATION_0/90/180/270.
39      */
rotateInsets(Rect inOutInsets, int rotationDelta)40     public static void rotateInsets(Rect inOutInsets, int rotationDelta) {
41         final Rect r = inOutInsets;
42         switch (rotationDelta) {
43             case Surface.ROTATION_0:
44                 return;
45             case Surface.ROTATION_90:
46                 r.set(r.top, r.right, r.bottom, r.left);
47                 break;
48             case Surface.ROTATION_180:
49                 r.set(r.right, r.bottom, r.left, r.top);
50                 break;
51             case Surface.ROTATION_270:
52                 r.set(r.bottom, r.left, r.top, r.right);
53                 break;
54             default:
55                 throw new IllegalArgumentException("Unknown rotation: " + rotationDelta);
56         }
57     }
58 
59     /**
60      * Adds {@code insetsToAdd} to {@code inOutInsets}.
61      */
addInsets(Rect inOutInsets, Rect insetsToAdd)62     public static void addInsets(Rect inOutInsets, Rect insetsToAdd) {
63         inOutInsets.left += insetsToAdd.left;
64         inOutInsets.top += insetsToAdd.top;
65         inOutInsets.right += insetsToAdd.right;
66         inOutInsets.bottom += insetsToAdd.bottom;
67     }
68 
69     /**
70      * Calculates the insets from the {@code outerFrame} to the {@code innerFrame}.
71      *
72      * Note that if a side of the outer frame is not actually on the outside, the inset for that
73      * side will be clamped to zero.
74      *
75      * @param outerFrame the reference frame from which the insets are calculated
76      * @param innerFrame the inset frame, to which the insets are calculated,
77      *                   or null to clear the insets.
78      * @param outInsets is set to the result of the inset calculation.
79      */
insetsBetweenFrames(@onNull Rect outerFrame, @Nullable Rect innerFrame, @NonNull Rect outInsets)80     public static void insetsBetweenFrames(@NonNull Rect outerFrame, @Nullable Rect innerFrame,
81             @NonNull Rect outInsets) {
82         if (innerFrame == null) {
83             outInsets.setEmpty();
84             return;
85         }
86         final int w = outerFrame.width();
87         final int h = outerFrame.height();
88         outInsets.set(
89                 Math.min(w, Math.max(0, innerFrame.left - outerFrame.left)),
90                 Math.min(h, Math.max(0, innerFrame.top - outerFrame.top)),
91                 Math.min(w, Math.max(0, outerFrame.right - innerFrame.right)),
92                 Math.min(h, Math.max(0, outerFrame.bottom - innerFrame.bottom)));
93     }
94 }
95