• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.window;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.graphics.Matrix;
22 import android.graphics.PointF;
23 import android.graphics.Rect;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.view.SurfaceControl;
27 
28 import java.util.Arrays;
29 import java.util.Objects;
30 
31 /**
32  * Represents a set of {@link android.view.SurfaceControl.Transaction} operations used to
33  * operate on the {@link android.view.SurfaceControl} for picture-in-picture.
34  *
35  * @hide
36  */
37 public final class PictureInPictureSurfaceTransaction implements Parcelable {
38     private static final float NOT_SET = -1f;
39 
40     public final float mAlpha;
41     public final PointF mPosition;
42 
43     public final float[] mFloat9;
44 
45     // Though this can be determined by mFloat9, it's easier to set the value directly
46     public final float mRotation;
47 
48     public final float mCornerRadius;
49 
50     public final float mShadowRadius;
51 
52     private final Rect mWindowCrop;
53 
54     private boolean mShouldDisableCanAffectSystemUiFlags;
55 
PictureInPictureSurfaceTransaction(Parcel in)56     private PictureInPictureSurfaceTransaction(Parcel in) {
57         mAlpha = in.readFloat();
58         mPosition = in.readTypedObject(PointF.CREATOR);
59         mFloat9 = new float[9];
60         in.readFloatArray(mFloat9);
61         mRotation = in.readFloat();
62         mCornerRadius = in.readFloat();
63         mShadowRadius = in.readFloat();
64         mWindowCrop = in.readTypedObject(Rect.CREATOR);
65         mShouldDisableCanAffectSystemUiFlags = in.readBoolean();
66     }
67 
PictureInPictureSurfaceTransaction(float alpha, @Nullable PointF position, @Nullable float[] float9, float rotation, float cornerRadius, float shadowRadius, @Nullable Rect windowCrop)68     private PictureInPictureSurfaceTransaction(float alpha, @Nullable PointF position,
69             @Nullable float[] float9, float rotation, float cornerRadius, float shadowRadius,
70             @Nullable Rect windowCrop) {
71         mAlpha = alpha;
72         mPosition = position;
73         if (float9 == null) {
74             mFloat9 = new float[9];
75             Matrix.IDENTITY_MATRIX.getValues(mFloat9);
76             mRotation = 0;
77         } else {
78             mFloat9 = Arrays.copyOf(float9, 9);
79             mRotation = rotation;
80         }
81         mCornerRadius = cornerRadius;
82         mShadowRadius = shadowRadius;
83         mWindowCrop = (windowCrop == null) ? null : new Rect(windowCrop);
84     }
85 
PictureInPictureSurfaceTransaction(PictureInPictureSurfaceTransaction other)86     public PictureInPictureSurfaceTransaction(PictureInPictureSurfaceTransaction other) {
87         this(other.mAlpha, other.mPosition,
88                 other.mFloat9, other.mRotation, other.mCornerRadius, other.mShadowRadius,
89                 other.mWindowCrop);
90         mShouldDisableCanAffectSystemUiFlags = other.mShouldDisableCanAffectSystemUiFlags;
91     }
92 
93     /** @return {@link Matrix} from {@link #mFloat9} */
getMatrix()94     public Matrix getMatrix() {
95         final Matrix matrix = new Matrix();
96         matrix.setValues(mFloat9);
97         return matrix;
98     }
99 
100     /** @return {@code true} if this transaction contains setting corner radius. */
hasCornerRadiusSet()101     public boolean hasCornerRadiusSet() {
102         return mCornerRadius > 0;
103     }
104 
105     /** @return {@code true} if this transaction contains setting shadow radius. */
hasShadowRadiusSet()106     public boolean hasShadowRadiusSet() {
107         return mShadowRadius > 0;
108     }
109 
110     /** Sets the internal {@link #mShouldDisableCanAffectSystemUiFlags}. */
setShouldDisableCanAffectSystemUiFlags(boolean shouldDisable)111     public void setShouldDisableCanAffectSystemUiFlags(boolean shouldDisable) {
112         mShouldDisableCanAffectSystemUiFlags = shouldDisable;
113     }
114 
115     /** @return {@code true} if we should disable Task#setCanAffectSystemUiFlags. */
getShouldDisableCanAffectSystemUiFlags()116     public boolean getShouldDisableCanAffectSystemUiFlags() {
117         return mShouldDisableCanAffectSystemUiFlags;
118     }
119 
120     @Override
equals(Object o)121     public boolean equals(Object o) {
122         if (this == o) return true;
123         if (!(o instanceof PictureInPictureSurfaceTransaction)) return false;
124         PictureInPictureSurfaceTransaction that = (PictureInPictureSurfaceTransaction) o;
125         return Objects.equals(mAlpha, that.mAlpha)
126                 && Objects.equals(mPosition, that.mPosition)
127                 && Arrays.equals(mFloat9, that.mFloat9)
128                 && Objects.equals(mRotation, that.mRotation)
129                 && Objects.equals(mCornerRadius, that.mCornerRadius)
130                 && Objects.equals(mShadowRadius, that.mShadowRadius)
131                 && Objects.equals(mWindowCrop, that.mWindowCrop)
132                 && mShouldDisableCanAffectSystemUiFlags
133                 == that.mShouldDisableCanAffectSystemUiFlags;
134     }
135 
136     @Override
hashCode()137     public int hashCode() {
138         return Objects.hash(mAlpha, mPosition, Arrays.hashCode(mFloat9),
139                 mRotation, mCornerRadius, mShadowRadius, mWindowCrop,
140                 mShouldDisableCanAffectSystemUiFlags);
141     }
142 
143     @Override
describeContents()144     public int describeContents() {
145         return 0;
146     }
147 
148     @Override
writeToParcel(Parcel out, int flags)149     public void writeToParcel(Parcel out, int flags) {
150         out.writeFloat(mAlpha);
151         out.writeTypedObject(mPosition, 0 /* flags */);
152         out.writeFloatArray(mFloat9);
153         out.writeFloat(mRotation);
154         out.writeFloat(mCornerRadius);
155         out.writeFloat(mShadowRadius);
156         out.writeTypedObject(mWindowCrop, 0 /* flags */);
157         out.writeBoolean(mShouldDisableCanAffectSystemUiFlags);
158     }
159 
160     @Override
toString()161     public String toString() {
162         final Matrix matrix = getMatrix();
163         return "PictureInPictureSurfaceTransaction("
164                 + " alpha=" + mAlpha
165                 + " position=" + mPosition
166                 + " matrix=" + matrix.toShortString()
167                 + " rotation=" + mRotation
168                 + " cornerRadius=" + mCornerRadius
169                 + " shadowRadius=" + mShadowRadius
170                 + " crop=" + mWindowCrop
171                 + " shouldDisableCanAffectSystemUiFlags" + mShouldDisableCanAffectSystemUiFlags
172                 + ")";
173     }
174 
175     /** Applies {@link PictureInPictureSurfaceTransaction} to a given leash. */
apply(@onNull PictureInPictureSurfaceTransaction surfaceTransaction, @NonNull SurfaceControl surfaceControl, @NonNull SurfaceControl.Transaction tx)176     public static void apply(@NonNull PictureInPictureSurfaceTransaction surfaceTransaction,
177             @NonNull SurfaceControl surfaceControl,
178             @NonNull SurfaceControl.Transaction tx) {
179         final Matrix matrix = surfaceTransaction.getMatrix();
180         tx.setMatrix(surfaceControl, matrix, new float[9]);
181         if (surfaceTransaction.mPosition != null) {
182             tx.setPosition(surfaceControl,
183                     surfaceTransaction.mPosition.x, surfaceTransaction.mPosition.y);
184         }
185         if (surfaceTransaction.mWindowCrop != null) {
186             tx.setWindowCrop(surfaceControl, surfaceTransaction.mWindowCrop);
187         }
188         if (surfaceTransaction.hasCornerRadiusSet()) {
189             tx.setCornerRadius(surfaceControl, surfaceTransaction.mCornerRadius);
190         }
191         if (surfaceTransaction.hasShadowRadiusSet()) {
192             tx.setShadowRadius(surfaceControl, surfaceTransaction.mShadowRadius);
193         }
194         if (surfaceTransaction.mAlpha != NOT_SET) {
195             tx.setAlpha(surfaceControl, surfaceTransaction.mAlpha);
196         }
197     }
198 
199     public static final @android.annotation.NonNull Creator<PictureInPictureSurfaceTransaction>
200             CREATOR =
201             new Creator<PictureInPictureSurfaceTransaction>() {
202                 public PictureInPictureSurfaceTransaction createFromParcel(Parcel in) {
203                     return new PictureInPictureSurfaceTransaction(in);
204                 }
205                 public PictureInPictureSurfaceTransaction[] newArray(int size) {
206                     return new PictureInPictureSurfaceTransaction[size];
207                 }
208             };
209 
210     public static class Builder {
211         private float mAlpha = NOT_SET;
212         private PointF mPosition;
213         private float[] mFloat9;
214         private float mRotation;
215         private float mCornerRadius = NOT_SET;
216         private float mShadowRadius = NOT_SET;
217         private Rect mWindowCrop;
218 
setAlpha(float alpha)219         public Builder setAlpha(float alpha) {
220             mAlpha = alpha;
221             return this;
222         }
223 
setPosition(float x, float y)224         public Builder setPosition(float x, float y) {
225             mPosition = new PointF(x, y);
226             return this;
227         }
228 
setTransform(@onNull float[] float9, float rotation)229         public Builder setTransform(@NonNull float[] float9, float rotation) {
230             mFloat9 = Arrays.copyOf(float9, 9);
231             mRotation = rotation;
232             return this;
233         }
234 
setCornerRadius(float cornerRadius)235         public Builder setCornerRadius(float cornerRadius) {
236             mCornerRadius = cornerRadius;
237             return this;
238         }
239 
setShadowRadius(float shadowRadius)240         public Builder setShadowRadius(float shadowRadius) {
241             mShadowRadius = shadowRadius;
242             return this;
243         }
244 
setWindowCrop(@onNull Rect windowCrop)245         public Builder setWindowCrop(@NonNull Rect windowCrop) {
246             mWindowCrop = new Rect(windowCrop);
247             return this;
248         }
249 
build()250         public PictureInPictureSurfaceTransaction build() {
251             return new PictureInPictureSurfaceTransaction(mAlpha, mPosition,
252                     mFloat9, mRotation, mCornerRadius, mShadowRadius, mWindowCrop);
253         }
254     }
255 }
256