blob: 719f649cb5a2fb307a7a5f6fbb1b9772d71544f1 [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 Jaggi23a02a92020-01-29 15:30:36 +010019import static android.view.InsetsState.ITYPE_IME;
20
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010021import android.annotation.Nullable;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020022import android.graphics.Insets;
23import android.graphics.Rect;
24import android.os.Parcel;
25import android.os.Parcelable;
Tiger Huang332793b2019-10-29 23:21:27 +080026import android.view.InsetsState.InternalInsetsType;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020027
28import java.io.PrintWriter;
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010029import java.util.Objects;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020030
31/**
32 * Represents the state of a single window generating insets for clients.
33 * @hide
34 */
35public class InsetsSource implements Parcelable {
36
Tiger Huang332793b2019-10-29 23:21:27 +080037 private final @InternalInsetsType int mType;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020038
39 /** Frame of the source in screen coordinate space */
40 private final Rect mFrame;
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010041 private @Nullable Rect mVisibleFrame;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020042 private boolean mVisible;
43
44 private final Rect mTmpFrame = new Rect();
45
Tiger Huang332793b2019-10-29 23:21:27 +080046 public InsetsSource(@InternalInsetsType int type) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +020047 mType = type;
48 mFrame = new Rect();
Jorim Jaggi0dd0cf92019-12-27 15:17:44 +010049 mVisible = InsetsState.getDefaultVisibility(type);
Jorim Jaggif96c90a2018-09-26 16:55:15 +020050 }
51
52 public InsetsSource(InsetsSource other) {
53 mType = other.mType;
54 mFrame = new Rect(other.mFrame);
55 mVisible = other.mVisible;
Jorim Jaggi4d4fae42020-01-30 23:10:12 +010056 mVisibleFrame = other.mVisibleFrame != null
57 ? new Rect(other.mVisibleFrame)
58 : null;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020059 }
60
Tiger Huange16645a2020-02-25 22:24:39 +080061 public void setFrame(int left, int top, int right, int bottom) {
62 mFrame.set(left, top, right, bottom);
63 }
64
Jorim Jaggif96c90a2018-09-26 16:55:15 +020065 public void setFrame(Rect frame) {
66 mFrame.set(frame);
67 }
68
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010069 public void setVisibleFrame(@Nullable Rect visibleFrame) {
70 mVisibleFrame = visibleFrame != null ? new Rect(visibleFrame) : visibleFrame;
71 }
72
Jorim Jaggif96c90a2018-09-26 16:55:15 +020073 public void setVisible(boolean visible) {
74 mVisible = visible;
75 }
76
Tiger Huang332793b2019-10-29 23:21:27 +080077 public @InternalInsetsType int getType() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +020078 return mType;
79 }
80
81 public Rect getFrame() {
82 return mFrame;
83 }
84
Jorim Jaggi4e04eb22020-01-09 16:42:14 +010085 public @Nullable Rect getVisibleFrame() {
86 return mVisibleFrame;
87 }
88
Jorim Jaggie35c0592018-11-06 16:21:08 +010089 public boolean isVisible() {
90 return mVisible;
91 }
92
Jorim Jaggif96c90a2018-09-26 16:55:15 +020093 /**
94 * Calculates the insets this source will cause to a client window.
95 *
96 * @param relativeFrame The frame to calculate the insets relative to.
97 * @param ignoreVisibility If true, always reports back insets even if source isn't visible.
Jorim Jaggi5bb571d2018-11-06 14:42:04 +010098 * @return The resulting insets. The contract is that only one side will be occupied by a
99 * source.
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200100 */
101 public Insets calculateInsets(Rect relativeFrame, boolean ignoreVisibility) {
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100102 return calculateInsets(relativeFrame, mFrame, ignoreVisibility);
103 }
104
105 /**
106 * Like {@link #calculateInsets(Rect, boolean)}, but will return visible insets.
107 */
108 public Insets calculateVisibleInsets(Rect relativeFrame) {
109 return calculateInsets(relativeFrame, mVisibleFrame != null ? mVisibleFrame : mFrame,
110 false /* ignoreVisibility */);
111 }
112
113 private Insets calculateInsets(Rect relativeFrame, Rect frame, boolean ignoreVisibility) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200114 if (!ignoreVisibility && !mVisible) {
115 return Insets.NONE;
116 }
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100117 if (!mTmpFrame.setIntersect(frame, relativeFrame)) {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200118 return Insets.NONE;
119 }
120
Jorim Jaggi23a02a92020-01-29 15:30:36 +0100121 // TODO: Currently, non-floating IME always intersects at bottom due to issues with cutout.
122 // However, we should let the policy decide from the server.
123 if (getType() == ITYPE_IME) {
124 return Insets.of(0, 0, 0, mTmpFrame.height());
125 }
126
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200127 // Intersecting at top/bottom
128 if (mTmpFrame.width() == relativeFrame.width()) {
129 if (mTmpFrame.top == relativeFrame.top) {
130 return Insets.of(0, mTmpFrame.height(), 0, 0);
131 } else {
132 return Insets.of(0, 0, 0, mTmpFrame.height());
133 }
134 }
135 // Intersecting at left/right
136 else if (mTmpFrame.height() == relativeFrame.height()) {
137 if (mTmpFrame.left == relativeFrame.left) {
138 return Insets.of(mTmpFrame.width(), 0, 0, 0);
139 } else {
140 return Insets.of(0, 0, mTmpFrame.width(), 0);
141 }
142 } else {
143 return Insets.NONE;
144 }
145 }
146
147 public void dump(String prefix, PrintWriter pw) {
148 pw.print(prefix);
149 pw.print("InsetsSource type="); pw.print(InsetsState.typeToString(mType));
150 pw.print(" frame="); pw.print(mFrame.toShortString());
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100151 if (mVisibleFrame != null) {
152 pw.print(" visibleFrmae="); pw.print(mVisibleFrame.toShortString());
153 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200154 pw.print(" visible="); pw.print(mVisible);
155 pw.println();
156 }
157
158 @Override
159 public boolean equals(Object o) {
160 if (this == o) return true;
161 if (o == null || getClass() != o.getClass()) return false;
162
163 InsetsSource that = (InsetsSource) o;
164
165 if (mType != that.mType) return false;
166 if (mVisible != that.mVisible) return false;
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100167 if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200168 return mFrame.equals(that.mFrame);
169 }
170
171 @Override
172 public int hashCode() {
173 int result = mType;
174 result = 31 * result + mFrame.hashCode();
Jorim Jaggi4d4fae42020-01-30 23:10:12 +0100175 result = 31 * result + (mVisibleFrame != null ? mVisibleFrame.hashCode() : 0);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200176 result = 31 * result + (mVisible ? 1 : 0);
177 return result;
178 }
179
180 public InsetsSource(Parcel in) {
181 mType = in.readInt();
182 mFrame = in.readParcelable(null /* loader */);
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100183 mVisibleFrame = in.readParcelable(null /* loader */);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200184 mVisible = in.readBoolean();
185 }
186
187 @Override
188 public int describeContents() {
189 return 0;
190 }
191
192 @Override
193 public void writeToParcel(Parcel dest, int flags) {
194 dest.writeInt(mType);
195 dest.writeParcelable(mFrame, 0 /* flags*/);
Jorim Jaggi4e04eb22020-01-09 16:42:14 +0100196 dest.writeParcelable(mVisibleFrame, 0 /* flags */);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200197 dest.writeBoolean(mVisible);
198 }
199
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900200 @Override
201 public String toString() {
202 return "InsetsSource: {"
203 + "mType=" + InsetsState.typeToString(mType)
204 + ", mFrame=" + mFrame.toShortString()
Tiger Huanga16634032020-02-05 17:10:03 +0800205 + ", mVisible=" + mVisible
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900206 + "}";
207 }
208
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700209 public static final @android.annotation.NonNull Creator<InsetsSource> CREATOR = new Creator<InsetsSource>() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200210
211 public InsetsSource createFromParcel(Parcel in) {
212 return new InsetsSource(in);
213 }
214
215 public InsetsSource[] newArray(int size) {
216 return new InsetsSource[size];
217 }
218 };
219}