1ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos/*
2ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * Copyright 2018 The Android Open Source Project
3ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos *
4ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * Licensed under the Apache License, Version 2.0 (the "License");
5ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * you may not use this file except in compliance with the License.
6ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * You may obtain a copy of the License at
7ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos *
8ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos *      http://www.apache.org/licenses/LICENSE-2.0
9ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos *
10ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * Unless required by applicable law or agreed to in writing, software
11ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * distributed under the License is distributed on an "AS IS" BASIS,
12ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * See the License for the specific language governing permissions and
14ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos * limitations under the License.
15ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos */
16ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos
17f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roospackage androidx.core.view;
18f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
19ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roosimport static android.os.Build.VERSION.SDK_INT;
20ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roos
21ec07ea6397ba55c89214e4cc21d9ae951908088cAdrian Roosimport android.graphics.Rect;
22f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roosimport android.view.DisplayCutout;
23f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
24f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roosimport java.util.List;
25f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
26f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
27f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos/**
28f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos * Represents the area of the display that is not functional for displaying content.
29f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos *
30f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos * <p>{@code DisplayCutoutCompat} instances are immutable.
31f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos */
32f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roospublic final class DisplayCutoutCompat {
33f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
34f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    private final Object mDisplayCutout;
35f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
36f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    /**
37f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * Creates a DisplayCutout instance.
38f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     *
39f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * @param safeInsets the insets from each edge which avoid the display cutout as returned by
40f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     *                   {@link #getSafeInsetTop()} etc.
41f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * @param boundingRects the bounding rects of the display cutouts as returned by
42f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     *               {@link #getBoundingRects()} ()}.
43f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     */
44f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
45f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public DisplayCutoutCompat(Rect safeInsets, List<Rect> boundingRects) {
46f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        this(SDK_INT >= 28 ? new DisplayCutout(safeInsets, boundingRects) : null);
47f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
48f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
49f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    private DisplayCutoutCompat(Object displayCutout) {
50f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        mDisplayCutout = displayCutout;
51f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
52f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
53f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    /** Returns the inset from the top which avoids the display cutout in pixels. */
54f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public int getSafeInsetTop() {
55f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (SDK_INT >= 28) {
56f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return ((DisplayCutout) mDisplayCutout).getSafeInsetTop();
57f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        } else {
58f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return 0;
59f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
60f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
61f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
62f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    /** Returns the inset from the bottom which avoids the display cutout in pixels. */
63f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public int getSafeInsetBottom() {
64f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (SDK_INT >= 28) {
65f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return ((DisplayCutout) mDisplayCutout).getSafeInsetBottom();
66f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        } else {
67f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return 0;
68f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
69f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
70f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
71f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    /** Returns the inset from the left which avoids the display cutout in pixels. */
72f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public int getSafeInsetLeft() {
73f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (SDK_INT >= 28) {
74f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return ((DisplayCutout) mDisplayCutout).getSafeInsetLeft();
75f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        } else {
76f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return 0;
77f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
78f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
79f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
80f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    /** Returns the inset from the right which avoids the display cutout in pixels. */
81f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public int getSafeInsetRight() {
82f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (SDK_INT >= 28) {
83f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return ((DisplayCutout) mDisplayCutout).getSafeInsetRight();
84f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        } else {
85f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return 0;
86f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
87f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
88f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
89f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    /**
90f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * Returns a list of {@code Rect}s, each of which is the bounding rectangle for a non-functional
91f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * area on the display.
92f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     *
93f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * There will be at most one non-functional area per short edge of the device, and none on
94f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * the long edges.
95f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     *
96f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     * @return a list of bounding {@code Rect}s, one for each display cutout area.
97f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos     */
98f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public List<Rect> getBoundingRects() {
99f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (SDK_INT >= 28) {
100f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return ((DisplayCutout) mDisplayCutout).getBoundingRects();
101f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        } else {
102f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return null;
103f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
104f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
105f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
106f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    @Override
107f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public boolean equals(Object o) {
108f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (this == o) {
109f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return true;
110f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
111f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        if (o == null || getClass() != o.getClass()) {
112f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos            return false;
113f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        }
114f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        DisplayCutoutCompat other = (DisplayCutoutCompat) o;
115f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        return mDisplayCutout == null ? other.mDisplayCutout == null
116f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos                : mDisplayCutout.equals(other.mDisplayCutout);
117f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
118f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
119f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    @Override
120f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public int hashCode() {
121f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        return mDisplayCutout == null ? 0 : mDisplayCutout.hashCode();
122f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
123f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
124f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    @Override
125f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    public String toString() {
126f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        return "DisplayCutoutCompat{" + mDisplayCutout + "}";
127f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
128f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos
129f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    static DisplayCutoutCompat wrap(Object displayCutout) {
130f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos        return displayCutout == null ? null : new DisplayCutoutCompat(displayCutout);
131f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos    }
132f06f10caad2193d5c032c6c4c224a74358e8fbfdAdrian Roos}
133