Merge "Fix Bitmap leaks in ImageWallpaper" into lmp-mr1-dev

This commit is contained in:
Adrian Roos
2014-11-17 13:50:56 +00:00
committed by Android (Google) Code Review

View File

@@ -174,7 +174,7 @@ public class ImageWallpaper extends WallpaperService {
public void trimMemory(int level) { public void trimMemory(int level) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW && if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW &&
mBackground != null && mIsHwAccelerated) { mBackground != null) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "trimMemory"); Log.d(TAG, "trimMemory");
} }
@@ -212,6 +212,7 @@ public class ImageWallpaper extends WallpaperService {
unregisterReceiver(mReceiver); unregisterReceiver(mReceiver);
} }
mBackground = null; mBackground = null;
mWallpaperManager.forgetLoadedWallpaper();
} }
void updateSurfaceSize(SurfaceHolder surfaceHolder) { void updateSurfaceSize(SurfaceHolder surfaceHolder) {
@@ -337,111 +338,116 @@ public class ImageWallpaper extends WallpaperService {
} }
void drawFrame() { void drawFrame() {
int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)). try {
getDefaultDisplay().getRotation(); int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)).
getDefaultDisplay().getRotation();
// Sometimes a wallpaper is not large enough to cover the screen in one dimension. // 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 // Call updateSurfaceSize -- it will only actually do the update if the dimensions
// should change // should change
if (newRotation != mLastRotation) { if (newRotation != mLastRotation) {
// Update surface size (if necessary) // Update surface size (if necessary)
updateSurfaceSize(getSurfaceHolder()); updateSurfaceSize(getSurfaceHolder());
}
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;
if (!redrawNeeded && !mOffsetsChanged) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
+ "and offsets have not changed.");
} }
return; SurfaceHolder sh = getSurfaceHolder();
} final Rect frame = sh.getSurfaceFrame();
mLastRotation = newRotation; final int dw = frame.width();
final int dh = frame.height();
boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth
|| dh != mLastSurfaceHeight;
// Load bitmap if it is not yet loaded or if it was loaded at a different size boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation;
if (mBackground == null || surfaceDimensionsChanged) { if (!redrawNeeded && !mOffsetsChanged) {
if (DEBUG) {
Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " +
mBackground + ", " +
((mBackground == null) ? 0 : mBackground.getWidth()) + ", " +
((mBackground == null) ? 0 : mBackground.getHeight()) + ", " +
dw + ", " + dh);
}
mWallpaperManager.forgetLoadedWallpaper();
updateWallpaperLocked();
if (mBackground == null) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Unable to load bitmap"); Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
+ "and offsets have not changed.");
} }
return; return;
} }
if (DEBUG) { mLastRotation = newRotation;
if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) {
Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " + // Load bitmap if it is not yet loaded or if it was loaded at a different size
dw + ", " + dh + ", " + mBackground.getWidth() + ", " + if (mBackground == null || surfaceDimensionsChanged) {
mBackground.getHeight()); if (DEBUG) {
Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " +
mBackground + ", " +
((mBackground == null) ? 0 : mBackground.getWidth()) + ", " +
((mBackground == null) ? 0 : mBackground.getHeight()) + ", " +
dw + ", " + dh);
}
mWallpaperManager.forgetLoadedWallpaper();
updateWallpaperLocked();
if (mBackground == null) {
if (DEBUG) {
Log.d(TAG, "Unable to load bitmap");
}
return;
}
if (DEBUG) {
if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) {
Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " +
dw + ", " + dh + ", " + mBackground.getWidth() + ", " +
mBackground.getHeight());
}
} }
} }
}
// Center the scaled image // Center the scaled image
mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(), mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(),
dh / (float) mBackground.getHeight())); dh / (float) mBackground.getHeight()));
final int availw = dw - (int) (mBackground.getWidth() * mScale); final int availw = dw - (int) (mBackground.getWidth() * mScale);
final int availh = dh - (int) (mBackground.getHeight() * mScale); final int availh = dh - (int) (mBackground.getHeight() * mScale);
int xPixels = availw / 2; int xPixels = availw / 2;
int yPixels = availh / 2; int yPixels = availh / 2;
// Adjust the image for xOffset/yOffset values. If window manager is handling offsets, // 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 // mXOffset and mYOffset are set to 0.5f by default and therefore xPixels and yPixels
// will remain unchanged // will remain unchanged
final int availwUnscaled = dw - mBackground.getWidth(); final int availwUnscaled = dw - mBackground.getWidth();
final int availhUnscaled = dh - mBackground.getHeight(); final int availhUnscaled = dh - mBackground.getHeight();
if (availwUnscaled < 0) xPixels += (int)(availwUnscaled * (mXOffset - .5f) + .5f); if (availwUnscaled < 0)
if (availhUnscaled < 0) yPixels += (int)(availhUnscaled * (mYOffset - .5f) + .5f); xPixels += (int) (availwUnscaled * (mXOffset - .5f) + .5f);
if (availhUnscaled < 0)
yPixels += (int) (availhUnscaled * (mYOffset - .5f) + .5f);
mOffsetsChanged = false; mOffsetsChanged = false;
mRedrawNeeded = false; mRedrawNeeded = false;
if (surfaceDimensionsChanged) { if (surfaceDimensionsChanged) {
mLastSurfaceWidth = dw; mLastSurfaceWidth = dw;
mLastSurfaceHeight = dh; 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; if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
} if (DEBUG) {
mLastXTranslation = xPixels; Log.d(TAG, "Suppressed drawFrame since the image has not "
mLastYTranslation = yPixels; + "actually moved an integral number of pixels.");
}
return;
}
mLastXTranslation = xPixels;
mLastYTranslation = yPixels;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Redrawing wallpaper"); Log.d(TAG, "Redrawing wallpaper");
} }
if (mIsHwAccelerated) { if (mIsHwAccelerated) {
if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
}
} else {
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
} }
} else { } finally {
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); if (FIXED_SIZED_SURFACE && !mIsHwAccelerated) {
if (FIXED_SIZED_SURFACE) {
// If the surface is fixed-size, we should only need to // If the surface is fixed-size, we should only need to
// draw it once and then we'll let the window manager // draw it once and then we'll let the window manager
// position it appropriately. As such, we no longer needed // position it appropriately. As such, we no longer needed
// the loaded bitmap. Yay! // the loaded bitmap. Yay!
// hw-accelerated path retains bitmap for faster rotation // hw-accelerated renderer retains bitmap for faster rotation
mBackground = null; mBackground = null;
mWallpaperManager.forgetLoadedWallpaper(); mWallpaperManager.forgetLoadedWallpaper();
} }
} }
} }
private void updateWallpaperLocked() { private void updateWallpaperLocked() {