Merge changes from topic "glwallpaper_cleanup"

* changes:
  Remove AOD_IMAGEWALLPAPER_ENABLED from feature flags
  Remove DrawableEngine and related logics
This commit is contained in:
TreeHugger Robot
2019-02-20 18:25:21 +00:00
committed by Android (Google) Code Review
15 changed files with 4 additions and 1607 deletions

View File

@@ -22,9 +22,7 @@ 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.
@@ -40,11 +38,9 @@ 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";
public static final String GLOBAL_ACTIONS_GRID_ENABLED = "settings_global_actions_grid_enabled";
private static final Map<String, String> DEFAULT_FLAGS;
private static final Set<String> OBSERVABLE_FLAGS;
static {
DEFAULT_FLAGS = new HashMap<>();
@@ -60,11 +56,7 @@ 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");
DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "false");
OBSERVABLE_FLAGS = new HashSet<>();
OBSERVABLE_FLAGS.add(AOD_IMAGEWALLPAPER_ENABLED);
}
/**
@@ -101,16 +93,6 @@ 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");
}
/**

View File

@@ -43,14 +43,6 @@
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"

View File

@@ -111,11 +111,6 @@
<!-- 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" />
<!-- For saving DynamicAnimation physics animations as view tags. -->
<item type="id" name="translation_x_dynamicanimation_tag"/>
<item type="id" name="translation_y_dynamicanimation_tag"/>

View File

@@ -16,62 +16,26 @@
package com.android.systemui;
import static android.view.Display.DEFAULT_DISPLAY;
import android.app.WallpaperManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.hardware.display.DisplayManager;
import android.opengl.GLSurfaceView;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.Trace;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceHolder;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.glwallpaper.ImageWallpaperRenderer;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Default built-in wallpaper that simply shows a static image.
*/
@SuppressWarnings({"UnusedDeclaration"})
public class ImageWallpaper extends WallpaperService {
private static final String TAG = "ImageWallpaper";
private static final String GL_LOG_TAG = "ImageWallpaperGL";
private static final boolean DEBUG = false;
private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu";
private static final long DELAY_FORGET_WALLPAPER = 5000;
private WallpaperManager mWallpaperManager;
private DrawableEngine mEngine;
private static final String TAG = ImageWallpaper.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
mWallpaperManager = getSystemService(WallpaperManager.class);
}
@Override
public void onTrimMemory(int level) {
if (mEngine != null) {
mEngine.trimMemory(level);
}
}
@Override
@@ -147,495 +111,6 @@ public class ImageWallpaper extends WallpaperService {
}
}
// TODO: Remove this engine, tracking on b/123617158.
class DrawableEngine extends Engine {
private final Runnable mUnloadWallpaperCallback = () -> {
unloadWallpaper(false /* forgetSize */);
};
// Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
// set min to 64 px (CTS covers this)
@VisibleForTesting
static final int MIN_BACKGROUND_WIDTH = 64;
@VisibleForTesting
static final int MIN_BACKGROUND_HEIGHT = 64;
Bitmap mBackground;
int mBackgroundWidth = -1, mBackgroundHeight = -1;
int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
int mLastRotation = -1;
float mXOffset = 0f;
float mYOffset = 0f;
float mScale = 1f;
private Display mDisplay;
private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
boolean mVisible = true;
boolean mOffsetsChanged;
int mLastXTranslation;
int mLastYTranslation;
private int mRotationAtLastSurfaceSizeUpdate = -1;
private int mDisplayWidthAtLastSurfaceSizeUpdate = -1;
private int mDisplayHeightAtLastSurfaceSizeUpdate = -1;
private int mLastRequestedWidth = -1;
private int mLastRequestedHeight = -1;
private AsyncTask<Void, Void, Bitmap> mLoader;
private boolean mNeedsDrawAfterLoadingWallpaper;
private boolean mSurfaceValid;
private boolean mSurfaceRedrawNeeded;
DrawableEngine() {
super();
setFixedSizeAllowed(true);
}
void trimMemory(int level) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW
&& level <= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL
&& mBackground != null) {
if (DEBUG) {
Log.d(TAG, "trimMemory");
}
unloadWallpaper(true /* forgetSize */);
}
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
if (DEBUG) {
Log.d(TAG, "onCreate");
}
super.onCreate(surfaceHolder);
//noinspection ConstantConditions
final Context displayContext = getDisplayContext();
final int displayId = displayContext == null ? DEFAULT_DISPLAY :
displayContext.getDisplayId();
DisplayManager dm = getSystemService(DisplayManager.class);
if (dm != null) {
mDisplay = dm.getDisplay(displayId);
if (mDisplay == null) {
Log.e(TAG, "Cannot find display! Fallback to default.");
mDisplay = dm.getDisplay(DEFAULT_DISPLAY);
}
}
setOffsetNotificationsEnabled(false);
updateSurfaceSize(surfaceHolder, getDisplayInfo(), false /* forDraw */);
}
@Override
public void onDestroy() {
super.onDestroy();
mBackground = null;
unloadWallpaper(true /* forgetSize */);
}
boolean updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo,
boolean forDraw) {
boolean hasWallpaper = true;
// Load background image dimensions, if we haven't saved them yet
if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
// Need to load the image to get dimensions
loadWallpaper(forDraw);
if (DEBUG) {
Log.d(TAG, "Reloading, redoing updateSurfaceSize later.");
}
hasWallpaper = false;
}
// Expected surface size.
int surfaceWidth = Math.max(displayInfo.logicalWidth, mBackgroundWidth);
int surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight);
// Calculate the minimum drawing area of the surface, which saves memory and does not
// distort the image.
final float scale = Math.min(
(float) mBackgroundHeight / (float) surfaceHeight,
(float) mBackgroundWidth / (float) surfaceWidth);
surfaceHeight = (int) (scale * surfaceHeight);
surfaceWidth = (int) (scale * surfaceWidth);
// Set surface size to at least MIN size.
if (surfaceWidth < MIN_BACKGROUND_WIDTH || surfaceHeight < MIN_BACKGROUND_HEIGHT) {
final float scaleUp = Math.max(
(float) MIN_BACKGROUND_WIDTH / (float) surfaceWidth,
(float) MIN_BACKGROUND_HEIGHT / (float) surfaceHeight);
surfaceWidth = (int) ((float) surfaceWidth * scaleUp);
surfaceHeight = (int) ((float) surfaceHeight * scaleUp);
}
// Used a fixed size surface, because we are special. We can do
// this because we know the current design of window animations doesn't
// cause this to break.
surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight);
mLastRequestedWidth = surfaceWidth;
mLastRequestedHeight = surfaceHeight;
return hasWallpaper;
}
@Override
public void onVisibilityChanged(boolean visible) {
if (DEBUG) {
Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible);
}
if (mVisible != visible) {
if (DEBUG) {
Log.d(TAG, "Visibility changed to visible=" + visible);
}
mVisible = visible;
if (visible) {
drawFrame();
}
}
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep,
int xPixels, int yPixels) {
if (DEBUG) {
Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset
+ ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep
+ ", xPixels=" + xPixels + ", yPixels=" + yPixels);
}
if (mXOffset != xOffset || mYOffset != yOffset) {
if (DEBUG) {
Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ").");
}
mXOffset = xOffset;
mYOffset = yOffset;
mOffsetsChanged = true;
}
drawFrame();
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (DEBUG) {
Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height);
}
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
if (DEBUG) {
Log.i(TAG, "onSurfaceDestroyed");
}
mLastSurfaceWidth = mLastSurfaceHeight = -1;
mSurfaceValid = false;
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
if (DEBUG) {
Log.i(TAG, "onSurfaceCreated");
}
mLastSurfaceWidth = mLastSurfaceHeight = -1;
mSurfaceValid = true;
}
@Override
public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
if (DEBUG) {
Log.d(TAG, "onSurfaceRedrawNeeded");
}
super.onSurfaceRedrawNeeded(holder);
// At the end of this method we should have drawn into the surface.
// This means that the bitmap should be loaded synchronously if
// it was already unloaded.
if (mBackground == null) {
updateBitmap(mWallpaperManager.getBitmap(true /* hardware */));
}
mSurfaceRedrawNeeded = true;
drawFrame();
}
@VisibleForTesting
DisplayInfo getDisplayInfo() {
mDisplay.getDisplayInfo(mTmpDisplayInfo);
return mTmpDisplayInfo;
}
void drawFrame() {
if (!mSurfaceValid) {
return;
}
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawWallpaper");
DisplayInfo displayInfo = getDisplayInfo();
int newRotation = displayInfo.rotation;
// Sometimes a wallpaper is not large enough to cover the screen in one dimension.
// Call updateSurfaceSize -- it will only actually do the update if the dimensions
// should change
if (newRotation != mLastRotation
|| mDisplayWidthAtLastSurfaceSizeUpdate != displayInfo.logicalWidth
|| mDisplayHeightAtLastSurfaceSizeUpdate != displayInfo.logicalHeight) {
// Update surface size (if necessary)
if (!updateSurfaceSize(getSurfaceHolder(), displayInfo, true /* forDraw */)) {
return; // had to reload wallpaper, will retry later
}
mRotationAtLastSurfaceSizeUpdate = newRotation;
mDisplayWidthAtLastSurfaceSizeUpdate = displayInfo.logicalWidth;
mDisplayHeightAtLastSurfaceSizeUpdate = displayInfo.logicalHeight;
}
SurfaceHolder sh = getSurfaceHolder();
final Rect frame = sh.getSurfaceFrame();
final int dw = frame.width();
final int dh = frame.height();
boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth
|| dh != mLastSurfaceHeight;
boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation
|| mSurfaceRedrawNeeded || mNeedsDrawAfterLoadingWallpaper;
if (!redrawNeeded && !mOffsetsChanged) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
+ "and offsets have not changed.");
}
return;
}
mLastRotation = newRotation;
mSurfaceRedrawNeeded = false;
// Load bitmap if it is not yet loaded
if (mBackground == null) {
loadWallpaper(true);
if (DEBUG) {
Log.d(TAG, "Reloading, resuming draw later");
}
return;
}
// Left align the scaled image
mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(),
dh / (float) mBackground.getHeight()));
final int availw = (int) (mBackground.getWidth() * mScale) - dw;
final int availh = (int) (mBackground.getHeight() * mScale) - dh;
int xPixels = (int) (availw * mXOffset);
int yPixels = (int) (availh * mYOffset);
mOffsetsChanged = false;
if (surfaceDimensionsChanged) {
mLastSurfaceWidth = dw;
mLastSurfaceHeight = dh;
}
if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since the image has not "
+ "actually moved an integral number of pixels.");
}
return;
}
mLastXTranslation = xPixels;
mLastYTranslation = yPixels;
if (DEBUG) {
Log.d(TAG, "Redrawing wallpaper");
}
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
scheduleUnloadWallpaper();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
/**
* Loads the wallpaper on background thread and schedules updating the surface frame,
* and if {@param needsDraw} is set also draws a frame.
*
* If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to
* the active request).
*
* If {@param needsReset} is set also clears the cache in WallpaperManager first.
*/
private void loadWallpaper(boolean needsDraw) {
mNeedsDrawAfterLoadingWallpaper |= needsDraw;
if (mLoader != null) {
if (DEBUG) {
Log.d(TAG, "Skipping loadWallpaper, already in flight ");
}
return;
}
mLoader = new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
Throwable exception;
try {
Bitmap wallpaper = mWallpaperManager.getBitmap(true /* hardware */);
if (wallpaper != null
&& wallpaper.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) {
throw new RuntimeException("Wallpaper is too large to draw!");
}
return wallpaper;
} catch (RuntimeException | OutOfMemoryError e) {
exception = e;
}
if (isCancelled()) {
return null;
}
// Note that if we do fail at this, and the default wallpaper can't
// be loaded, we will go into a cycle. Don't do a build where the
// default wallpaper can't be loaded.
Log.w(TAG, "Unable to load wallpaper!", exception);
try {
mWallpaperManager.clear();
} catch (IOException ex) {
// now we're really screwed.
Log.w(TAG, "Unable reset to default wallpaper!", ex);
}
if (isCancelled()) {
return null;
}
try {
return mWallpaperManager.getBitmap(true /* hardware */);
} catch (RuntimeException | OutOfMemoryError e) {
Log.w(TAG, "Unable to load default wallpaper!", e);
}
return null;
}
@Override
protected void onPostExecute(Bitmap b) {
updateBitmap(b);
if (mNeedsDrawAfterLoadingWallpaper) {
drawFrame();
}
mLoader = null;
mNeedsDrawAfterLoadingWallpaper = false;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@VisibleForTesting
void updateBitmap(Bitmap bitmap) {
mBackground = null;
mBackgroundWidth = -1;
mBackgroundHeight = -1;
if (bitmap != null) {
mBackground = bitmap;
mBackgroundWidth = mBackground.getWidth();
mBackgroundHeight = mBackground.getHeight();
}
if (DEBUG) {
Log.d(TAG, "Wallpaper loaded: " + mBackground);
}
updateSurfaceSize(getSurfaceHolder(), getDisplayInfo(),
false /* forDraw */);
}
private void unloadWallpaper(boolean forgetSize) {
if (mLoader != null) {
mLoader.cancel(false);
mLoader = null;
}
mBackground = null;
if (forgetSize) {
mBackgroundWidth = -1;
mBackgroundHeight = -1;
}
final Surface surface = getSurfaceHolder().getSurface();
surface.hwuiDestroy();
mWallpaperManager.forgetLoadedWallpaper();
}
private void scheduleUnloadWallpaper() {
Handler handler = getMainThreadHandler();
handler.removeCallbacks(mUnloadWallpaperCallback);
handler.postDelayed(mUnloadWallpaperCallback, DELAY_FORGET_WALLPAPER);
}
@Override
protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
super.dump(prefix, fd, out, args);
out.print(prefix); out.println("ImageWallpaper.DrawableEngine:");
out.print(prefix); out.print(" mBackground="); out.print(mBackground);
out.print(" mBackgroundWidth="); out.print(mBackgroundWidth);
out.print(" mBackgroundHeight="); out.println(mBackgroundHeight);
out.print(prefix); out.print(" mLastRotation="); out.print(mLastRotation);
out.print(" mLastSurfaceWidth="); out.print(mLastSurfaceWidth);
out.print(" mLastSurfaceHeight="); out.println(mLastSurfaceHeight);
out.print(prefix); out.print(" mXOffset="); out.print(mXOffset);
out.print(" mYOffset="); out.println(mYOffset);
out.print(prefix); out.print(" mVisible="); out.print(mVisible);
out.print(" mOffsetsChanged="); out.println(mOffsetsChanged);
out.print(prefix); out.print(" mLastXTranslation="); out.print(mLastXTranslation);
out.print(" mLastYTranslation="); out.print(mLastYTranslation);
out.print(" mScale="); out.println(mScale);
out.print(prefix); out.print(" mLastRequestedWidth="); out.print(mLastRequestedWidth);
out.print(" mLastRequestedHeight="); out.println(mLastRequestedHeight);
out.print(prefix); out.println(" DisplayInfo at last updateSurfaceSize:");
out.print(prefix);
out.print(" rotation="); out.print(mRotationAtLastSurfaceSizeUpdate);
out.print(" width="); out.print(mDisplayWidthAtLastSurfaceSizeUpdate);
out.print(" height="); out.println(mDisplayHeightAtLastSurfaceSizeUpdate);
}
private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int left, int top) {
Canvas c = sh.lockHardwareCanvas();
if (c != null) {
try {
if (DEBUG) {
Log.d(TAG, "Redrawing: left=" + left + ", top=" + top);
}
final float right = left + mBackground.getWidth() * mScale;
final float bottom = top + mBackground.getHeight() * mScale;
if (w < 0 || h < 0) {
c.save(Canvas.CLIP_SAVE_FLAG);
c.clipRect(left, top, right, bottom,
Op.DIFFERENCE);
c.drawColor(0xff000000);
c.restore();
}
if (mBackground != null) {
RectF dest = new RectF(left, top, right, bottom);
Log.i(TAG, "Redrawing in rect: " + dest + " with surface size: "
+ mLastRequestedWidth + "x" + mLastRequestedHeight);
c.drawBitmap(mBackground, null, dest, null);
}
} finally {
sh.unlockCanvasAndPost(c);
}
}
}
}
/**
* A listener to trace status of image wallpaper.
*/

