1 /*
2  * Copyright 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 androidx.core.view;
18 
19 import static android.os.Build.VERSION.SDK_INT;
20 
21 import android.graphics.Rect;
22 import android.view.DisplayCutout;
23 
24 import java.util.List;
25 
26 
27 /**
28  * Represents the area of the display that is not functional for displaying content.
29  *
30  * <p>{@code DisplayCutoutCompat} instances are immutable.
31  */
32 public final class DisplayCutoutCompat {
33 
34     private final Object mDisplayCutout;
35 
36     /**
37      * Creates a DisplayCutout instance.
38      *
39      * @param safeInsets the insets from each edge which avoid the display cutout as returned by
40      *                   {@link #getSafeInsetTop()} etc.
41      * @param boundingRects the bounding rects of the display cutouts as returned by
42      *               {@link #getBoundingRects()} ()}.
43      */
44     // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
DisplayCutoutCompat(Rect safeInsets, List<Rect> boundingRects)45     public DisplayCutoutCompat(Rect safeInsets, List<Rect> boundingRects) {
46         this(SDK_INT >= 28 ? new DisplayCutout(safeInsets, boundingRects) : null);
47     }
48 
DisplayCutoutCompat(Object displayCutout)49     private DisplayCutoutCompat(Object displayCutout) {
50         mDisplayCutout = displayCutout;
51     }
52 
53     /** Returns the inset from the top which avoids the display cutout in pixels. */
getSafeInsetTop()54     public int getSafeInsetTop() {
55         if (SDK_INT >= 28) {
56             return ((DisplayCutout) mDisplayCutout).getSafeInsetTop();
57         } else {
58             return 0;
59         }
60     }
61 
62     /** Returns the inset from the bottom which avoids the display cutout in pixels. */
getSafeInsetBottom()63     public int getSafeInsetBottom() {
64         if (SDK_INT >= 28) {
65             return ((DisplayCutout) mDisplayCutout).getSafeInsetBottom();
66         } else {
67             return 0;
68         }
69     }
70 
71     /** Returns the inset from the left which avoids the display cutout in pixels. */
getSafeInsetLeft()72     public int getSafeInsetLeft() {
73         if (SDK_INT >= 28) {
74             return ((DisplayCutout) mDisplayCutout).getSafeInsetLeft();
75         } else {
76             return 0;
77         }
78     }
79 
80     /** Returns the inset from the right which avoids the display cutout in pixels. */
getSafeInsetRight()81     public int getSafeInsetRight() {
82         if (SDK_INT >= 28) {
83             return ((DisplayCutout) mDisplayCutout).getSafeInsetRight();
84         } else {
85             return 0;
86         }
87     }
88 
89     /**
90      * Returns a list of {@code Rect}s, each of which is the bounding rectangle for a non-functional
91      * area on the display.
92      *
93      * There will be at most one non-functional area per short edge of the device, and none on
94      * the long edges.
95      *
96      * @return a list of bounding {@code Rect}s, one for each display cutout area.
97      */
getBoundingRects()98     public List<Rect> getBoundingRects() {
99         if (SDK_INT >= 28) {
100             return ((DisplayCutout) mDisplayCutout).getBoundingRects();
101         } else {
102             return null;
103         }
104     }
105 
106     @Override
equals(Object o)107     public boolean equals(Object o) {
108         if (this == o) {
109             return true;
110         }
111         if (o == null || getClass() != o.getClass()) {
112             return false;
113         }
114         DisplayCutoutCompat other = (DisplayCutoutCompat) o;
115         return mDisplayCutout == null ? other.mDisplayCutout == null
116                 : mDisplayCutout.equals(other.mDisplayCutout);
117     }
118 
119     @Override
hashCode()120     public int hashCode() {
121         return mDisplayCutout == null ? 0 : mDisplayCutout.hashCode();
122     }
123 
124     @Override
toString()125     public String toString() {
126         return "DisplayCutoutCompat{" + mDisplayCutout + "}";
127     }
128 
wrap(Object displayCutout)129     static DisplayCutoutCompat wrap(Object displayCutout) {
130         return displayCutout == null ? null : new DisplayCutoutCompat(displayCutout);
131     }
132 }
133