2020-02-27 23:34:24 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
2020-03-24 12:41:56 -07:00
|
|
|
package com.android.launcher3.statehandlers;
|
2020-02-27 23:34:24 -08:00
|
|
|
|
|
|
|
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
2020-04-15 15:19:49 -07:00
|
|
|
import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
|
2020-02-27 23:34:24 -08:00
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
import android.os.IBinder;
|
|
|
|
|
import android.util.FloatProperty;
|
2020-02-27 23:34:24 -08:00
|
|
|
import android.view.View;
|
2020-03-24 12:41:56 -07:00
|
|
|
import android.view.ViewTreeObserver;
|
2020-03-06 15:56:46 -08:00
|
|
|
|
2020-02-27 23:34:24 -08:00
|
|
|
import com.android.launcher3.Launcher;
|
|
|
|
|
import com.android.launcher3.LauncherState;
|
|
|
|
|
import com.android.launcher3.R;
|
|
|
|
|
import com.android.launcher3.Utilities;
|
2020-03-13 13:01:33 -07:00
|
|
|
import com.android.launcher3.anim.PendingAnimation;
|
2020-05-08 13:37:58 -07:00
|
|
|
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
2020-03-13 13:01:33 -07:00
|
|
|
import com.android.launcher3.states.StateAnimationConfig;
|
2020-02-27 23:34:24 -08:00
|
|
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
|
|
|
|
import com.android.systemui.shared.system.SurfaceControlCompat;
|
|
|
|
|
import com.android.systemui.shared.system.TransactionCompat;
|
2020-03-17 17:11:32 -07:00
|
|
|
import com.android.systemui.shared.system.WallpaperManagerCompat;
|
2020-02-27 23:34:24 -08:00
|
|
|
|
|
|
|
|
/**
|
2020-03-17 17:11:32 -07:00
|
|
|
* Controls blur and wallpaper zoom, for the Launcher surface only.
|
2020-02-27 23:34:24 -08:00
|
|
|
*/
|
2020-05-08 13:37:58 -07:00
|
|
|
public class DepthController implements StateHandler<LauncherState> {
|
2020-02-27 23:34:24 -08:00
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
public static final FloatProperty<DepthController> DEPTH =
|
|
|
|
|
new FloatProperty<DepthController>("depth") {
|
2020-02-27 23:34:24 -08:00
|
|
|
@Override
|
2020-03-17 17:11:32 -07:00
|
|
|
public void setValue(DepthController depthController, float depth) {
|
|
|
|
|
depthController.setDepth(depth);
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2020-03-17 17:11:32 -07:00
|
|
|
public Float get(DepthController depthController) {
|
|
|
|
|
return depthController.mDepth;
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A property that updates the background blur within a given range of values (ie. even if the
|
|
|
|
|
* animator goes beyond 0..1, the interpolated value will still be bounded).
|
|
|
|
|
*/
|
2020-03-17 17:11:32 -07:00
|
|
|
public static class ClampedDepthProperty extends FloatProperty<DepthController> {
|
|
|
|
|
private final float mMinValue;
|
|
|
|
|
private final float mMaxValue;
|
2020-02-27 23:34:24 -08:00
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
public ClampedDepthProperty(float minValue, float maxValue) {
|
|
|
|
|
super("depthClamped");
|
2020-02-27 23:34:24 -08:00
|
|
|
mMinValue = minValue;
|
|
|
|
|
mMaxValue = maxValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2020-03-17 17:11:32 -07:00
|
|
|
public void setValue(DepthController depthController, float depth) {
|
|
|
|
|
depthController.setDepth(Utilities.boundToRange(depth, mMinValue, mMaxValue));
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2020-03-17 17:11:32 -07:00
|
|
|
public Float get(DepthController depthController) {
|
|
|
|
|
return depthController.mDepth;
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 12:41:56 -07:00
|
|
|
private final ViewTreeObserver.OnDrawListener mOnDrawListener =
|
|
|
|
|
new ViewTreeObserver.OnDrawListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onDraw() {
|
|
|
|
|
View view = mLauncher.getDragLayer();
|
|
|
|
|
setSurface(new SurfaceControlCompat(view));
|
|
|
|
|
view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-02-27 23:34:24 -08:00
|
|
|
private final Launcher mLauncher;
|
2020-03-17 17:11:32 -07:00
|
|
|
/**
|
|
|
|
|
* Blur radius when completely zoomed out, in pixels.
|
|
|
|
|
*/
|
|
|
|
|
private int mMaxBlurRadius;
|
|
|
|
|
private WallpaperManagerCompat mWallpaperManager;
|
2020-02-27 23:34:24 -08:00
|
|
|
private SurfaceControlCompat mSurface;
|
2020-03-17 17:11:32 -07:00
|
|
|
/**
|
|
|
|
|
* Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
|
|
|
|
|
* @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
|
|
|
|
|
*/
|
|
|
|
|
private float mDepth;
|
2020-02-27 23:34:24 -08:00
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
public DepthController(Launcher l) {
|
2020-02-27 23:34:24 -08:00
|
|
|
mLauncher = l;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
private void ensureDependencies() {
|
|
|
|
|
if (mWallpaperManager != null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
|
|
|
|
|
mWallpaperManager = new WallpaperManagerCompat(mLauncher);
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-03-24 12:41:56 -07:00
|
|
|
* Sets if the underlying activity is started or not
|
2020-02-27 23:34:24 -08:00
|
|
|
*/
|
2020-03-24 12:41:56 -07:00
|
|
|
public void setActivityStarted(boolean isStarted) {
|
|
|
|
|
if (isStarted) {
|
|
|
|
|
mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
|
|
|
|
|
} else {
|
|
|
|
|
mLauncher.getDragLayer().getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
|
|
|
|
|
setSurface(null);
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-03-24 12:41:56 -07:00
|
|
|
* Sets the specified app target surface to apply the blur to.
|
2020-02-27 23:34:24 -08:00
|
|
|
*/
|
2020-03-24 12:41:56 -07:00
|
|
|
public void setSurfaceToApp(RemoteAnimationTargetCompat target) {
|
|
|
|
|
if (target != null) {
|
|
|
|
|
setSurface(target.leash);
|
|
|
|
|
} else {
|
|
|
|
|
setActivityStarted(mLauncher.isStarted());
|
|
|
|
|
}
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setSurface(SurfaceControlCompat surface) {
|
|
|
|
|
if (mSurface != surface) {
|
|
|
|
|
mSurface = surface;
|
|
|
|
|
if (surface != null) {
|
2020-03-17 17:11:32 -07:00
|
|
|
setDepth(mDepth);
|
2020-02-27 23:34:24 -08:00
|
|
|
} else {
|
2020-03-17 17:11:32 -07:00
|
|
|
// If there is no surface, then reset the ratio
|
|
|
|
|
setDepth(0f);
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setState(LauncherState toState) {
|
|
|
|
|
if (mSurface == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
float toDepth = toState.getDepth(mLauncher);
|
|
|
|
|
if (Float.compare(mDepth, toDepth) != 0) {
|
|
|
|
|
setDepth(toDepth);
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2020-03-13 13:01:33 -07:00
|
|
|
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
|
|
|
|
|
PendingAnimation animation) {
|
2020-04-15 15:19:49 -07:00
|
|
|
if (mSurface == null
|
|
|
|
|
|| config.onlyPlayAtomicComponent()
|
|
|
|
|
|| config.hasAnimationFlag(SKIP_DEPTH_CONTROLLER)) {
|
2020-02-27 23:34:24 -08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
float toDepth = toState.getDepth(mLauncher);
|
|
|
|
|
if (Float.compare(mDepth, toDepth) != 0) {
|
|
|
|
|
animation.setFloat(this, DEPTH, toDepth, LINEAR);
|
2020-02-27 23:34:24 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 17:11:32 -07:00
|
|
|
private void setDepth(float depth) {
|
2020-04-17 16:16:44 -07:00
|
|
|
// Round out the depth to dedupe frequent, non-perceptable updates
|
|
|
|
|
int depthI = (int) (depth * 256);
|
|
|
|
|
float depthF = depthI / 256f;
|
|
|
|
|
if (Float.compare(mDepth, depthF) == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mDepth = depthF;
|
2020-02-27 23:34:24 -08:00
|
|
|
if (mSurface == null || !mSurface.isValid()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-03-17 17:11:32 -07:00
|
|
|
ensureDependencies();
|
|
|
|
|
IBinder windowToken = mLauncher.getRootView().getWindowToken();
|
|
|
|
|
if (windowToken != null) {
|
|
|
|
|
mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
|
|
|
|
|
}
|
2020-04-29 10:40:58 -07:00
|
|
|
final int blur;
|
|
|
|
|
if (mLauncher.isInState(LauncherState.ALL_APPS) && mDepth == 1) {
|
|
|
|
|
// All apps has a solid background. We don't need to draw blurs after it's fully
|
|
|
|
|
// visible. This will take us out of GPU composition, saving battery and increasing
|
|
|
|
|
// performance.
|
|
|
|
|
blur = 0;
|
|
|
|
|
} else {
|
|
|
|
|
blur = (int) (mDepth * mMaxBlurRadius);
|
|
|
|
|
}
|
2020-02-27 23:34:24 -08:00
|
|
|
new TransactionCompat()
|
2020-04-29 10:40:58 -07:00
|
|
|
.setBackgroundBlurRadius(mSurface, blur)
|
2020-02-27 23:34:24 -08:00
|
|
|
.apply();
|
|
|
|
|
}
|
|
|
|
|
}
|