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