Merge "Enable AOD image wallpaper and apply aod mask view."
This commit is contained in:
@@ -22,7 +22,9 @@ import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Util class to get feature flag information.
|
||||
@@ -37,8 +39,11 @@ public class FeatureFlagUtils {
|
||||
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
|
||||
public static final String SAFETY_HUB = "settings_safety_hub";
|
||||
public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
|
||||
public static final String AOD_IMAGEWALLPAPER_ENABLED = "settings_aod_imagewallpaper_enabled";
|
||||
|
||||
private static final Map<String, String> DEFAULT_FLAGS;
|
||||
private static final Set<String> OBSERVABLE_FLAGS;
|
||||
|
||||
static {
|
||||
DEFAULT_FLAGS = new HashMap<>();
|
||||
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
|
||||
@@ -54,6 +59,10 @@ public class FeatureFlagUtils {
|
||||
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
|
||||
DEFAULT_FLAGS.put(SAFETY_HUB, "false");
|
||||
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
|
||||
DEFAULT_FLAGS.put(AOD_IMAGEWALLPAPER_ENABLED, "false");
|
||||
|
||||
OBSERVABLE_FLAGS = new HashSet<>();
|
||||
OBSERVABLE_FLAGS.add(AOD_IMAGEWALLPAPER_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,6 +99,16 @@ public class FeatureFlagUtils {
|
||||
*/
|
||||
public static void setEnabled(Context context, String feature, boolean enabled) {
|
||||
SystemProperties.set(FFLAG_OVERRIDE_PREFIX + feature, enabled ? "true" : "false");
|
||||
|
||||
// Also update Settings.Global if needed so that we can observe it via observer.
|
||||
if (OBSERVABLE_FLAGS.contains(feature)) {
|
||||
setObservableFlag(context, feature, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setObservableFlag(Context context, String feature, boolean enabled) {
|
||||
Settings.Global.putString(
|
||||
context.getContentResolver(), feature, enabled ? "true" : "false");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,6 +43,14 @@
|
||||
android:visibility="invisible" />
|
||||
</com.android.systemui.statusbar.BackDropView>
|
||||
|
||||
<com.android.systemui.wallpaper.AodMaskView
|
||||
android:id="@+id/aod_mask"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
android:visibility="invisible"
|
||||
sysui:ignoreRightInset="true" />
|
||||
|
||||
<com.android.systemui.statusbar.ScrimView
|
||||
android:id="@+id/scrim_behind"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -109,5 +109,10 @@
|
||||
|
||||
<!-- Optional cancel button on Keyguard -->
|
||||
<item type="id" name="cancel_button"/>
|
||||
|
||||
<!-- AodMaskView transition tag -->
|
||||
<item type="id" name="aod_mask_transition_progress_tag" />
|
||||
<item type="id" name="aod_mask_transition_progress_end_tag" />
|
||||
<item type="id" name="aod_mask_transition_progress_start_tag" />
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -219,6 +219,14 @@ public enum ScrimState {
|
||||
public void prepare(ScrimState previousState) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if lockscreen wallpaper or music album art exists.
|
||||
* @return true if lockscreen wallpaper or music album art exists.
|
||||
*/
|
||||
public boolean hasBackdrop() {
|
||||
return mHasBackdrop;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
@@ -98,6 +99,7 @@ import android.service.dreams.IDreamManager;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.EventLog;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.Display;
|
||||
@@ -478,8 +480,13 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
WallpaperInfo info = wallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
|
||||
final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
|
||||
final boolean aodImageWallpaperEnabled = FeatureFlagUtils.isEnabled(mContext,
|
||||
FeatureFlagUtils.AOD_IMAGEWALLPAPER_ENABLED);
|
||||
updateAodMaskVisibility(deviceSupportsAodWallpaper && aodImageWallpaperEnabled);
|
||||
// If WallpaperInfo is null, it must be ImageWallpaper.
|
||||
final boolean supportsAmbientMode = deviceSupportsAodWallpaper
|
||||
&& info != null && info.supportsAmbientMode();
|
||||
&& (info == null && aodImageWallpaperEnabled
|
||||
|| info != null && info.supportsAmbientMode());
|
||||
|
||||
mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
|
||||
mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
|
||||
@@ -581,6 +588,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
protected NotificationPresenter mPresenter;
|
||||
private NotificationActivityStarter mNotificationActivityStarter;
|
||||
private boolean mPulsing;
|
||||
private ContentObserver mFeatureFlagObserver;
|
||||
|
||||
@Override
|
||||
public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
|
||||
@@ -697,6 +705,9 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mContext.registerReceiverAsUser(mWallpaperChangedReceiver, UserHandle.ALL,
|
||||
wallpaperChangedFilter, null /* broadcastPermission */, null /* scheduler */);
|
||||
mWallpaperChangedReceiver.onReceive(mContext, null);
|
||||
mFeatureFlagObserver = new FeatureFlagObserver(
|
||||
FeatureFlagUtils.AOD_IMAGEWALLPAPER_ENABLED /* feature */,
|
||||
() -> mWallpaperChangedReceiver.onReceive(mContext, null) /* callback */);
|
||||
|
||||
// Set up the initial notification state. This needs to happen before CommandQueue.disable()
|
||||
setUpPresenter();
|
||||
@@ -4415,4 +4426,33 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
public @TransitionMode int getStatusBarMode() {
|
||||
return mStatusBarMode;
|
||||
}
|
||||
|
||||
private void updateAodMaskVisibility(boolean supportsAodWallpaper) {
|
||||
View mask = mStatusBarWindow.findViewById(R.id.aod_mask);
|
||||
if (mask != null) {
|
||||
mask.setVisibility(supportsAodWallpaper ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private final class FeatureFlagObserver extends ContentObserver {
|
||||
private final Runnable mCallback;
|
||||
|
||||
FeatureFlagObserver(String feature, Runnable callback) {
|
||||
this(null, feature, callback);
|
||||
}
|
||||
|
||||
private FeatureFlagObserver(Handler handler, String feature, Runnable callback) {
|
||||
super(handler);
|
||||
mCallback = callback;
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(feature), false, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
if (mCallback != null) {
|
||||
mStatusBarWindow.post(mCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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.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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.ValueAnimator;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
/**
|
||||
* Abstract filter used by static image wallpaper.
|
||||
*/
|
||||
abstract class ImageWallpaperFilter {
|
||||
protected static final boolean DEBUG = false;
|
||||
|
||||
private ImageWallpaperTransformer mTransformer;
|
||||
|
||||
/**
|
||||
* Apply this filter to the bitmap before drawing on canvas.
|
||||
* @param c The canvas that will draw to.
|
||||
* @param bitmap The bitmap to apply this filter.
|
||||
* @param src The subset of the bitmap to be drawn.
|
||||
* @param dest The rectangle that the bitmap will be scaled/translated to fit into.
|
||||
*/
|
||||
public abstract void apply(@NonNull Canvas c, @Nullable Bitmap bitmap,
|
||||
@Nullable Rect src, @NonNull RectF dest);
|
||||
|
||||
/**
|
||||
* Notifies the occurrence of built-in transition of the animation.
|
||||
* @param animator The animator which was animated.
|
||||
*/
|
||||
public abstract void onAnimatorUpdate(ValueAnimator animator);
|
||||
|
||||
/**
|
||||
* Notifies the occurrence of another transition of the animation.
|
||||
* @param amount The transition amount.
|
||||
*/
|
||||
public abstract void onTransitionAmountUpdate(float amount);
|
||||
|
||||
/**
|
||||
* To set the associated transformer.
|
||||
* @param transformer The transformer that is associated with this filter.
|
||||
*/
|
||||
public void setTransformer(ImageWallpaperTransformer transformer) {
|
||||
if (transformer != null) {
|
||||
mTransformer = transformer;
|
||||
}
|
||||
}
|
||||
|
||||
protected ImageWallpaperTransformer getTransformer() {
|
||||
return mTransformer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the changing of the offset value of the ImageWallpaper.
|
||||
* @param force True to force re-evaluate offsets.
|
||||
* @param xOffset X offset of the ImageWallpaper in percentage.
|
||||
* @param yOffset Y offset of the ImageWallpaper in percentage.
|
||||
*/
|
||||
public void onOffsetsUpdate(boolean force, float xOffset, float yOffset) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.view.DisplayInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class is used to manage the filters that will be applied.
|
||||
*/
|
||||
public class ImageWallpaperTransformer {
|
||||
private static final String TAG = ImageWallpaperTransformer.class.getSimpleName();
|
||||
|
||||
private DisplayInfo mDisplayInfo;
|
||||
private final List<ImageWallpaperFilter> mFilters;
|
||||
private final TransformationListener mListener;
|
||||
private boolean mIsInAmbientMode;
|
||||
private boolean mIsTransiting;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param listener A listener to inform you the transformation has updated.
|
||||
*/
|
||||
public ImageWallpaperTransformer(TransformationListener listener) {
|
||||
mFilters = new ArrayList<>();
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Claim that we want to use the specified filter.
|
||||
* @param filter The filter will be used.
|
||||
*/
|
||||
public void addFilter(ImageWallpaperFilter filter) {
|
||||
if (filter != null) {
|
||||
filter.setTransformer(this);
|
||||
mFilters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any transition is running.
|
||||
* @return True if the transition is running, false otherwise.
|
||||
*/
|
||||
boolean isTransiting() {
|
||||
return mIsTransiting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if any transition is running. <br/>
|
||||
* @param isTransiting True if the transition is running.
|
||||
*/
|
||||
void setIsTransiting(boolean isTransiting) {
|
||||
mIsTransiting = isTransiting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the device is in ambient mode.
|
||||
* @return True if the device is in ambient mode, false otherwise.
|
||||
*/
|
||||
public boolean isInAmbientMode() {
|
||||
return mIsInAmbientMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update current state of ambient mode.
|
||||
* @param isInAmbientMode Current ambient mode state.
|
||||
*/
|
||||
public void updateAmbientModeState(boolean isInAmbientMode) {
|
||||
mIsInAmbientMode = isInAmbientMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int idx = 0;
|
||||
for (ImageWallpaperFilter filter : mFilters) {
|
||||
sb.append(idx++).append(": ").append(filter.getClass().getSimpleName()).append("\n");
|
||||
}
|
||||
if (sb.length() == 0) {
|
||||
sb.append("No filters applied");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new display info.
|
||||
* @param displayInfo New display info.
|
||||
*/
|
||||
public void updateDisplayInfo(DisplayInfo displayInfo) {
|
||||
mDisplayInfo = displayInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* To get current display info.
|
||||
* @return Current display info.
|
||||
*/
|
||||
public DisplayInfo getDisplayInfo() {
|
||||
return mDisplayInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the offsets with default value.
|
||||
*/
|
||||
public void updateOffsets() {
|
||||
this.updateOffsets(true, 0f, .5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* To notify the filters that the offset of the ImageWallpaper changes.
|
||||
* @param force True to force re-evaluate offsets.
|
||||
* @param offsetX X offset of the ImageWallpaper in percentage.
|
||||
* @param offsetY Y offset of the ImageWallpaper in percentage.
|
||||
*/
|
||||
public void updateOffsets(boolean force, float offsetX, float offsetY) {
|
||||
mFilters.forEach(filter -> filter.onOffsetsUpdate(force, offsetX, offsetY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply all specified filters to the bitmap then draw to the canvas.
|
||||
* @param c The canvas that will draw to.
|
||||
* @param target The bitmap to apply filters.
|
||||
* @param src The subset of the bitmap to be drawn
|
||||
* @param dest The rectangle that the bitmap will be scaled/translated to fit into.
|
||||
*/
|
||||
void drawTransformedImage(@NonNull Canvas c, @Nullable Bitmap target,
|
||||
@Nullable Rect src, @NonNull RectF dest) {
|
||||
mFilters.forEach(filter -> filter.apply(c, target, src, dest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the transition amount. <br/>
|
||||
* Must invoke this to update transition amount if not running built-in transition.
|
||||
* @param amount The transition amount.
|
||||
*/
|
||||
void updateTransitionAmount(float amount) {
|
||||
mFilters.forEach(filter -> filter.onTransitionAmountUpdate(amount));
|
||||
if (mListener != null) {
|
||||
mListener.onTransformationUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface that informs the transformation status.
|
||||
*/
|
||||
public interface TransformationListener {
|
||||
/**
|
||||
* Notifies the update of the transformation.
|
||||
*/
|
||||
void onTransformationUpdated();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.ValueAnimator;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
/**
|
||||
* A filter that implements 70% black scrim effect.
|
||||
*/
|
||||
public class ScrimFilter extends ImageWallpaperFilter {
|
||||
private static final int MAX_ALPHA = (int) (255 * .7f);
|
||||
private static final int MIN_ALPHA = 0;
|
||||
|
||||
private final Paint mPaint;
|
||||
|
||||
public ScrimFilter() {
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(Color.BLACK);
|
||||
mPaint.setAlpha(MAX_ALPHA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Canvas c, Bitmap bitmap, Rect src, RectF dest) {
|
||||
ImageWallpaperTransformer transformer = getTransformer();
|
||||
|
||||
// If it is not in the transition, we need to set the property according to aod state.
|
||||
if (!transformer.isTransiting()) {
|
||||
mPaint.setAlpha(transformer.isInAmbientMode() ? MAX_ALPHA : MIN_ALPHA);
|
||||
}
|
||||
|
||||
c.drawRect(dest, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimatorUpdate(ValueAnimator animator) {
|
||||
ImageWallpaperTransformer transformer = getTransformer();
|
||||
float fraction = animator.getAnimatedFraction();
|
||||
float factor = transformer.isInAmbientMode() ? fraction : 1f - fraction;
|
||||
mPaint.setAlpha((int) (factor * MAX_ALPHA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionAmountUpdate(float amount) {
|
||||
mPaint.setAlpha((int) (amount * MAX_ALPHA));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.ValueAnimator;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RadialGradient;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.util.Log;
|
||||
import android.view.DisplayInfo;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* A filter that implements vignette effect.
|
||||
*/
|
||||
public class VignetteFilter extends ImageWallpaperFilter {
|
||||
private static final String TAG = VignetteFilter.class.getSimpleName();
|
||||
private static final int MAX_ALPHA = 255;
|
||||
private static final int MIN_ALPHA = 0;
|
||||
|
||||
private final Paint mPaint;
|
||||
private final Matrix mMatrix;
|
||||
private final Shader mShader;
|
||||
|
||||
private float mXOffset;
|
||||
private float mYOffset;
|
||||
private float mCenterX;
|
||||
private float mCenterY;
|
||||
private float mStretchX;
|
||||
private float mStretchY;
|
||||
private boolean mCalculateOffsetNeeded;
|
||||
|
||||
public VignetteFilter() {
|
||||
mPaint = new Paint();
|
||||
mMatrix = new Matrix();
|
||||
mShader = new RadialGradient(0, 0, 1,
|
||||
Color.TRANSPARENT, Color.BLACK, Shader.TileMode.CLAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Canvas c, Bitmap bitmap, Rect src, RectF dest) {
|
||||
DisplayInfo info = getTransformer().getDisplayInfo();
|
||||
|
||||
if (mCalculateOffsetNeeded) {
|
||||
int lw = info.logicalWidth;
|
||||
int lh = info.logicalHeight;
|
||||
mCenterX = lw / 2 + (dest.width() - lw) * mXOffset;
|
||||
mCenterY = lh / 2 + (dest.height() - lh) * mYOffset;
|
||||
mStretchX = info.logicalWidth / 2;
|
||||
mStretchY = info.logicalHeight / 2;
|
||||
mCalculateOffsetNeeded = false;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "apply: lw=" + info.logicalWidth + ", lh=" + info.logicalHeight
|
||||
+ ", center=(" + mCenterX + "," + mCenterY + ")"
|
||||
+ ", stretch=(" + mStretchX + "," + mStretchY + ")");
|
||||
}
|
||||
|
||||
mMatrix.reset();
|
||||
mMatrix.postTranslate(mCenterX, mCenterY);
|
||||
mMatrix.postScale(mStretchX, mStretchY, mCenterX, mCenterY);
|
||||
mShader.setLocalMatrix(mMatrix);
|
||||
mPaint.setShader(mShader);
|
||||
|
||||
ImageWallpaperTransformer transformer = getTransformer();
|
||||
|
||||
// If it is not in the transition, we need to set the property according to aod state.
|
||||
if (!transformer.isTransiting()) {
|
||||
mPaint.setAlpha(transformer.isInAmbientMode() ? MAX_ALPHA : MIN_ALPHA);
|
||||
}
|
||||
|
||||
c.drawRect(dest, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimatorUpdate(ValueAnimator animator) {
|
||||
ImageWallpaperTransformer transformer = getTransformer();
|
||||
float fraction = animator.getAnimatedFraction();
|
||||
float factor = transformer.isInAmbientMode() ? fraction : 1f - fraction;
|
||||
mPaint.setAlpha((int) (factor * MAX_ALPHA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionAmountUpdate(float amount) {
|
||||
mPaint.setAlpha((int) (amount * MAX_ALPHA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffsetsUpdate(boolean force, float xOffset, float yOffset) {
|
||||
if (force || mXOffset != xOffset || mYOffset != yOffset) {
|
||||
mXOffset = xOffset;
|
||||
mYOffset = yOffset;
|
||||
mCalculateOffsetNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public PointF getCenterPoint() {
|
||||
return new PointF(mCenterX, mCenterY);
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,12 @@
|
||||
|
||||
package com.android.systemui;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
@@ -58,13 +53,15 @@ public class ImageWallpaperTest extends SysuiTestCase {
|
||||
@Mock private SurfaceHolder mSurfaceHolder;
|
||||
@Mock private DisplayInfo mDisplayInfo;
|
||||
|
||||
CountDownLatch mEventCountdown;
|
||||
private CountDownLatch mEventCountdown;
|
||||
private CountDownLatch mAmbientEventCountdown;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mEventCountdown = new CountDownLatch(1);
|
||||
mAmbientEventCountdown = new CountDownLatch(2);
|
||||
|
||||
mImageWallpaper = new ImageWallpaper() {
|
||||
@Override
|
||||
@@ -86,6 +83,11 @@ public class ImageWallpaperTest extends SysuiTestCase {
|
||||
assertTrue("mFixedSizeAllowed should be true", allowed);
|
||||
mEventCountdown.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAmbientModeChanged(boolean inAmbientMode, long duration) {
|
||||
mAmbientEventCountdown.countDown();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -132,4 +134,23 @@ public class ImageWallpaperTest extends SysuiTestCase {
|
||||
verify(mSurfaceHolder, times(1)).setFixedSize(ImageWallpaper.DrawableEngine.MIN_BACKGROUND_WIDTH, ImageWallpaper.DrawableEngine.MIN_BACKGROUND_HEIGHT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeliversAmbientModeChanged() {
|
||||
ImageWallpaper.DrawableEngine wallpaperEngine =
|
||||
(ImageWallpaper.DrawableEngine) mImageWallpaper.onCreateEngine();
|
||||
|
||||
assertEquals("setFixedSizeAllowed should have been called.",
|
||||
0, mEventCountdown.getCount());
|
||||
|
||||
wallpaperEngine.setCreated(true);
|
||||
wallpaperEngine.doAmbientModeChanged(false, 1000);
|
||||
assertFalse("ambient mode should be false", wallpaperEngine.isInAmbientMode());
|
||||
assertEquals("onAmbientModeChanged should have been called.",
|
||||
1, mAmbientEventCountdown.getCount());
|
||||
|
||||
wallpaperEngine.doAmbientModeChanged(true, 1000);
|
||||
assertTrue("ambient mode should be true", wallpaperEngine.isInAmbientMode());
|
||||
assertEquals("onAmbientModeChanged should have been called.",
|
||||
0, mAmbientEventCountdown.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.RectF;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AodMaskViewTest extends SysuiTestCase {
|
||||
private AodMaskView mMaskView;
|
||||
private DisplayInfo mDisplayInfo;
|
||||
private ImageWallpaperTransformer mTransformer;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
DisplayManager displayManager =
|
||||
spy((DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE));
|
||||
doNothing().when(displayManager).registerDisplayListener(any(), any());
|
||||
mContext.addMockSystemService(DisplayManager.class, displayManager);
|
||||
|
||||
WallpaperManager wallpaperManager =
|
||||
spy((WallpaperManager) mContext.getSystemService(Context.WALLPAPER_SERVICE));
|
||||
doReturn(null).when(wallpaperManager).getWallpaperInfo();
|
||||
mContext.addMockSystemService(WallpaperManager.class, wallpaperManager);
|
||||
|
||||
mTransformer = spy(new ImageWallpaperTransformer(null /* listener */));
|
||||
mMaskView = spy(new AodMaskView(getContext(), null /* attrs */, mTransformer));
|
||||
mDisplayInfo = new DisplayInfo();
|
||||
|
||||
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
|
||||
.getDefaultDisplay().getDisplayInfo(mDisplayInfo);
|
||||
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.AOD_IMAGEWALLPAPER_ENABLED, true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.AOD_IMAGEWALLPAPER_ENABLED, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateMaskView_TransformerIsNotNull() {
|
||||
assertNotNull("mTransformer should not be null", mTransformer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAodMaskView_ShouldNotClickable() {
|
||||
assertFalse("MaskView should not be clickable", mMaskView.isClickable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAodMaskView_OnSizeChange_ShouldUpdateTransformerOffsets() {
|
||||
mMaskView.onSizeChanged(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, 0, 0);
|
||||
verify(mTransformer, times(1)).updateOffsets();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAodMaskView_OnDraw_ShouldDrawTransformedImage() {
|
||||
Canvas c = new Canvas();
|
||||
RectF bounds = new RectF(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
|
||||
mMaskView.onSizeChanged(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, 0, 0);
|
||||
mMaskView.onStatePreChange(0, 1);
|
||||
mMaskView.onDraw(c);
|
||||
verify(mTransformer, times(1)).drawTransformedImage(c, null, null, bounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAodMaskView_IsDozing_ShouldUpdateAmbientModeState() {
|
||||
doNothing().when(mMaskView).setAnimatorProperty(anyBoolean());
|
||||
mMaskView.onStatePreChange(0, 1);
|
||||
mMaskView.onDozingChanged(true);
|
||||
verify(mTransformer, times(1)).updateAmbientModeState(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAodMaskView_IsDozing_ShouldDoTransitionOrDrawFinalFrame() {
|
||||
doNothing().when(mMaskView).setAnimatorProperty(anyBoolean());
|
||||
mMaskView.onStatePreChange(0, 1);
|
||||
mMaskView.onDozingChanged(true);
|
||||
mMaskView.onStatePostChange();
|
||||
mMaskView.onDozingChanged(false);
|
||||
verify(mMaskView, times(1)).invalidate();
|
||||
verify(mMaskView, times(1)).setAnimatorProperty(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ImageWallpaperTransformerTest extends SysuiTestCase {
|
||||
private DisplayInfo mDisplayInfo;
|
||||
private Bitmap mBitmap;
|
||||
private Canvas mCanvas;
|
||||
private RectF mDestination;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDisplayInfo = new DisplayInfo();
|
||||
((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
|
||||
.getDefaultDisplay().getDisplayInfo(mDisplayInfo);
|
||||
int dimension = Math.max(mDisplayInfo.logicalHeight, mDisplayInfo.logicalWidth);
|
||||
mBitmap = Bitmap.createBitmap(dimension, dimension, Bitmap.Config.ARGB_8888);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
mCanvas.drawColor(Color.RED);
|
||||
mDestination = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVignetteFilter() {
|
||||
VignetteFilter vignette = new VignetteFilter();
|
||||
|
||||
ImageWallpaperTransformer transformer = getTransformer(vignette);
|
||||
transformer.drawTransformedImage(mCanvas, mBitmap, null, mDestination);
|
||||
|
||||
PointF center = vignette.getCenterPoint();
|
||||
int p1 = mBitmap.getPixel((int) center.x, (int) center.y);
|
||||
int p2 = mBitmap.getPixel(0, 0);
|
||||
int p3 = mBitmap.getPixel(mBitmap.getWidth() - 1, mBitmap.getHeight() - 1);
|
||||
|
||||
assertThat(p1).isEqualTo(Color.RED);
|
||||
assertThat(p2 | p3).isEqualTo(Color.BLACK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScrimFilter() {
|
||||
getTransformer(new ScrimFilter())
|
||||
.drawTransformedImage(mCanvas, mBitmap, null, mDestination);
|
||||
|
||||
int pixel = mBitmap.getPixel(0, 0);
|
||||
|
||||
// 0xff4d0000 is the result of 70% alpha pre-multiplied which is 0.7*(0,0,0)+0.3*(255,0,0).
|
||||
assertThat(pixel).isEqualTo(0xff4d0000);
|
||||
}
|
||||
|
||||
private ImageWallpaperTransformer getTransformer(ImageWallpaperFilter filter) {
|
||||
ImageWallpaperTransformer transformer = new ImageWallpaperTransformer(null);
|
||||
transformer.addFilter(filter);
|
||||
transformer.updateDisplayInfo(mDisplayInfo);
|
||||
transformer.updateOffsets();
|
||||
transformer.updateAmbientModeState(true);
|
||||
return transformer;
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,7 @@ import android.service.wallpaper.WallpaperService;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.EventLog;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -2219,8 +2220,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
synchronized (mLock) {
|
||||
mInAmbientMode = inAmbientMode;
|
||||
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
|
||||
if (data != null && data.connection != null && data.connection.mInfo != null
|
||||
&& data.connection.mInfo.supportsAmbientMode()) {
|
||||
final boolean hasConnection = data != null && data.connection != null;
|
||||
final WallpaperInfo info = hasConnection ? data.connection.mInfo : null;
|
||||
|
||||
// The wallpaper info is null for image wallpaper, also use the engine in this case.
|
||||
if (hasConnection && (info == null && isAodImageWallpaperEnabled()
|
||||
|| info != null && info.supportsAmbientMode())) {
|
||||
// TODO(multi-display) Extends this method with specific display.
|
||||
engine = data.connection.getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine;
|
||||
} else {
|
||||
@@ -2237,6 +2242,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAodImageWallpaperEnabled() {
|
||||
return FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.AOD_IMAGEWALLPAPER_ENABLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
|
||||
checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);
|
||||
|
||||
Reference in New Issue
Block a user