blob: e3fed3a5dce3bff208655a38145db3fe45f2d3c2 [file] [log] [blame]
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001/*
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
17package android.view;
18
Jorim Jaggi90990792019-01-21 23:00:20 +010019import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
Tarandeep Singh92d2dd32019-08-07 14:45:01 -070020import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
Adrian Roos11dfd272019-03-25 19:21:26 +010021import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
22import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
Jorim Jaggi90990792019-01-21 23:00:20 +010023import static android.view.WindowInsets.Type.SIZE;
Adrian Roos11dfd272019-03-25 19:21:26 +010024import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
Jorim Jaggibcf99ff2018-12-03 18:04:26 +010025import static android.view.WindowInsets.Type.indexOf;
26
Jorim Jaggif96c90a2018-09-26 16:55:15 +020027import android.annotation.IntDef;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +010028import android.annotation.Nullable;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020029import android.graphics.Insets;
30import android.graphics.Rect;
31import android.os.Parcel;
32import android.os.Parcelable;
33import android.util.ArrayMap;
Jorim Jaggib6030952018-10-23 18:31:52 +020034import android.util.ArraySet;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +010035import android.util.SparseIntArray;
Jorim Jaggib6030952018-10-23 18:31:52 +020036import android.view.WindowInsets.Type;
Tiger Huang332793b2019-10-29 23:21:27 +080037import android.view.WindowInsets.Type.InsetsType;
Jorim Jaggi648e5882019-01-24 13:24:02 +010038import android.view.WindowManager.LayoutParams;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020039
40import java.io.PrintWriter;
41import java.lang.annotation.Retention;
42import java.lang.annotation.RetentionPolicy;
Tarandeep Singha6f35612019-01-11 19:50:46 -080043import java.util.Objects;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020044
45/**
46 * Holder for state of system windows that cause window insets for all other windows in the system.
47 * @hide
48 */
49public class InsetsState implements Parcelable {
50
51 /**
52 * Internal representation of inset source types. This is different from the public API in
53 * {@link WindowInsets.Type} as one type from the public API might indicate multiple windows
54 * at the same time.
55 */
56 @Retention(RetentionPolicy.SOURCE)
Tiger Huang332793b2019-10-29 23:21:27 +080057 @IntDef(prefix = "ITYPE", value = {
58 ITYPE_STATUS_BAR,
59 ITYPE_NAVIGATION_BAR,
60 ITYPE_CAPTION_BAR,
61 ITYPE_TOP_GESTURES,
62 ITYPE_BOTTOM_GESTURES,
63 ITYPE_LEFT_GESTURES,
64 ITYPE_RIGHT_GESTURES,
65 ITYPE_TOP_TAPPABLE_ELEMENT,
66 ITYPE_BOTTOM_TAPPABLE_ELEMENT,
67 ITYPE_IME
Jorim Jaggif96c90a2018-09-26 16:55:15 +020068 })
Tiger Huang332793b2019-10-29 23:21:27 +080069 public @interface InternalInsetsType {}
Jorim Jaggif96c90a2018-09-26 16:55:15 +020070
71 static final int FIRST_TYPE = 0;
72
Tiger Huang332793b2019-10-29 23:21:27 +080073 public static final int ITYPE_STATUS_BAR = FIRST_TYPE;
74 public static final int ITYPE_NAVIGATION_BAR = 1;
75 public static final int ITYPE_CAPTION_BAR = 2;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020076
Tiger Huang332793b2019-10-29 23:21:27 +080077 public static final int ITYPE_TOP_GESTURES = 3;
78 public static final int ITYPE_BOTTOM_GESTURES = 4;
79 public static final int ITYPE_LEFT_GESTURES = 5;
80 public static final int ITYPE_RIGHT_GESTURES = 6;
81 public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 7;
82 public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 8;
Adrian Roos11dfd272019-03-25 19:21:26 +010083
Jorim Jaggif96c90a2018-09-26 16:55:15 +020084 /** Input method window. */
Tiger Huang332793b2019-10-29 23:21:27 +080085 public static final int ITYPE_IME = 9;
Adrian Roos11dfd272019-03-25 19:21:26 +010086
Tiger Huang332793b2019-10-29 23:21:27 +080087 static final int LAST_TYPE = ITYPE_IME;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020088
89 // Derived types
90
Jorim Jaggif96c90a2018-09-26 16:55:15 +020091 /** A shelf is the same as the navigation bar. */
Tiger Huang332793b2019-10-29 23:21:27 +080092 public static final int ITYPE_SHELF = ITYPE_NAVIGATION_BAR;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020093
Jorim Jaggi5bb571d2018-11-06 14:42:04 +010094 @Retention(RetentionPolicy.SOURCE)
Tiger Huang332793b2019-10-29 23:21:27 +080095 @IntDef(prefix = "IINSETS_SIDE", value = {
96 ISIDE_LEFT,
97 ISIDE_TOP,
98 ISIDE_RIGHT,
99 ISIDE_BOTTOM,
100 ISIDE_FLOATING,
101 ISIDE_UNKNOWN
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100102 })
Tiger Huang332793b2019-10-29 23:21:27 +0800103 public @interface InternalInsetsSide {}
104 static final int ISIDE_LEFT = 0;
105 static final int ISIDE_TOP = 1;
106 static final int ISIDE_RIGHT = 2;
107 static final int ISIDE_BOTTOM = 3;
108 static final int ISIDE_FLOATING = 4;
109 static final int ISIDE_UNKNOWN = 5;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100110
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200111 private final ArrayMap<Integer, InsetsSource> mSources = new ArrayMap<>();
112
Tarandeep Singha6f35612019-01-11 19:50:46 -0800113 /**
114 * The frame of the display these sources are relative to.
115 */
116 private final Rect mDisplayFrame = new Rect();
117
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200118 public InsetsState() {
119 }
120
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100121 public InsetsState(InsetsState copy) {
122 set(copy);
123 }
124
Jorim Jaggi02a741f2018-12-12 17:40:19 -0800125 public InsetsState(InsetsState copy, boolean copySources) {
126 set(copy, copySources);
127 }
128
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200129 /**
130 * Calculates {@link WindowInsets} based on the current source configuration.
131 *
132 * @param frame The frame to calculate the insets relative to.
133 * @return The calculated insets.
134 */
135 public WindowInsets calculateInsets(Rect frame, boolean isScreenRound,
Brad Stenninge0573692019-03-11 13:52:46 -0700136 boolean alwaysConsumeSystemBars, DisplayCutout cutout,
Jorim Jaggi73f3e8a2019-01-14 13:06:23 +0100137 @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets,
Tiger Huang332793b2019-10-29 23:21:27 +0800138 int legacySoftInputMode, @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100139 Insets[] typeInsetsMap = new Insets[Type.SIZE];
140 Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
Jorim Jaggi90990792019-01-21 23:00:20 +0100141 boolean[] typeVisibilityMap = new boolean[SIZE];
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200142 final Rect relativeFrame = new Rect(frame);
143 final Rect relativeFrameMax = new Rect(frame);
Jorim Jaggi90990792019-01-21 23:00:20 +0100144 if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
Jorim Jaggi73f3e8a2019-01-14 13:06:23 +0100145 && legacyContentInsets != null && legacyStableInsets != null) {
146 WindowInsets.assignCompatInsets(typeInsetsMap, legacyContentInsets);
147 WindowInsets.assignCompatInsets(typeMaxInsetsMap, legacyStableInsets);
148 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200149 for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
150 InsetsSource source = mSources.get(type);
151 if (source == null) {
152 continue;
153 }
Jorim Jaggi648e5882019-01-24 13:24:02 +0100154
Tarandeep Singh92d2dd32019-08-07 14:45:01 -0700155 boolean skipNonImeInImeMode = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_IME
Tiger Huang332793b2019-10-29 23:21:27 +0800156 && source.getType() != ITYPE_IME;
Jorim Jaggi648e5882019-01-24 13:24:02 +0100157 boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
Tiger Huang332793b2019-10-29 23:21:27 +0800158 && (type == ITYPE_STATUS_BAR || type == ITYPE_NAVIGATION_BAR);
159 boolean skipIme = source.getType() == ITYPE_IME
Jorim Jaggi648e5882019-01-24 13:24:02 +0100160 && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
Adrian Roos11dfd272019-03-25 19:21:26 +0100161 boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
162 && (toPublicType(type) & Type.compatSystemInsets()) != 0;
Tarandeep Singh92d2dd32019-08-07 14:45:01 -0700163 if (skipSystemBars || skipIme || skipLegacyTypes || skipNonImeInImeMode) {
Jorim Jaggi90990792019-01-21 23:00:20 +0100164 typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible();
165 continue;
166 }
167
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100168 processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
Jorim Jaggi90990792019-01-21 23:00:20 +0100169 typeSideMap, typeVisibilityMap);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200170
171 // IME won't be reported in max insets as the size depends on the EditorInfo of the IME
172 // target.
Tiger Huang332793b2019-10-29 23:21:27 +0800173 if (source.getType() != ITYPE_IME) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100174 processSource(source, relativeFrameMax, true /* ignoreVisibility */,
Jorim Jaggi90990792019-01-21 23:00:20 +0100175 typeMaxInsetsMap, null /* typeSideMap */, null /* typeVisibilityMap */);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200176 }
177 }
Jorim Jaggi90990792019-01-21 23:00:20 +0100178 return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
Brad Stenninge0573692019-03-11 13:52:46 -0700179 alwaysConsumeSystemBars, cutout);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200180 }
181
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100182 private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
Tiger Huang332793b2019-10-29 23:21:27 +0800183 Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray typeSideMap,
Jorim Jaggi90990792019-01-21 23:00:20 +0100184 @Nullable boolean[] typeVisibilityMap) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100185 Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
186
Adrian Roos11dfd272019-03-25 19:21:26 +0100187 int type = toPublicType(source.getType());
188 processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
189 insets, type);
190
191 if (type == MANDATORY_SYSTEM_GESTURES) {
192 // Mandatory system gestures are also system gestures.
193 // TODO: find a way to express this more generally. One option would be to define
194 // Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the
195 // ability to set systemGestureInsets() independently from
196 // mandatorySystemGestureInsets() in the Builder.
197 processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
198 insets, SYSTEM_GESTURES);
199 }
200 }
201
202 private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
Tiger Huang332793b2019-10-29 23:21:27 +0800203 @InternalInsetsSide @Nullable SparseIntArray typeSideMap,
Adrian Roos11dfd272019-03-25 19:21:26 +0100204 @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
205 int index = indexOf(type);
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100206 Insets existing = typeInsetsMap[index];
207 if (existing == null) {
208 typeInsetsMap[index] = insets;
209 } else {
210 typeInsetsMap[index] = Insets.max(existing, insets);
211 }
212
Jorim Jaggi90990792019-01-21 23:00:20 +0100213 if (typeVisibilityMap != null) {
214 typeVisibilityMap[index] = source.isVisible();
215 }
216
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700217 if (typeSideMap != null) {
Tiger Huang332793b2019-10-29 23:21:27 +0800218 @InternalInsetsSide int insetSide = getInsetSide(insets);
219 if (insetSide != ISIDE_UNKNOWN) {
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700220 typeSideMap.put(source.getType(), insetSide);
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100221 }
222 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200223 }
224
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100225 /**
226 * Retrieves the side for a certain {@code insets}. It is required that only one field l/t/r/b
227 * is set in order that this method returns a meaningful result.
228 */
Tiger Huang332793b2019-10-29 23:21:27 +0800229 private @InternalInsetsSide int getInsetSide(Insets insets) {
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700230 if (Insets.NONE.equals(insets)) {
Tiger Huang332793b2019-10-29 23:21:27 +0800231 return ISIDE_FLOATING;
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700232 }
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100233 if (insets.left != 0) {
Tiger Huang332793b2019-10-29 23:21:27 +0800234 return ISIDE_LEFT;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100235 }
236 if (insets.top != 0) {
Tiger Huang332793b2019-10-29 23:21:27 +0800237 return ISIDE_TOP;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100238 }
239 if (insets.right != 0) {
Tiger Huang332793b2019-10-29 23:21:27 +0800240 return ISIDE_RIGHT;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100241 }
242 if (insets.bottom != 0) {
Tiger Huang332793b2019-10-29 23:21:27 +0800243 return ISIDE_BOTTOM;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100244 }
Tiger Huang332793b2019-10-29 23:21:27 +0800245 return ISIDE_UNKNOWN;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100246 }
247
Tiger Huang332793b2019-10-29 23:21:27 +0800248 public InsetsSource getSource(@InternalInsetsType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200249 return mSources.computeIfAbsent(type, InsetsSource::new);
250 }
251
Tarandeep Singha6f35612019-01-11 19:50:46 -0800252 public void setDisplayFrame(Rect frame) {
253 mDisplayFrame.set(frame);
254 }
255
256 public Rect getDisplayFrame() {
257 return mDisplayFrame;
258 }
259
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200260 /**
261 * Modifies the state of this class to exclude a certain type to make it ready for dispatching
262 * to the client.
263 *
Tiger Huang332793b2019-10-29 23:21:27 +0800264 * @param type The {@link InternalInsetsType} of the source to remove
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200265 */
Tiger Huang332793b2019-10-29 23:21:27 +0800266 public void removeSource(@InternalInsetsType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200267 mSources.remove(type);
268 }
269
Jorim Jaggi956ca412019-01-07 14:49:14 +0100270 /**
271 * A shortcut for setting the visibility of the source.
272 *
Tiger Huang332793b2019-10-29 23:21:27 +0800273 * @param type The {@link InternalInsetsType} of the source to set the visibility
Jorim Jaggi956ca412019-01-07 14:49:14 +0100274 * @param visible {@code true} for visible
275 */
Tiger Huang332793b2019-10-29 23:21:27 +0800276 public void setSourceVisible(@InternalInsetsType int type, boolean visible) {
Jorim Jaggi956ca412019-01-07 14:49:14 +0100277 InsetsSource source = mSources.get(type);
278 if (source != null) {
279 source.setVisible(visible);
280 }
281 }
282
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200283 public void set(InsetsState other) {
284 set(other, false /* copySources */);
285 }
286
287 public void set(InsetsState other, boolean copySources) {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800288 mDisplayFrame.set(other.mDisplayFrame);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200289 mSources.clear();
290 if (copySources) {
291 for (int i = 0; i < other.mSources.size(); i++) {
292 InsetsSource source = other.mSources.valueAt(i);
293 mSources.put(source.getType(), new InsetsSource(source));
294 }
295 } else {
296 mSources.putAll(other.mSources);
297 }
298 }
299
Jorim Jaggie35c0592018-11-06 16:21:08 +0100300 public void addSource(InsetsSource source) {
301 mSources.put(source.getType(), source);
302 }
303
304 public int getSourcesCount() {
305 return mSources.size();
306 }
307
308 public InsetsSource sourceAt(int index) {
309 return mSources.valueAt(index);
310 }
311
Tiger Huang332793b2019-10-29 23:21:27 +0800312 public static @InternalInsetsType ArraySet<Integer> toInternalType(@InsetsType int types) {
Jorim Jaggib6030952018-10-23 18:31:52 +0200313 final ArraySet<Integer> result = new ArraySet<>();
Tiger Huang332793b2019-10-29 23:21:27 +0800314 if ((types & Type.STATUS_BARS) != 0) {
315 result.add(ITYPE_STATUS_BAR);
Jorim Jaggib6030952018-10-23 18:31:52 +0200316 }
Tiger Huang332793b2019-10-29 23:21:27 +0800317 if ((types & Type.NAVIGATION_BARS) != 0) {
318 result.add(ITYPE_NAVIGATION_BAR);
Jorim Jaggib6030952018-10-23 18:31:52 +0200319 }
Tiger Huang332793b2019-10-29 23:21:27 +0800320 if ((types & Type.CAPTION_BAR) != 0) {
321 result.add(ITYPE_CAPTION_BAR);
322 }
323 if ((types & Type.IME) != 0) {
324 result.add(ITYPE_IME);
Jorim Jaggib6030952018-10-23 18:31:52 +0200325 }
326 return result;
327 }
328
Tiger Huang332793b2019-10-29 23:21:27 +0800329 static @Type.InsetsType int toPublicType(@InternalInsetsType int type) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100330 switch (type) {
Tiger Huang332793b2019-10-29 23:21:27 +0800331 case ITYPE_STATUS_BAR:
332 return Type.STATUS_BARS;
333 case ITYPE_NAVIGATION_BAR:
334 return Type.NAVIGATION_BARS;
335 case ITYPE_CAPTION_BAR:
336 return Type.CAPTION_BAR;
337 case ITYPE_IME:
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100338 return Type.IME;
Tiger Huang332793b2019-10-29 23:21:27 +0800339 case ITYPE_TOP_GESTURES:
340 case ITYPE_BOTTOM_GESTURES:
Adrian Roos11dfd272019-03-25 19:21:26 +0100341 return Type.MANDATORY_SYSTEM_GESTURES;
Tiger Huang332793b2019-10-29 23:21:27 +0800342 case ITYPE_LEFT_GESTURES:
343 case ITYPE_RIGHT_GESTURES:
Adrian Roos11dfd272019-03-25 19:21:26 +0100344 return Type.SYSTEM_GESTURES;
Tiger Huang332793b2019-10-29 23:21:27 +0800345 case ITYPE_TOP_TAPPABLE_ELEMENT:
346 case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
Adrian Roos11dfd272019-03-25 19:21:26 +0100347 return Type.TAPPABLE_ELEMENT;
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100348 default:
349 throw new IllegalArgumentException("Unknown type: " + type);
350 }
351 }
352
Tiger Huang332793b2019-10-29 23:21:27 +0800353 public static boolean getDefaultVisibility(@InsetsType int type) {
354 return type != ITYPE_IME;
Jorim Jaggie35c0592018-11-06 16:21:08 +0100355 }
356
Tiger Huang332793b2019-10-29 23:21:27 +0800357 public static boolean containsType(@InternalInsetsType int[] types,
358 @InternalInsetsType int type) {
Jorim Jaggi956ca412019-01-07 14:49:14 +0100359 if (types == null) {
360 return false;
361 }
362 for (int t : types) {
363 if (t == type) {
364 return true;
365 }
366 }
367 return false;
368 }
369
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200370 public void dump(String prefix, PrintWriter pw) {
371 pw.println(prefix + "InsetsState");
372 for (int i = mSources.size() - 1; i >= 0; i--) {
373 mSources.valueAt(i).dump(prefix + " ", pw);
374 }
375 }
376
Tiger Huang332793b2019-10-29 23:21:27 +0800377 public static String typeToString(@InternalInsetsType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200378 switch (type) {
Tiger Huang332793b2019-10-29 23:21:27 +0800379 case ITYPE_STATUS_BAR:
380 return "ITYPE_STATUS_BAR";
381 case ITYPE_NAVIGATION_BAR:
382 return "ITYPE_NAVIGATION_BAR";
383 case ITYPE_CAPTION_BAR:
384 return "ITYPE_CAPTION_BAR";
385 case ITYPE_TOP_GESTURES:
386 return "ITYPE_TOP_GESTURES";
387 case ITYPE_BOTTOM_GESTURES:
388 return "ITYPE_BOTTOM_GESTURES";
389 case ITYPE_LEFT_GESTURES:
390 return "ITYPE_LEFT_GESTURES";
391 case ITYPE_RIGHT_GESTURES:
392 return "ITYPE_RIGHT_GESTURES";
393 case ITYPE_TOP_TAPPABLE_ELEMENT:
394 return "ITYPE_TOP_TAPPABLE_ELEMENT";
395 case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
396 return "ITYPE_BOTTOM_TAPPABLE_ELEMENT";
397 case ITYPE_IME:
398 return "ITYPE_IME";
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200399 default:
Tiger Huang332793b2019-10-29 23:21:27 +0800400 return "ITYPE_UNKNOWN_" + type;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200401 }
402 }
403
404 @Override
405 public boolean equals(Object o) {
406 if (this == o) { return true; }
407 if (o == null || getClass() != o.getClass()) { return false; }
408
409 InsetsState state = (InsetsState) o;
410
Tarandeep Singha6f35612019-01-11 19:50:46 -0800411 if (!mDisplayFrame.equals(state.mDisplayFrame)) {
412 return false;
413 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200414 if (mSources.size() != state.mSources.size()) {
415 return false;
416 }
417 for (int i = mSources.size() - 1; i >= 0; i--) {
418 InsetsSource source = mSources.valueAt(i);
419 InsetsSource otherSource = state.mSources.get(source.getType());
420 if (otherSource == null) {
421 return false;
422 }
423 if (!otherSource.equals(source)) {
424 return false;
425 }
426 }
427 return true;
428 }
429
430 @Override
431 public int hashCode() {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800432 return Objects.hash(mDisplayFrame, mSources);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200433 }
434
435 public InsetsState(Parcel in) {
436 readFromParcel(in);
437 }
438
439 @Override
440 public int describeContents() {
441 return 0;
442 }
443
444 @Override
445 public void writeToParcel(Parcel dest, int flags) {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800446 dest.writeParcelable(mDisplayFrame, flags);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200447 dest.writeInt(mSources.size());
448 for (int i = 0; i < mSources.size(); i++) {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800449 dest.writeParcelable(mSources.valueAt(i), flags);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200450 }
451 }
452
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700453 public static final @android.annotation.NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200454
455 public InsetsState createFromParcel(Parcel in) {
456 return new InsetsState(in);
457 }
458
459 public InsetsState[] newArray(int size) {
460 return new InsetsState[size];
461 }
462 };
463
464 public void readFromParcel(Parcel in) {
465 mSources.clear();
Tarandeep Singha6f35612019-01-11 19:50:46 -0800466 mDisplayFrame.set(in.readParcelable(null /* loader */));
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200467 final int size = in.readInt();
468 for (int i = 0; i < size; i++) {
469 final InsetsSource source = in.readParcelable(null /* loader */);
470 mSources.put(source.getType(), source);
471 }
472 }
473}
474