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 package com.android.launcher3.util;
17 
18 import android.graphics.Insets;
19 import android.graphics.Point;
20 import android.graphics.Rect;
21 import android.view.WindowInsets.Type;
22 import android.view.WindowMetrics;
23 
24 import androidx.annotation.Nullable;
25 
26 import java.util.Objects;
27 
28 /**
29  * Utility class to hold information about window position and layout
30  */
31 public class WindowBounds {
32 
33     public final Rect bounds;
34     public final Rect insets;
35     public final Point availableSize;
36     public final int rotationHint;
37 
WindowBounds(Rect bounds, Rect insets)38     public WindowBounds(Rect bounds, Rect insets) {
39         this(bounds, insets, -1);
40     }
41 
WindowBounds(Rect bounds, Rect insets, int rotationHint)42     public WindowBounds(Rect bounds, Rect insets, int rotationHint) {
43         this.bounds = bounds;
44         this.insets = insets;
45         this.rotationHint = rotationHint;
46         availableSize = new Point(bounds.width() - insets.left - insets.right,
47                 bounds.height() - insets.top - insets.bottom);
48     }
49 
WindowBounds(int width, int height, int availableWidth, int availableHeight, int rotationHint)50     public WindowBounds(int width, int height, int availableWidth, int availableHeight,
51             int rotationHint) {
52         this.bounds = new Rect(0, 0, width, height);
53         this.availableSize = new Point(availableWidth, availableHeight);
54         // We don't care about insets in this case
55         this.insets = new Rect(0, 0, width - availableWidth, height - availableHeight);
56         this.rotationHint = rotationHint;
57     }
58 
59     @Override
hashCode()60     public int hashCode() {
61         return Objects.hash(bounds, insets);
62     }
63 
64     @Override
equals(@ullable Object obj)65     public boolean equals(@Nullable Object obj) {
66         if (!(obj instanceof WindowBounds)) {
67             return false;
68         }
69         WindowBounds other = (WindowBounds) obj;
70         return other.bounds.equals(bounds) && other.insets.equals(insets)
71                 && other.rotationHint == rotationHint;
72     }
73 
74     @Override
toString()75     public String toString() {
76         return "WindowBounds{"
77                 + "bounds=" + bounds
78                 + ", insets=" + insets
79                 + ", availableSize=" + availableSize
80                 + ", rotationHint=" + rotationHint
81                 + '}';
82     }
83 
84     /**
85      * Returns true if the device is in landscape orientation
86      */
isLandscape()87     public final boolean isLandscape() {
88         return bounds.width() > bounds.height();
89     }
90 
91     /**
92      * Returns the bounds corresponding to the provided WindowMetrics
93      */
94     @SuppressWarnings("NewApi")
fromWindowMetrics(WindowMetrics wm)95     public static WindowBounds fromWindowMetrics(WindowMetrics wm) {
96         Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
97         return new WindowBounds(wm.getBounds(),
98                 new Rect(insets.left, insets.top, insets.right, insets.bottom));
99     }
100 }
101