• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.graphics.PointProto.X;
20 import static android.graphics.PointProto.Y;
21 import static android.view.InsetsSourceControlProto.LEASH;
22 import static android.view.InsetsSourceControlProto.POSITION;
23 import static android.view.InsetsSourceControlProto.TYPE;
24 
25 import android.annotation.Nullable;
26 import android.graphics.Insets;
27 import android.graphics.Point;
28 import android.os.Parcel;
29 import android.os.Parcelable;
30 import android.util.proto.ProtoOutputStream;
31 import android.view.InsetsState.InternalInsetsType;
32 
33 import java.io.PrintWriter;
34 import java.util.Objects;
35 import java.util.function.Consumer;
36 
37 /**
38  * Represents a parcelable object to allow controlling a single {@link InsetsSource}.
39  * @hide
40  */
41 public class InsetsSourceControl implements Parcelable {
42 
43     private final @InternalInsetsType int mType;
44     private final @Nullable SurfaceControl mLeash;
45     private final boolean mInitiallyVisible;
46     private final Point mSurfacePosition;
47 
48     // This is used while playing an insets animation regardless of the relative frame. This would
49     // be the insets received by the bounds of its source window.
50     private Insets mInsetsHint;
51 
52     private boolean mSkipAnimationOnce;
53     private int mParcelableFlags;
54 
InsetsSourceControl(@nternalInsetsType int type, @Nullable SurfaceControl leash, boolean initiallyVisible, Point surfacePosition, Insets insetsHint)55     public InsetsSourceControl(@InternalInsetsType int type, @Nullable SurfaceControl leash,
56             boolean initiallyVisible, Point surfacePosition, Insets insetsHint) {
57         mType = type;
58         mLeash = leash;
59         mInitiallyVisible = initiallyVisible;
60         mSurfacePosition = surfacePosition;
61         mInsetsHint = insetsHint;
62     }
63 
InsetsSourceControl(InsetsSourceControl other)64     public InsetsSourceControl(InsetsSourceControl other) {
65         mType = other.mType;
66         if (other.mLeash != null) {
67             mLeash = new SurfaceControl(other.mLeash, "InsetsSourceControl");
68         } else {
69             mLeash = null;
70         }
71         mInitiallyVisible = other.mInitiallyVisible;
72         mSurfacePosition = new Point(other.mSurfacePosition);
73         mInsetsHint = other.mInsetsHint;
74         mSkipAnimationOnce = other.getAndClearSkipAnimationOnce();
75     }
76 
InsetsSourceControl(Parcel in)77     public InsetsSourceControl(Parcel in) {
78         mType = in.readInt();
79         mLeash = in.readTypedObject(SurfaceControl.CREATOR);
80         mInitiallyVisible = in.readBoolean();
81         mSurfacePosition = in.readTypedObject(Point.CREATOR);
82         mInsetsHint = in.readTypedObject(Insets.CREATOR);
83         mSkipAnimationOnce = in.readBoolean();
84     }
85 
getType()86     public int getType() {
87         return mType;
88     }
89 
90     /**
91      * Gets the leash for controlling insets source. If the system is controlling the insets source,
92      * for example, transient bars, the client will receive fake controls without leash in it.
93      *
94      * @return the leash.
95      */
getLeash()96     public @Nullable SurfaceControl getLeash() {
97         return mLeash;
98     }
99 
isInitiallyVisible()100     public boolean isInitiallyVisible() {
101         return mInitiallyVisible;
102     }
103 
setSurfacePosition(int left, int top)104     public boolean setSurfacePosition(int left, int top) {
105         if (mSurfacePosition.equals(left, top)) {
106             return false;
107         }
108         mSurfacePosition.set(left, top);
109         return true;
110     }
111 
getSurfacePosition()112     public Point getSurfacePosition() {
113         return mSurfacePosition;
114     }
115 
setInsetsHint(Insets insets)116     public void setInsetsHint(Insets insets) {
117         mInsetsHint = insets;
118     }
119 
setInsetsHint(int left, int top, int right, int bottom)120     public void setInsetsHint(int left, int top, int right, int bottom) {
121         mInsetsHint = Insets.of(left, top, right, bottom);
122     }
123 
getInsetsHint()124     public Insets getInsetsHint() {
125         return mInsetsHint;
126     }
127 
setSkipAnimationOnce(boolean skipAnimation)128     public void setSkipAnimationOnce(boolean skipAnimation) {
129         mSkipAnimationOnce = skipAnimation;
130     }
131 
132     /**
133      * Get the state whether the current control needs to skip animation or not.
134      *
135      * Note that this is a one-time check that the state is only valid and can be called when
136      * {@link InsetsController#applyAnimation} to check if the current control can skip animation
137      * at this time, and then will clear the state value.
138      */
getAndClearSkipAnimationOnce()139     public boolean getAndClearSkipAnimationOnce() {
140         final boolean result = mSkipAnimationOnce;
141         mSkipAnimationOnce = false;
142         return result;
143     }
144 
setParcelableFlags(int parcelableFlags)145     public void setParcelableFlags(int parcelableFlags) {
146         mParcelableFlags = parcelableFlags;
147     }
148 
149     @Override
describeContents()150     public int describeContents() {
151         return 0;
152     }
153 
154     @Override
writeToParcel(Parcel dest, int flags)155     public void writeToParcel(Parcel dest, int flags) {
156         dest.writeInt(mType);
157         dest.writeTypedObject(mLeash, mParcelableFlags);
158         dest.writeBoolean(mInitiallyVisible);
159         dest.writeTypedObject(mSurfacePosition, mParcelableFlags);
160         dest.writeTypedObject(mInsetsHint, mParcelableFlags);
161         dest.writeBoolean(mSkipAnimationOnce);
162     }
163 
release(Consumer<SurfaceControl> surfaceReleaseConsumer)164     public void release(Consumer<SurfaceControl> surfaceReleaseConsumer) {
165         if (mLeash != null) {
166             surfaceReleaseConsumer.accept(mLeash);
167         }
168     }
169 
170     @Override
equals(@ullable Object o)171     public boolean equals(@Nullable Object o) {
172         if (this == o) {
173             return true;
174         }
175         if (o == null || getClass() != o.getClass()) {
176             return false;
177         }
178         final InsetsSourceControl that = (InsetsSourceControl) o;
179         final SurfaceControl thatLeash = that.mLeash;
180         return mType == that.mType
181                 && ((mLeash == thatLeash)
182                         || (mLeash != null && thatLeash != null && mLeash.isSameSurface(thatLeash)))
183                 && mInitiallyVisible == that.mInitiallyVisible
184                 && mSurfacePosition.equals(that.mSurfacePosition)
185                 && mInsetsHint.equals(that.mInsetsHint)
186                 && mSkipAnimationOnce == that.mSkipAnimationOnce;
187     }
188 
189     @Override
hashCode()190     public int hashCode() {
191         return Objects.hash(mType, mLeash, mInitiallyVisible, mSurfacePosition, mInsetsHint,
192                 mSkipAnimationOnce);
193     }
194 
195     @Override
toString()196     public String toString() {
197         return "InsetsSourceControl: {"
198                 + "type=" + InsetsState.typeToString(mType)
199                 + ", mSurfacePosition=" + mSurfacePosition
200                 + ", mInsetsHint=" + mInsetsHint
201                 + "}";
202     }
203 
dump(String prefix, PrintWriter pw)204     public void dump(String prefix, PrintWriter pw) {
205         pw.print(prefix);
206         pw.print("InsetsSourceControl type="); pw.print(InsetsState.typeToString(mType));
207         pw.print(" mLeash="); pw.print(mLeash);
208         pw.print(" mInitiallyVisible="); pw.print(mInitiallyVisible);
209         pw.print(" mSurfacePosition="); pw.print(mSurfacePosition);
210         pw.print(" mInsetsHint="); pw.print(mInsetsHint);
211         pw.print(" mSkipAnimationOnce="); pw.print(mSkipAnimationOnce);
212         pw.println();
213     }
214 
215     public static final @android.annotation.NonNull Creator<InsetsSourceControl> CREATOR
216             = new Creator<InsetsSourceControl>() {
217         public InsetsSourceControl createFromParcel(Parcel in) {
218             return new InsetsSourceControl(in);
219         }
220 
221         public InsetsSourceControl[] newArray(int size) {
222             return new InsetsSourceControl[size];
223         }
224     };
225 
226     /**
227      * Export the state of {@link InsetsSourceControl} into a protocol buffer output stream.
228      *
229      * @param proto   Stream to write the state to
230      * @param fieldId FieldId of InsetsSource as defined in the parent message
231      */
dumpDebug(ProtoOutputStream proto, long fieldId)232     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
233         final long token = proto.start(fieldId);
234         proto.write(TYPE, InsetsState.typeToString(mType));
235 
236         final long surfaceToken = proto.start(POSITION);
237         proto.write(X, mSurfacePosition.x);
238         proto.write(Y, mSurfacePosition.y);
239         proto.end(surfaceToken);
240 
241         if (mLeash != null) {
242             mLeash.dumpDebug(proto, LEASH);
243         }
244         proto.end(token);
245     }
246 }
247