1 /*
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 
17 package android.view;
18 
19 import android.graphics.Insets;
20 import android.graphics.Rect;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.view.InsetsState.InternalInsetType;
24 
25 import java.io.PrintWriter;
26 
27 /**
28  * Represents the state of a single window generating insets for clients.
29  * @hide
30  */
31 public class InsetsSource implements Parcelable {
32 
33     private final @InternalInsetType int mType;
34 
35     /** Frame of the source in screen coordinate space */
36     private final Rect mFrame;
37     private boolean mVisible;
38 
39     private final Rect mTmpFrame = new Rect();
40 
InsetsSource(@nternalInsetType int type)41     public InsetsSource(@InternalInsetType int type) {
42         mType = type;
43         mFrame = new Rect();
44     }
45 
InsetsSource(InsetsSource other)46     public InsetsSource(InsetsSource other) {
47         mType = other.mType;
48         mFrame = new Rect(other.mFrame);
49         mVisible = other.mVisible;
50     }
51 
setFrame(Rect frame)52     public void setFrame(Rect frame) {
53         mFrame.set(frame);
54     }
55 
setVisible(boolean visible)56     public void setVisible(boolean visible) {
57         mVisible = visible;
58     }
59 
getType()60     public @InternalInsetType int getType() {
61         return mType;
62     }
63 
getFrame()64     public Rect getFrame() {
65         return mFrame;
66     }
67 
isVisible()68     public boolean isVisible() {
69         return mVisible;
70     }
71 
72     /**
73      * Calculates the insets this source will cause to a client window.
74      *
75      * @param relativeFrame The frame to calculate the insets relative to.
76      * @param ignoreVisibility If true, always reports back insets even if source isn't visible.
77      * @return The resulting insets. The contract is that only one side will be occupied by a
78      *         source.
79      */
calculateInsets(Rect relativeFrame, boolean ignoreVisibility)80     public Insets calculateInsets(Rect relativeFrame, boolean ignoreVisibility) {
81         if (!ignoreVisibility && !mVisible) {
82             return Insets.NONE;
83         }
84         if (!mTmpFrame.setIntersect(mFrame, relativeFrame)) {
85             return Insets.NONE;
86         }
87 
88         // Intersecting at top/bottom
89         if (mTmpFrame.width() == relativeFrame.width()) {
90             if (mTmpFrame.top == relativeFrame.top) {
91                 return Insets.of(0, mTmpFrame.height(), 0, 0);
92             } else {
93                 return Insets.of(0, 0, 0, mTmpFrame.height());
94             }
95         }
96         // Intersecting at left/right
97         else if (mTmpFrame.height() == relativeFrame.height()) {
98             if (mTmpFrame.left == relativeFrame.left) {
99                 return Insets.of(mTmpFrame.width(), 0, 0, 0);
100             } else {
101                 return Insets.of(0, 0, mTmpFrame.width(), 0);
102             }
103         } else {
104             return Insets.NONE;
105         }
106     }
107 
dump(String prefix, PrintWriter pw)108     public void dump(String prefix, PrintWriter pw) {
109         pw.print(prefix);
110         pw.print("InsetsSource type="); pw.print(InsetsState.typeToString(mType));
111         pw.print(" frame="); pw.print(mFrame.toShortString());
112         pw.print(" visible="); pw.print(mVisible);
113         pw.println();
114     }
115 
116     @Override
equals(Object o)117     public boolean equals(Object o) {
118         if (this == o) return true;
119         if (o == null || getClass() != o.getClass()) return false;
120 
121         InsetsSource that = (InsetsSource) o;
122 
123         if (mType != that.mType) return false;
124         if (mVisible != that.mVisible) return false;
125         return mFrame.equals(that.mFrame);
126     }
127 
128     @Override
hashCode()129     public int hashCode() {
130         int result = mType;
131         result = 31 * result + mFrame.hashCode();
132         result = 31 * result + (mVisible ? 1 : 0);
133         return result;
134     }
135 
InsetsSource(Parcel in)136     public InsetsSource(Parcel in) {
137         mType = in.readInt();
138         mFrame = in.readParcelable(null /* loader */);
139         mVisible = in.readBoolean();
140     }
141 
142     @Override
describeContents()143     public int describeContents() {
144         return 0;
145     }
146 
147     @Override
writeToParcel(Parcel dest, int flags)148     public void writeToParcel(Parcel dest, int flags) {
149         dest.writeInt(mType);
150         dest.writeParcelable(mFrame, 0 /* flags*/);
151         dest.writeBoolean(mVisible);
152     }
153 
154     public static final @android.annotation.NonNull Creator<InsetsSource> CREATOR = new Creator<InsetsSource>() {
155 
156         public InsetsSource createFromParcel(Parcel in) {
157             return new InsetsSource(in);
158         }
159 
160         public InsetsSource[] newArray(int size) {
161             return new InsetsSource[size];
162         }
163     };
164 }
165