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