View File

@@ -214,14 +214,6 @@ 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;
}

View File

@@ -70,7 +70,6 @@ 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;
@@ -99,7 +98,6 @@ 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;
@@ -474,9 +472,6 @@ 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());
@@ -580,7 +575,6 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationPresenter mPresenter;
private NotificationActivityStarter mNotificationActivityStarter;
private boolean mPulsing;
private ContentObserver mFeatureFlagObserver;
protected BubbleController mBubbleController;
private final BubbleController.BubbleExpandListener mBubbleExpandListener =
(isExpanding, key) -> {
@@ -705,9 +699,6 @@ 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();
@@ -4426,32 +4417,4 @@ public class StatusBar extends SystemUI implements DemoMode,
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);
}
}
}
}

View File

@@ -1,224 +0,0 @@
/*
* 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).
// Because of conflicting with another wallpaper feature,
// we only support LockScreen wallpaper currently.
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;
}
}

View File

@@ -1,81 +0,0 @@
/*
* 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
}
}

View File

@@ -1,173 +0,0 @@
/*
* 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();
}
}

View File

@@ -1,67 +0,0 @@
/*
* 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));
}
}

View File

@@ -1,124 +0,0 @@
/*
* 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);
}
}

View File

@@ -16,24 +16,12 @@
package com.android.systemui;
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;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.DisplayInfo;
import android.view.SurfaceHolder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.concurrent.CountDownLatch;
@@ -42,115 +30,20 @@ import java.util.concurrent.CountDownLatch;
@RunWith(AndroidJUnit4.class)
public class ImageWallpaperTest extends SysuiTestCase {
private static final int BMP_WIDTH = 128;
private static final int BMP_HEIGHT = 128;
private static final int INVALID_BMP_WIDTH = 1;
private static final int INVALID_BMP_HEIGHT = 1;
private ImageWallpaper mImageWallpaper;
@Mock private SurfaceHolder mSurfaceHolder;
@Mock private DisplayInfo mDisplayInfo;
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
public Engine onCreateEngine() {
return new DrawableEngine() {
@Override
DisplayInfo getDisplayInfo() {
return mDisplayInfo;
}
@Override
public SurfaceHolder getSurfaceHolder() {
return mSurfaceHolder;
}
@Override
public void setFixedSizeAllowed(boolean allowed) {
super.setFixedSizeAllowed(allowed);
assertTrue("mFixedSizeAllowed should be true", allowed);
mEventCountdown.countDown();
}
@Override
public void onAmbientModeChanged(boolean inAmbientMode, long duration) {
mAmbientEventCountdown.countDown();
}
};
}
};
}
@Test
public void testSetValidBitmapWallpaper() {
ImageWallpaper.DrawableEngine wallpaperEngine =
(ImageWallpaper.DrawableEngine) mImageWallpaper.onCreateEngine();
assertEquals("setFixedSizeAllowed should have been called.",
0, mEventCountdown.getCount());
Bitmap mockedBitmap = mock(Bitmap.class);
when(mockedBitmap.getWidth()).thenReturn(BMP_WIDTH);
when(mockedBitmap.getHeight()).thenReturn(BMP_HEIGHT);
wallpaperEngine.updateBitmap(mockedBitmap);
assertEquals(BMP_WIDTH, wallpaperEngine.mBackgroundWidth);
assertEquals(BMP_HEIGHT, wallpaperEngine.mBackgroundHeight);
verify(mSurfaceHolder, times(1)).setFixedSize(BMP_WIDTH, BMP_HEIGHT);
}
@Test
public void testSetTooSmallBitmapWallpaper() {
ImageWallpaper.DrawableEngine wallpaperEngine =
(ImageWallpaper.DrawableEngine) mImageWallpaper.onCreateEngine();
assertEquals("setFixedSizeAllowed should have been called.",
0, mEventCountdown.getCount());
Bitmap mockedBitmap = mock(Bitmap.class);
when(mockedBitmap.getWidth()).thenReturn(INVALID_BMP_WIDTH);
when(mockedBitmap.getHeight()).thenReturn(INVALID_BMP_HEIGHT);
wallpaperEngine.updateBitmap(mockedBitmap);
assertEquals(INVALID_BMP_WIDTH, wallpaperEngine.mBackgroundWidth);
assertEquals(INVALID_BMP_HEIGHT, wallpaperEngine.mBackgroundHeight);
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());
//TODO: We need add tests for GLEngine.
}
// TODO: Add more test cases for GLEngine, tracing in b/124838911.
}

View File

@@ -1,128 +0,0 @@
/*
* 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);
}
}

View File

@@ -1,93 +0,0 @@
/*
* 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;
}
}

View File

@@ -84,7 +84,6 @@ 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;
@@ -2262,10 +2261,6 @@ 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);