1 /*
2  * Copyright (C) 2020 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 package com.android.quickstep.util;
17 
18 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
19 
20 import android.util.FloatProperty;
21 import android.view.RemoteAnimationTarget;
22 
23 import com.android.quickstep.RemoteAnimationTargets;
24 import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
25 
26 public class TransformParams {
27 
28     public static FloatProperty<TransformParams> PROGRESS =
29             new FloatProperty<TransformParams>("progress") {
30         @Override
31         public void setValue(TransformParams params, float v) {
32             params.setProgress(v);
33         }
34 
35         @Override
36         public Float get(TransformParams params) {
37             return params.getProgress();
38         }
39     };
40 
41     public static FloatProperty<TransformParams> TARGET_ALPHA =
42             new FloatProperty<TransformParams>("targetAlpha") {
43         @Override
44         public void setValue(TransformParams params, float v) {
45             params.setTargetAlpha(v);
46         }
47 
48         @Override
49         public Float get(TransformParams params) {
50             return params.getTargetAlpha();
51         }
52     };
53 
54     /** Progress from 0 to 1 where 0 is in-app and 1 is Overview */
55     private float mProgress;
56     private float mTargetAlpha;
57     private float mCornerRadius;
58     private RemoteAnimationTargets mTargetSet;
59     private SurfaceTransactionApplier mSyncTransactionApplier;
60 
61     private BuilderProxy mHomeBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
62     private BuilderProxy mBaseBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
63 
TransformParams()64     public TransformParams() {
65         mProgress = 0;
66         mTargetAlpha = 1;
67         mCornerRadius = -1;
68     }
69 
70     /**
71      * Sets the progress of the transformation, where 0 is the source and 1 is the target. We
72      * automatically adjust properties such as currentRect and cornerRadius based on this
73      * progress, unless they are manually overridden by setting them on this TransformParams.
74      */
setProgress(float progress)75     public TransformParams setProgress(float progress) {
76         mProgress = progress;
77         return this;
78     }
79 
80     /**
81      * Sets the corner radius of the transformed window, in pixels. If unspecified (-1), we
82      * simply interpolate between the window's corner radius to the task view's corner radius,
83      * based on {@link #mProgress}.
84      */
setCornerRadius(float cornerRadius)85     public TransformParams setCornerRadius(float cornerRadius) {
86         mCornerRadius = cornerRadius;
87         return this;
88     }
89 
90     /**
91      * Specifies the alpha of the transformed window. Default is 1.
92      */
setTargetAlpha(float targetAlpha)93     public TransformParams setTargetAlpha(float targetAlpha) {
94         mTargetAlpha = targetAlpha;
95         return this;
96     }
97 
98     /**
99      * Specifies the set of RemoteAnimationTargetCompats that are included in the transformation
100      * that these TransformParams help compute. These TransformParams generally only apply to
101      * the targetSet.apps which match the targetSet.targetMode (e.g. the MODE_CLOSING app when
102      * swiping to home).
103      */
setTargetSet(RemoteAnimationTargets targetSet)104     public TransformParams setTargetSet(RemoteAnimationTargets targetSet) {
105         mTargetSet = targetSet;
106         return this;
107     }
108 
109     /**
110      * Sets the SyncRtSurfaceTransactionApplierCompat that will apply the SurfaceParams that
111      * are computed based on these TransformParams.
112      */
setSyncTransactionApplier(SurfaceTransactionApplier applier)113     public TransformParams setSyncTransactionApplier(SurfaceTransactionApplier applier) {
114         mSyncTransactionApplier = applier;
115         return this;
116     }
117 
118     /**
119      * Sets an alternate function to control transform for non-target apps. The default
120      * implementation keeps the targets visible with alpha=1
121      */
setBaseBuilderProxy(BuilderProxy proxy)122     public TransformParams setBaseBuilderProxy(BuilderProxy proxy) {
123         mBaseBuilderProxy = proxy;
124         return this;
125     }
126 
127     /**
128      * Sets an alternate function to control transform for home target. The default
129      * implementation keeps the targets visible with alpha=1
130      */
setHomeBuilderProxy(BuilderProxy proxy)131     public TransformParams setHomeBuilderProxy(BuilderProxy proxy) {
132         mHomeBuilderProxy = proxy;
133         return this;
134     }
135 
136     /** Builds the SurfaceTransaction from the given BuilderProxy params. */
createSurfaceParams(BuilderProxy proxy)137     public SurfaceTransaction createSurfaceParams(BuilderProxy proxy) {
138         RemoteAnimationTargets targets = mTargetSet;
139         SurfaceTransaction transaction = new SurfaceTransaction();
140         if (targets == null) {
141             return transaction;
142         }
143         for (int i = 0; i < targets.unfilteredApps.length; i++) {
144             RemoteAnimationTarget app = targets.unfilteredApps[i];
145             SurfaceProperties builder = transaction.forSurface(app.leash);
146 
147             if (app.mode == targets.targetMode) {
148                 int activityType = app.windowConfiguration.getActivityType();
149                 if (activityType == ACTIVITY_TYPE_HOME) {
150                     mHomeBuilderProxy.onBuildTargetParams(builder, app, this);
151                 } else {
152                     builder.setAlpha(getTargetAlpha());
153                     proxy.onBuildTargetParams(builder, app, this);
154                 }
155             } else {
156                 mBaseBuilderProxy.onBuildTargetParams(builder, app, this);
157             }
158         }
159 
160         // always put wallpaper layer to bottom.
161         final int wallpaperLength = targets.wallpapers != null ? targets.wallpapers.length : 0;
162         for (int i = 0; i < wallpaperLength; i++) {
163             RemoteAnimationTarget wallpaper = targets.wallpapers[i];
164             transaction.forSurface(wallpaper.leash).setLayer(Integer.MIN_VALUE);
165         }
166         return transaction;
167     }
168 
169     // Pubic getters so outside packages can read the values.
170 
getProgress()171     public float getProgress() {
172         return mProgress;
173     }
174 
getTargetAlpha()175     public float getTargetAlpha() {
176         return mTargetAlpha;
177     }
178 
getCornerRadius()179     public float getCornerRadius() {
180         return mCornerRadius;
181     }
182 
getTargetSet()183     public RemoteAnimationTargets getTargetSet() {
184         return mTargetSet;
185     }
186 
applySurfaceParams(SurfaceTransaction builder)187     public void applySurfaceParams(SurfaceTransaction builder) {
188         if (mSyncTransactionApplier != null) {
189             mSyncTransactionApplier.scheduleApply(builder);
190         } else {
191             builder.getTransaction().apply();
192         }
193     }
194 
195     @FunctionalInterface
196     public interface BuilderProxy {
197 
198         BuilderProxy NO_OP = (builder, app, params) -> { };
199         BuilderProxy ALWAYS_VISIBLE = (builder, app, params) -> builder.setAlpha(1);
200 
onBuildTargetParams(SurfaceProperties builder, RemoteAnimationTarget app, TransformParams params)201         void onBuildTargetParams(SurfaceProperties builder,
202                 RemoteAnimationTarget app, TransformParams params);
203     }
204 }
205