blob: e9de3f0bb3ca73d32e4d260cb4ec775a221bd806 [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;
37import android.view.WindowInsets.Type.InsetType;
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)
57 @IntDef(prefix = "TYPE", value = {
58 TYPE_TOP_BAR,
59 TYPE_SIDE_BAR_1,
60 TYPE_SIDE_BAR_2,
61 TYPE_SIDE_BAR_3,
Adrian Roos11dfd272019-03-25 19:21:26 +010062 TYPE_TOP_GESTURES,
63 TYPE_BOTTOM_GESTURES,
64 TYPE_LEFT_GESTURES,
65 TYPE_RIGHT_GESTURES,
66 TYPE_TOP_TAPPABLE_ELEMENT,
67 TYPE_BOTTOM_TAPPABLE_ELEMENT,
Jorim Jaggif96c90a2018-09-26 16:55:15 +020068 TYPE_IME
69 })
70 public @interface InternalInsetType {}
71
72 static final int FIRST_TYPE = 0;
73
74 /** Top bar. Can be status bar or caption in freeform windowing mode. */
75 public static final int TYPE_TOP_BAR = FIRST_TYPE;
76
77 /**
78 * Up to 3 side bars that appear on left/right/bottom. On phones there is only one side bar
79 * (the navigation bar, see {@link #TYPE_NAVIGATION_BAR}), but other form factors might have
80 * multiple, like Android Auto.
81 */
82 public static final int TYPE_SIDE_BAR_1 = 1;
83 public static final int TYPE_SIDE_BAR_2 = 2;
84 public static final int TYPE_SIDE_BAR_3 = 3;
85
Adrian Roos11dfd272019-03-25 19:21:26 +010086 public static final int TYPE_TOP_GESTURES = 4;
87 public static final int TYPE_BOTTOM_GESTURES = 5;
88 public static final int TYPE_LEFT_GESTURES = 6;
89 public static final int TYPE_RIGHT_GESTURES = 7;
90 public static final int TYPE_TOP_TAPPABLE_ELEMENT = 8;
91 public static final int TYPE_BOTTOM_TAPPABLE_ELEMENT = 9;
92
Jorim Jaggif96c90a2018-09-26 16:55:15 +020093 /** Input method window. */
Adrian Roos11dfd272019-03-25 19:21:26 +010094 public static final int TYPE_IME = 10;
95
Jorim Jaggif96c90a2018-09-26 16:55:15 +020096 static final int LAST_TYPE = TYPE_IME;
97
98 // Derived types
99
100 /** First side bar is navigation bar. */
101 public static final int TYPE_NAVIGATION_BAR = TYPE_SIDE_BAR_1;
102
103 /** A shelf is the same as the navigation bar. */
104 public static final int TYPE_SHELF = TYPE_NAVIGATION_BAR;
105
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100106 @Retention(RetentionPolicy.SOURCE)
107 @IntDef(prefix = "INSET_SIDE", value = {
108 INSET_SIDE_LEFT,
109 INSET_SIDE_TOP,
110 INSET_SIDE_RIGHT,
111 INSET_SIDE_BOTTOM,
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700112 INSET_SIDE_FLOATING,
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100113 INSET_SIDE_UNKNWON
114 })
115 public @interface InsetSide {}
116 static final int INSET_SIDE_LEFT = 0;
117 static final int INSET_SIDE_TOP = 1;
118 static final int INSET_SIDE_RIGHT = 2;
119 static final int INSET_SIDE_BOTTOM = 3;
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700120 static final int INSET_SIDE_FLOATING = 4;
121 static final int INSET_SIDE_UNKNWON = 5;
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100122
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200123 private final ArrayMap<Integer, InsetsSource> mSources = new ArrayMap<>();
124
Tarandeep Singha6f35612019-01-11 19:50:46 -0800125 /**
126 * The frame of the display these sources are relative to.
127 */
128 private final Rect mDisplayFrame = new Rect();
129
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200130 public InsetsState() {
131 }
132
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100133 public InsetsState(InsetsState copy) {
134 set(copy);
135 }
136
Jorim Jaggi02a741f2018-12-12 17:40:19 -0800137 public InsetsState(InsetsState copy, boolean copySources) {
138 set(copy, copySources);
139 }
140
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200141 /**
142 * Calculates {@link WindowInsets} based on the current source configuration.
143 *
144 * @param frame The frame to calculate the insets relative to.
145 * @return The calculated insets.
146 */
147 public WindowInsets calculateInsets(Rect frame, boolean isScreenRound,
Brad Stenninge0573692019-03-11 13:52:46 -0700148 boolean alwaysConsumeSystemBars, DisplayCutout cutout,
Jorim Jaggi73f3e8a2019-01-14 13:06:23 +0100149 @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets,
Jorim Jaggi648e5882019-01-24 13:24:02 +0100150 int legacySoftInputMode, @Nullable @InsetSide SparseIntArray typeSideMap) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100151 Insets[] typeInsetsMap = new Insets[Type.SIZE];
152 Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
Jorim Jaggi90990792019-01-21 23:00:20 +0100153 boolean[] typeVisibilityMap = new boolean[SIZE];
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200154 final Rect relativeFrame = new Rect(frame);
155 final Rect relativeFrameMax = new Rect(frame);
Jorim Jaggi90990792019-01-21 23:00:20 +0100156 if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
Jorim Jaggi73f3e8a2019-01-14 13:06:23 +0100157 && legacyContentInsets != null && legacyStableInsets != null) {
158 WindowInsets.assignCompatInsets(typeInsetsMap, legacyContentInsets);
159 WindowInsets.assignCompatInsets(typeMaxInsetsMap, legacyStableInsets);
160 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200161 for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
162 InsetsSource source = mSources.get(type);
163 if (source == null) {
164 continue;
165 }
Jorim Jaggi648e5882019-01-24 13:24:02 +0100166
Tarandeep Singh92d2dd32019-08-07 14:45:01 -0700167 boolean skipNonImeInImeMode = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_IME
168 && source.getType() != TYPE_IME;
Jorim Jaggi648e5882019-01-24 13:24:02 +0100169 boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
170 && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR);
171 boolean skipIme = source.getType() == TYPE_IME
172 && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
Adrian Roos11dfd272019-03-25 19:21:26 +0100173 boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
174 && (toPublicType(type) & Type.compatSystemInsets()) != 0;
Tarandeep Singh92d2dd32019-08-07 14:45:01 -0700175 if (skipSystemBars || skipIme || skipLegacyTypes || skipNonImeInImeMode) {
Jorim Jaggi90990792019-01-21 23:00:20 +0100176 typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible();
177 continue;
178 }
179
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100180 processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
Jorim Jaggi90990792019-01-21 23:00:20 +0100181 typeSideMap, typeVisibilityMap);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200182
183 // IME won't be reported in max insets as the size depends on the EditorInfo of the IME
184 // target.
185 if (source.getType() != TYPE_IME) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100186 processSource(source, relativeFrameMax, true /* ignoreVisibility */,
Jorim Jaggi90990792019-01-21 23:00:20 +0100187 typeMaxInsetsMap, null /* typeSideMap */, null /* typeVisibilityMap */);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200188 }
189 }
Jorim Jaggi90990792019-01-21 23:00:20 +0100190 return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
Brad Stenninge0573692019-03-11 13:52:46 -0700191 alwaysConsumeSystemBars, cutout);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200192 }
193
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100194 private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
Jorim Jaggi90990792019-01-21 23:00:20 +0100195 Insets[] typeInsetsMap, @Nullable @InsetSide SparseIntArray typeSideMap,
196 @Nullable boolean[] typeVisibilityMap) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100197 Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
198
Adrian Roos11dfd272019-03-25 19:21:26 +0100199 int type = toPublicType(source.getType());
200 processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
201 insets, type);
202
203 if (type == MANDATORY_SYSTEM_GESTURES) {
204 // Mandatory system gestures are also system gestures.
205 // TODO: find a way to express this more generally. One option would be to define
206 // Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the
207 // ability to set systemGestureInsets() independently from
208 // mandatorySystemGestureInsets() in the Builder.
209 processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
210 insets, SYSTEM_GESTURES);
211 }
212 }
213
214 private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
215 @InsetSide @Nullable SparseIntArray typeSideMap,
216 @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
217 int index = indexOf(type);
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100218 Insets existing = typeInsetsMap[index];
219 if (existing == null) {
220 typeInsetsMap[index] = insets;
221 } else {
222 typeInsetsMap[index] = Insets.max(existing, insets);
223 }
224
Jorim Jaggi90990792019-01-21 23:00:20 +0100225 if (typeVisibilityMap != null) {
226 typeVisibilityMap[index] = source.isVisible();
227 }
228
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700229 if (typeSideMap != null) {
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100230 @InsetSide int insetSide = getInsetSide(insets);
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100231 if (insetSide != INSET_SIDE_UNKNWON) {
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700232 typeSideMap.put(source.getType(), insetSide);
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100233 }
234 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200235 }
236
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100237 /**
238 * Retrieves the side for a certain {@code insets}. It is required that only one field l/t/r/b
239 * is set in order that this method returns a meaningful result.
240 */
241 private @InsetSide int getInsetSide(Insets insets) {
Tarandeep Singh95a3dbf2019-10-22 10:39:24 -0700242 if (Insets.NONE.equals(insets)) {
243 return INSET_SIDE_FLOATING;
244 }
Jorim Jaggi5bb571d2018-11-06 14:42:04 +0100245 if (insets.left != 0) {
246 return INSET_SIDE_LEFT;
247 }
248 if (insets.top != 0) {
249 return INSET_SIDE_TOP;
250 }
251 if (insets.right != 0) {
252 return INSET_SIDE_RIGHT;
253 }
254 if (insets.bottom != 0) {
255 return INSET_SIDE_BOTTOM;
256 }
257 return INSET_SIDE_UNKNWON;
258 }
259
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200260 public InsetsSource getSource(@InternalInsetType int type) {
261 return mSources.computeIfAbsent(type, InsetsSource::new);
262 }
263
Tarandeep Singha6f35612019-01-11 19:50:46 -0800264 public void setDisplayFrame(Rect frame) {
265 mDisplayFrame.set(frame);
266 }
267
268 public Rect getDisplayFrame() {
269 return mDisplayFrame;
270 }
271
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200272 /**
273 * Modifies the state of this class to exclude a certain type to make it ready for dispatching
274 * to the client.
275 *
276 * @param type The {@link InternalInsetType} of the source to remove
277 */
Jorim Jaggi956ca412019-01-07 14:49:14 +0100278 public void removeSource(@InternalInsetType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200279 mSources.remove(type);
280 }
281
Jorim Jaggi956ca412019-01-07 14:49:14 +0100282 /**
283 * A shortcut for setting the visibility of the source.
284 *
285 * @param type The {@link InternalInsetType} of the source to set the visibility
286 * @param visible {@code true} for visible
287 */
288 public void setSourceVisible(@InternalInsetType int type, boolean visible) {
289 InsetsSource source = mSources.get(type);
290 if (source != null) {
291 source.setVisible(visible);
292 }
293 }
294
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200295 public void set(InsetsState other) {
296 set(other, false /* copySources */);
297 }
298
299 public void set(InsetsState other, boolean copySources) {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800300 mDisplayFrame.set(other.mDisplayFrame);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200301 mSources.clear();
302 if (copySources) {
303 for (int i = 0; i < other.mSources.size(); i++) {
304 InsetsSource source = other.mSources.valueAt(i);
305 mSources.put(source.getType(), new InsetsSource(source));
306 }
307 } else {
308 mSources.putAll(other.mSources);
309 }
310 }
311
Jorim Jaggie35c0592018-11-06 16:21:08 +0100312 public void addSource(InsetsSource source) {
313 mSources.put(source.getType(), source);
314 }
315
316 public int getSourcesCount() {
317 return mSources.size();
318 }
319
320 public InsetsSource sourceAt(int index) {
321 return mSources.valueAt(index);
322 }
323
Jorim Jaggib6030952018-10-23 18:31:52 +0200324 public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) {
325 final ArraySet<Integer> result = new ArraySet<>();
326 if ((insetTypes & Type.TOP_BAR) != 0) {
327 result.add(TYPE_TOP_BAR);
328 }
329 if ((insetTypes & Type.SIDE_BARS) != 0) {
330 result.add(TYPE_SIDE_BAR_1);
331 result.add(TYPE_SIDE_BAR_2);
332 result.add(TYPE_SIDE_BAR_3);
333 }
334 if ((insetTypes & Type.IME) != 0) {
335 result.add(TYPE_IME);
336 }
337 return result;
338 }
339
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100340 static @InsetType int toPublicType(@InternalInsetType int type) {
341 switch (type) {
342 case TYPE_TOP_BAR:
343 return Type.TOP_BAR;
344 case TYPE_SIDE_BAR_1:
345 case TYPE_SIDE_BAR_2:
346 case TYPE_SIDE_BAR_3:
347 return Type.SIDE_BARS;
348 case TYPE_IME:
349 return Type.IME;
Adrian Roos11dfd272019-03-25 19:21:26 +0100350 case TYPE_TOP_GESTURES:
351 case TYPE_BOTTOM_GESTURES:
352 return Type.MANDATORY_SYSTEM_GESTURES;
353 case TYPE_LEFT_GESTURES:
354 case TYPE_RIGHT_GESTURES:
355 return Type.SYSTEM_GESTURES;
356 case TYPE_TOP_TAPPABLE_ELEMENT:
357 case TYPE_BOTTOM_TAPPABLE_ELEMENT:
358 return Type.TAPPABLE_ELEMENT;
Jorim Jaggibcf99ff2018-12-03 18:04:26 +0100359 default:
360 throw new IllegalArgumentException("Unknown type: " + type);
361 }
362 }
363
Jorim Jaggid89efeb2019-01-22 17:48:34 +0100364 public static boolean getDefaultVisibility(@InsetType int type) {
Jorim Jaggie35c0592018-11-06 16:21:08 +0100365 switch (type) {
366 case TYPE_TOP_BAR:
367 case TYPE_SIDE_BAR_1:
368 case TYPE_SIDE_BAR_2:
369 case TYPE_SIDE_BAR_3:
370 return true;
371 case TYPE_IME:
372 return false;
373 default:
374 return true;
375 }
376 }
377
Jorim Jaggi956ca412019-01-07 14:49:14 +0100378 public static boolean containsType(@InternalInsetType int[] types,
379 @InternalInsetType int type) {
380 if (types == null) {
381 return false;
382 }
383 for (int t : types) {
384 if (t == type) {
385 return true;
386 }
387 }
388 return false;
389 }
390
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200391 public void dump(String prefix, PrintWriter pw) {
392 pw.println(prefix + "InsetsState");
393 for (int i = mSources.size() - 1; i >= 0; i--) {
394 mSources.valueAt(i).dump(prefix + " ", pw);
395 }
396 }
397
Jorim Jaggi956ca412019-01-07 14:49:14 +0100398 public static String typeToString(@InternalInsetType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200399 switch (type) {
400 case TYPE_TOP_BAR:
401 return "TYPE_TOP_BAR";
402 case TYPE_SIDE_BAR_1:
403 return "TYPE_SIDE_BAR_1";
404 case TYPE_SIDE_BAR_2:
405 return "TYPE_SIDE_BAR_2";
406 case TYPE_SIDE_BAR_3:
407 return "TYPE_SIDE_BAR_3";
Adrian Roos11dfd272019-03-25 19:21:26 +0100408 case TYPE_TOP_GESTURES:
409 return "TYPE_TOP_GESTURES";
410 case TYPE_BOTTOM_GESTURES:
411 return "TYPE_BOTTOM_GESTURES";
412 case TYPE_LEFT_GESTURES:
413 return "TYPE_LEFT_GESTURES";
414 case TYPE_RIGHT_GESTURES:
415 return "TYPE_RIGHT_GESTURES";
416 case TYPE_TOP_TAPPABLE_ELEMENT:
417 return "TYPE_TOP_TAPPABLE_ELEMENT";
418 case TYPE_BOTTOM_TAPPABLE_ELEMENT:
419 return "TYPE_BOTTOM_TAPPABLE_ELEMENT";
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200420 default:
Adrian Roos11dfd272019-03-25 19:21:26 +0100421 return "TYPE_UNKNOWN_" + type;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200422 }
423 }
424
425 @Override
426 public boolean equals(Object o) {
427 if (this == o) { return true; }
428 if (o == null || getClass() != o.getClass()) { return false; }
429
430 InsetsState state = (InsetsState) o;
431
Tarandeep Singha6f35612019-01-11 19:50:46 -0800432 if (!mDisplayFrame.equals(state.mDisplayFrame)) {
433 return false;
434 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200435 if (mSources.size() != state.mSources.size()) {
436 return false;
437 }
438 for (int i = mSources.size() - 1; i >= 0; i--) {
439 InsetsSource source = mSources.valueAt(i);
440 InsetsSource otherSource = state.mSources.get(source.getType());
441 if (otherSource == null) {
442 return false;
443 }
444 if (!otherSource.equals(source)) {
445 return false;
446 }
447 }
448 return true;
449 }
450
451 @Override
452 public int hashCode() {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800453 return Objects.hash(mDisplayFrame, mSources);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200454 }
455
456 public InsetsState(Parcel in) {
457 readFromParcel(in);
458 }
459
460 @Override
461 public int describeContents() {
462 return 0;
463 }
464
465 @Override
466 public void writeToParcel(Parcel dest, int flags) {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800467 dest.writeParcelable(mDisplayFrame, flags);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200468 dest.writeInt(mSources.size());
469 for (int i = 0; i < mSources.size(); i++) {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800470 dest.writeParcelable(mSources.valueAt(i), flags);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200471 }
472 }
473
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700474 public static final @android.annotation.NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200475
476 public InsetsState createFromParcel(Parcel in) {
477 return new InsetsState(in);
478 }
479
480 public InsetsState[] newArray(int size) {
481 return new InsetsState[size];
482 }
483 };
484
485 public void readFromParcel(Parcel in) {
486 mSources.clear();
Tarandeep Singha6f35612019-01-11 19:50:46 -0800487 mDisplayFrame.set(in.readParcelable(null /* loader */));
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200488 final int size = in.readInt();
489 for (int i = 0; i < size; i++) {
490 final InsetsSource source = in.readParcelable(null /* loader */);
491 mSources.put(source.getType(), source);
492 }
493 }
494}
495