blob: 6ee341dd974c74263a2582b7299b5072d0422bf6 [file] [log] [blame]
/*
* Copyright (C) 2018 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.
*/
package com.android.systemui.wallpaper;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.util.AttributeSet;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
import android.widget.ImageView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.phone.ScrimState;
/**
* A view that draws mask upon either image wallpaper or music album art in AOD.
*/
public class AodMaskView extends ImageView implements StatusBarStateController.StateListener,
ImageWallpaperTransformer.TransformationListener {
private static final String TAG = AodMaskView.class.getSimpleName();
private static final int TRANSITION_DURATION = 1000;
private static final AnimatableProperty TRANSITION_PROGRESS = AnimatableProperty.from(
"transition_progress",
AodMaskView::setTransitionAmount,
AodMaskView::getTransitionAmount,
R.id.aod_mask_transition_progress_tag,
R.id.aod_mask_transition_progress_start_tag,
R.id.aod_mask_transition_progress_end_tag
);
private final AnimationProperties mTransitionProperties = new AnimationProperties();
private final ImageWallpaperTransformer mTransformer;
private final RectF mBounds = new RectF();
private boolean mChangingStates;
private boolean mNeedMask;
private float mTransitionAmount;
private final WallpaperManager mWallpaperManager;
private final DisplayManager mDisplayManager;
private DisplayListener mDisplayListener = new DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
}
@Override
public void onDisplayRemoved(int displayId) {
}
@Override
public void onDisplayChanged(int displayId) {
// We just support DEFAULT_DISPLAY currently.
if (displayId == Display.DEFAULT_DISPLAY) {
mTransformer.updateDisplayInfo(getDisplayInfo(displayId));
}
}
};
public AodMaskView(Context context) {
this(context, null);
}
public AodMaskView(Context context, AttributeSet attrs) {
this(context, attrs, null);
}
@VisibleForTesting
public AodMaskView(Context context, AttributeSet attrs, ImageWallpaperTransformer transformer) {
super(context, attrs);
setClickable(false);
StatusBarStateController controller = Dependency.get(StatusBarStateController.class);
if (controller != null) {
controller.addCallback(this);
} else {
Log.d(TAG, "Can not get StatusBarStateController!");
}
mDisplayManager = (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(mDisplayListener, null);
mWallpaperManager =
(WallpaperManager) getContext().getSystemService(Context.WALLPAPER_SERVICE);
if (transformer == null) {
mTransformer = new ImageWallpaperTransformer(this);
mTransformer.addFilter(new ScrimFilter());
mTransformer.addFilter(new VignetteFilter());
mTransformer.updateOffsets();
mTransformer.updateDisplayInfo(getDisplayInfo(Display.DEFAULT_DISPLAY));
mTransitionProperties.setDuration(TRANSITION_DURATION);
mTransitionProperties.setAnimationFinishListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mTransformer.setIsTransiting(false);
}
@Override
public void onAnimationStart(Animator animation) {
mTransformer.setIsTransiting(true);
}
});
} else {
// This part should only be hit by test cases.
mTransformer = transformer;
}
}
private DisplayInfo getDisplayInfo(int displayId) {
DisplayInfo displayInfo = new DisplayInfo();
mDisplayManager.getDisplay(displayId).getDisplayInfo(displayInfo);
return displayInfo;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBounds.set(0, 0, w, h);
mTransformer.updateOffsets();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mNeedMask) {
mTransformer.drawTransformedImage(canvas, null /* target */, null /* src */, mBounds);
}
}
private boolean checkIfNeedMask() {
// We need mask for ImageWallpaper / LockScreen Wallpaper (Music album art).
return mWallpaperManager.getWallpaperInfo() == null || ScrimState.AOD.hasBackdrop();
}
@Override
public void onStatePreChange(int oldState, int newState) {
mChangingStates = oldState != newState;
mNeedMask = checkIfNeedMask();
}
@Override
public void onStatePostChange() {
mChangingStates = false;
}
@Override
public void onStateChanged(int newState) {
}
@Override
public void onDozingChanged(boolean isDozing) {
if (!mNeedMask) {
return;
}
boolean enabled = checkFeatureIsEnabled();
mTransformer.updateAmbientModeState(enabled && isDozing);
if (enabled && !mChangingStates) {
setAnimatorProperty(isDozing);
} else {
invalidate();
}
}
private boolean checkFeatureIsEnabled() {
return FeatureFlagUtils.isEnabled(
getContext(), FeatureFlagUtils.AOD_IMAGEWALLPAPER_ENABLED);
}
@VisibleForTesting
void setAnimatorProperty(boolean isDozing) {
PropertyAnimator.setProperty(
this,
TRANSITION_PROGRESS,
isDozing ? 1f : 0f /* newEndValue */,
mTransitionProperties,
true /* animated */);
}
@Override
public void onTransformationUpdated() {
invalidate();
}
private void setTransitionAmount(float amount) {
mTransitionAmount = amount;
mTransformer.updateTransitionAmount(amount);
}
private float getTransitionAmount() {
return mTransitionAmount;
}
}