Change wallpaper sizing
- ignore suggested dimensions
- when orientation changes, scale up wallpaper if
it doesn't fill the whole screen, or scale back to
original size if not necessary
Change-Id: I75b7519a105d4097bf7a35cd8af61fc40f45f8fb
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 4435032..e6e0f35 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -44,9 +44,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.util.DisplayMetrics;
import android.util.Log;
-import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import java.io.BufferedInputStream;
@@ -280,9 +278,8 @@
try {
BitmapFactory.Options options = new BitmapFactory.Options();
- Bitmap bm = BitmapFactory.decodeFileDescriptor(
+ return BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, options);
- return generateBitmap(context, bm, width, height);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode file", e);
} finally {
@@ -309,8 +306,7 @@
try {
BitmapFactory.Options options = new BitmapFactory.Options();
- Bitmap bm = BitmapFactory.decodeStream(is, null, options);
- return generateBitmap(context, bm, width, height);
+ return BitmapFactory.decodeStream(is, null, options);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode stream", e);
} finally {
@@ -1015,62 +1011,4 @@
public void clear() throws IOException {
setResource(com.android.internal.R.drawable.default_wallpaper);
}
-
- static Bitmap generateBitmap(Context context, Bitmap bm, int width, int height) {
- if (bm == null) {
- return null;
- }
-
- WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics metrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(metrics);
- bm.setDensity(metrics.noncompatDensityDpi);
-
- if (width <= 0 || height <= 0
- || (bm.getWidth() == width && bm.getHeight() == height)) {
- return bm;
- }
-
- // This is the final bitmap we want to return.
- try {
- Bitmap newbm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- newbm.setDensity(metrics.noncompatDensityDpi);
-
- Canvas c = new Canvas(newbm);
- Rect targetRect = new Rect();
- targetRect.right = bm.getWidth();
- targetRect.bottom = bm.getHeight();
-
- int deltaw = width - targetRect.right;
- int deltah = height - targetRect.bottom;
-
- if (deltaw > 0 || deltah > 0) {
- // We need to scale up so it covers the entire area.
- float scale;
- if (deltaw > deltah) {
- scale = width / (float)targetRect.right;
- } else {
- scale = height / (float)targetRect.bottom;
- }
- targetRect.right = (int)(targetRect.right*scale);
- targetRect.bottom = (int)(targetRect.bottom*scale);
- deltaw = width - targetRect.right;
- deltah = height - targetRect.bottom;
- }
-
- targetRect.offset(deltaw/2, deltah/2);
-
- Paint paint = new Paint();
- paint.setFilterBitmap(true);
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- c.drawBitmap(bm, null, targetRect, paint);
-
- bm.recycle();
- c.setBitmap(null);
- return newbm;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Can't generate default bitmap", e);
- return bm;
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index c7f4828..74483cc 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -27,13 +27,16 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Region.Op;
import android.opengl.GLUtils;
import android.os.SystemProperties;
import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.WindowManager;
@@ -107,10 +110,12 @@
private WallpaperObserver mReceiver;
Bitmap mBackground;
+ int mBackgroundWidth = -1, mBackgroundHeight = -1;
int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
int mLastRotation = -1;
- float mXOffset;
- float mYOffset;
+ float mXOffset = 0.5f;
+ float mYOffset = 0.5f;
+ float mScale = 1f;
boolean mVisible = true;
boolean mRedrawNeeded;
@@ -155,6 +160,8 @@
mLastSurfaceWidth = mLastSurfaceHeight = -1;
mBackground = null;
+ mBackgroundWidth = -1;
+ mBackgroundHeight = -1;
mRedrawNeeded = true;
drawFrame();
}
@@ -173,6 +180,8 @@
}
mBackground.recycle();
mBackground = null;
+ mBackgroundWidth = -1;
+ mBackgroundHeight = -1;
mWallpaperManager.forgetLoadedWallpaper();
}
}
@@ -204,21 +213,40 @@
}
}
- @Override
- public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
- super.onDesiredSizeChanged(desiredWidth, desiredHeight);
- SurfaceHolder surfaceHolder = getSurfaceHolder();
- if (surfaceHolder != null) {
- updateSurfaceSize(surfaceHolder);
- }
- }
-
void updateSurfaceSize(SurfaceHolder surfaceHolder) {
+ Point p = getDefaultDisplaySize();
+
+ // Load background image dimensions, if we haven't saved them yet
+ if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
+ // Need to load the image to get dimensions
+ mWallpaperManager.forgetLoadedWallpaper();
+ updateWallpaperLocked();
+ if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
+ // Default to the display size if we can't find the dimensions
+ mBackgroundWidth = p.x;
+ mBackgroundHeight = p.y;
+ }
+ }
+
+ // Force the wallpaper to cover the screen in both dimensions
+ int surfaceWidth = Math.max(p.x, mBackgroundWidth);
+ int surfaceHeight = Math.max(p.y, mBackgroundHeight);
+
+ // If the surface dimensions haven't changed, then just return
+ final Rect frame = surfaceHolder.getSurfaceFrame();
+ if (frame != null) {
+ final int dw = frame.width();
+ final int dh = frame.height();
+ if (surfaceWidth == dw && surfaceHeight == dh) {
+ return;
+ }
+ }
+
if (FIXED_SIZED_SURFACE) {
// 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(getDesiredMinimumWidth(), getDesiredMinimumHeight());
+ surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight);
} else {
surfaceHolder.setSizeFromLayout();
}
@@ -298,13 +326,30 @@
drawFrame();
}
+ private Point getDefaultDisplaySize() {
+ Point p = new Point();
+ Context c = ImageWallpaper.this.getApplicationContext();
+ WindowManager wm = (WindowManager)c.getSystemService(Context.WINDOW_SERVICE);
+ Display d = wm.getDefaultDisplay();
+ d.getRealSize(p);
+ return p;
+ }
+
void drawFrame() {
+ int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)).
+ getDefaultDisplay().getRotation();
+
+ // 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) {
+ // Update surface size (if necessary)
+ updateSurfaceSize(getSurfaceHolder());
+ }
SurfaceHolder sh = getSurfaceHolder();
final Rect frame = sh.getSurfaceFrame();
final int dw = frame.width();
final int dh = frame.height();
- int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)).
- getDefaultDisplay().getRotation();
boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth || dh != mLastSurfaceHeight;
boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation;
@@ -343,10 +388,21 @@
}
}
- final int availw = dw - mBackground.getWidth();
- final int availh = dh - mBackground.getHeight();
- int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2);
- int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
+ // Center the scaled image
+ mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(),
+ dh / (float) mBackground.getHeight()));
+ final int availw = dw - (int) (mBackground.getWidth() * mScale);
+ final int availh = dh - (int) (mBackground.getHeight() * mScale);
+ int xPixels = availw / 2;
+ int yPixels = availh / 2;
+
+ // Adjust the image for xOffset/yOffset values. If window manager is handling offsets,
+ // mXOffset and mYOffset are set to 0.5f by default and therefore xPixels and yPixels
+ // will remain unchanged
+ final int availwUnscaled = dw - mBackground.getWidth();
+ final int availhUnscaled = dh - mBackground.getHeight();
+ if (availwUnscaled < 0) xPixels += (int)(availwUnscaled * (mXOffset - .5f) + .5f);
+ if (availhUnscaled < 0) yPixels += (int)(availhUnscaled * (mYOffset - .5f) + .5f);
mOffsetsChanged = false;
mRedrawNeeded = false;
@@ -354,8 +410,6 @@
mLastSurfaceWidth = dw;
mLastSurfaceHeight = dh;
}
- mLastXTranslation = xPixels;
- mLastYTranslation = yPixels;
if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since the image has not "
@@ -363,6 +417,8 @@
}
return;
}
+ mLastXTranslation = xPixels;
+ mLastYTranslation = yPixels;
if (DEBUG) {
Log.d(TAG, "Redrawing wallpaper");
@@ -391,7 +447,11 @@
Throwable exception = null;
try {
mBackground = null;
+ mBackgroundWidth = -1;
+ mBackgroundHeight = -1;
mBackground = mWallpaperManager.getBitmap();
+ mBackgroundWidth = mBackground.getWidth();
+ mBackgroundHeight = mBackground.getHeight();
} catch (RuntimeException e) {
exception = e;
} catch (OutOfMemoryError e) {
@@ -400,6 +460,8 @@
if (exception != null) {
mBackground = null;
+ mBackgroundWidth = -1;
+ mBackgroundHeight = -1;
// 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.
@@ -413,24 +475,27 @@
}
}
- private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int x, int y) {
+ private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int left, int top) {
Canvas c = sh.lockCanvas();
if (c != null) {
try {
if (DEBUG) {
- Log.d(TAG, "Redrawing: x=" + x + ", y=" + y);
+ Log.d(TAG, "Redrawing: left=" + left + ", top=" + top);
}
- c.translate(x, y);
+ 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(0, 0, mBackground.getWidth(), mBackground.getHeight(),
+ c.clipRect(left, top, right, bottom,
Op.DIFFERENCE);
c.drawColor(0xff000000);
c.restore();
}
if (mBackground != null) {
- c.drawBitmap(mBackground, 0, 0, null);
+ RectF dest = new RectF(left, top, right, bottom);
+ // add a filter bitmap?
+ c.drawBitmap(mBackground, null, dest, null);
}
} finally {
sh.unlockCanvasAndPost(c);
@@ -441,8 +506,8 @@
private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) {
if (!initGL(sh)) return false;
- final float right = left + mBackground.getWidth();
- final float bottom = top + mBackground.getHeight();
+ final float right = left + mBackground.getWidth() * mScale;
+ final float bottom = top + mBackground.getHeight() * mScale;
final Rect frame = sh.getSurfaceFrame();
final Matrix4f ortho = new Matrix4f();