blob: 67ccfd6707f4036097262a64f2852be52bb11ca9 [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 Jaggi4e04eb22020-01-09 16:42:14 +010019import android.annotation.Nullable;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020020import android.graphics.Insets;
21import android.graphics.Rect;
22import android.os.Parcel;
23import android.os.Parcelable;
Tiger Huang332793b2019-10-29 23:21:27 +080024import android.view.InsetsState.InternalInsetsType;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020025
26import java.io.PrintWriter;
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010027import java.util.Objects;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020028
29/**
30 * Represents the state of a single window generating insets for clients.
31 * @hide
32 */
33public class InsetsSource implements Parcelable {
34
Tiger Huang332793b2019-10-29 23:21:27 +080035 private final @InternalInsetsType int mType;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020036
37 /** Frame of the source in screen coordinate space */
38 private final Rect mFrame;
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010039 private @Nullable Rect mVisibleFrame;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020040 private boolean mVisible;
41
42 private final Rect mTmpFrame = new Rect();
43
Tiger Huang332793b2019-10-29 23:21:27 +080044 public InsetsSource(@InternalInsetsType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +020045 mType = type;
46 mFrame = new Rect();
Jorim Jaggi0dd0cf92019-12-27 15:17:44 +010047 mVisible = InsetsState.getDefaultVisibility(type);
Jorim Jaggif96c90a2018-09-26 16:55:15 +020048 }
49
50 public InsetsSource(InsetsSource other) {
51 mType = other.mType;
52 mFrame = new Rect(other.mFrame);
53 mVisible = other.mVisible;
54 }
55
56 public void setFrame(Rect frame) {
57 mFrame.set(frame);
58 }
59
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010060 public void setVisibleFrame(@Nullable Rect visibleFrame) {
61 mVisibleFrame = visibleFrame != null ? new Rect(visibleFrame) : visibleFrame;
62 }
63
Jorim Jaggif96c90a2018-09-26 16:55:15 +020064 public void setVisible(boolean visible) {
65 mVisible = visible;
66 }
67
Tiger Huang332793b2019-10-29 23:21:27 +080068 public @InternalInsetsType int getType() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +020069 return mType;
70 }
71
72 public Rect getFrame() {
73 return mFrame;
74 }
75
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010076 public @Nullable Rect getVisibleFrame() {
77 return mVisibleFrame;
78 }
79
Jorim Jaggie35c0592018-11-06 16:21:08 +010080 public boolean isVisible() {
81 return mVisible;
82 }
83
Jorim Jaggif96c90a2018-09-26 16:55:15 +020084 /**
85 * Calculates the insets this source will cause to a client window.
86 *
87 * @param relativeFrame The frame to calculate the insets relative to.
88 * @param ignoreVisibility If true, always reports back insets even if source isn't visible.
Jorim Jaggi5bb571d2018-11-06 14:42:04 +010089 * @return The resulting insets. The contract is that only one side will be occupied by a
90 * source.
Jorim Jaggif96c90a2018-09-26 16:55:15 +020091 */
92 public Insets calculateInsets(Rect relativeFrame, boolean ignoreVisibility) {
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010093 return calculateInsets(relativeFrame, mFrame, ignoreVisibility);
94 }
95
96 /**
97 * Like {@link #calculateInsets(Rect, boolean)}, but will return visible insets.
98 */
99 public Insets calculateVisibleInsets(Rect relativeFrame) {
100 return calculateInsets(relativeFrame, mVisibleFrame != null ? mVisibleFrame : mFrame,
101 false /* ignoreVisibility */);
102 }
103
104 private Insets calculateInsets(Rect relativeFrame, Rect frame, boolean ignoreVisibility) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200105 if (!ignoreVisibility && !mVisible) {
106 return Insets.NONE;
107 }
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100108 if (!mTmpFrame.setIntersect(frame, relativeFrame)) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200109 return Insets.NONE;
110 }
111
112 // Intersecting at top/bottom
113 if (mTmpFrame.width() == relativeFrame.width()) {
114 if (mTmpFrame.top == relativeFrame.top) {
115 return Insets.of(0, mTmpFrame.height(), 0, 0);
116 } else {
117 return Insets.of(0, 0, 0, mTmpFrame.height());
118 }
119 }
120 // Intersecting at left/right
121 else if (mTmpFrame.height() == relativeFrame.height()) {
122 if (mTmpFrame.left == relativeFrame.left) {
123 return Insets.of(mTmpFrame.width(), 0, 0, 0);
124 } else {
125 return Insets.of(0, 0, mTmpFrame.width(), 0);
126 }
127 } else {
128 return Insets.NONE;
129 }
130 }
131
132 public void dump(String prefix, PrintWriter pw) {
133 pw.print(prefix);
134 pw.print("InsetsSource type="); pw.print(InsetsState.typeToString(mType));
135 pw.print(" frame="); pw.print(mFrame.toShortString());
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100136 if (mVisibleFrame != null) {
137 pw.print(" visibleFrmae="); pw.print(mVisibleFrame.toShortString());
138 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200139 pw.print(" visible="); pw.print(mVisible);
140 pw.println();
141 }
142
143 @Override
144 public boolean equals(Object o) {
145 if (this == o) return true;
146 if (o == null || getClass() != o.getClass()) return false;
147
148 InsetsSource that = (InsetsSource) o;
149
150 if (mType != that.mType) return false;
151 if (mVisible != that.mVisible) return false;
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100152 if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200153 return mFrame.equals(that.mFrame);
154 }
155
156 @Override
157 public int hashCode() {
158 int result = mType;
159 result = 31 * result + mFrame.hashCode();
160 result = 31 * result + (mVisible ? 1 : 0);
161 return result;
162 }
163
164 public InsetsSource(Parcel in) {
165 mType = in.readInt();
166 mFrame = in.readParcelable(null /* loader */);
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100167 mVisibleFrame = in.readParcelable(null /* loader */);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200168 mVisible = in.readBoolean();
169 }
170
171 @Override
172 public int describeContents() {
173 return 0;
174 }
175
176 @Override
177 public void writeToParcel(Parcel dest, int flags) {
178 dest.writeInt(mType);
179 dest.writeParcelable(mFrame, 0 /* flags*/);
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100180 dest.writeParcelable(mVisibleFrame, 0 /* flags */);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200181 dest.writeBoolean(mVisible);
182 }
183
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700184 public static final @android.annotation.NonNull Creator<InsetsSource> CREATOR = new Creator<InsetsSource>() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200185
186 public InsetsSource createFromParcel(Parcel in) {
187 return new InsetsSource(in);
188 }
189
190 public InsetsSource[] newArray(int size) {
191 return new InsetsSource[size];
192 }
193 };
194}