am d023f9a9: Merge change 24829 into eclair
Merge commit 'd023f9a9a90705410250cd86bc6446c738423a99' into eclair-plus-aosp * commit 'd023f9a9a90705410250cd86bc6446c738423a99': Some optizations to wallpaper drawing/scrolling.
This commit is contained in:
@@ -22,7 +22,9 @@ import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -56,9 +58,96 @@ public class WallpaperManager {
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
/**
|
||||
* Special drawable that draws a wallpaper as fast as possible. Assumes
|
||||
* no scaling or placement off (0,0) of the wallpaper (this should be done
|
||||
* at the time the bitmap is loaded).
|
||||
*/
|
||||
static class FastBitmapDrawable extends Drawable {
|
||||
private final Bitmap mBitmap;
|
||||
private final int mWidth;
|
||||
private final int mHeight;
|
||||
private int mDrawLeft;
|
||||
private int mDrawTop;
|
||||
|
||||
private FastBitmapDrawable(Bitmap bitmap) {
|
||||
mBitmap = bitmap;
|
||||
mWidth = bitmap.getWidth();
|
||||
mHeight = bitmap.getHeight();
|
||||
setBounds(0, 0, mWidth, mHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.OPAQUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int left, int top, int right, int bottom) {
|
||||
mDrawLeft = left + (right-left - mWidth) / 2;
|
||||
mDrawTop = top + (bottom-top - mHeight) / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(Rect bounds) {
|
||||
// TODO Auto-generated method stub
|
||||
super.setBounds(bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Not supported with this drawable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Not supported with this drawable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDither(boolean dither) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Not supported with this drawable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilterBitmap(boolean filter) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Not supported with this drawable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinimumWidth() {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinimumHeight() {
|
||||
return mHeight;
|
||||
}
|
||||
}
|
||||
|
||||
static class Globals extends IWallpaperManagerCallback.Stub {
|
||||
private IWallpaperManager mService;
|
||||
private Bitmap mWallpaper;
|
||||
private Bitmap mDefaultWallpaper;
|
||||
|
||||
private static final int MSG_CLEAR_WALLPAPER = 1;
|
||||
|
||||
@@ -74,6 +163,7 @@ public class WallpaperManager {
|
||||
case MSG_CLEAR_WALLPAPER:
|
||||
synchronized (this) {
|
||||
mWallpaper = null;
|
||||
mDefaultWallpaper = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -90,12 +180,19 @@ public class WallpaperManager {
|
||||
mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER);
|
||||
}
|
||||
|
||||
public Bitmap peekWallpaperBitmap(Context context) {
|
||||
public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) {
|
||||
synchronized (this) {
|
||||
if (mWallpaper != null) {
|
||||
return mWallpaper;
|
||||
}
|
||||
if (mDefaultWallpaper != null) {
|
||||
return mDefaultWallpaper;
|
||||
}
|
||||
mWallpaper = getCurrentWallpaperLocked(context);
|
||||
if (mWallpaper == null && returnDefault) {
|
||||
mDefaultWallpaper = getDefaultWallpaperLocked(context);
|
||||
return mDefaultWallpaper;
|
||||
}
|
||||
return mWallpaper;
|
||||
}
|
||||
}
|
||||
@@ -134,48 +231,48 @@ public class WallpaperManager {
|
||||
fd.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
if (bm == null) {
|
||||
|
||||
return generateBitmap(context, bm, width, height);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Bitmap getDefaultWallpaperLocked(Context context) {
|
||||
try {
|
||||
InputStream is = context.getResources().openRawResource(
|
||||
com.android.internal.R.drawable.default_wallpaper);
|
||||
if (is != null) {
|
||||
int width = mService.getWidthHint();
|
||||
int height = mService.getHeightHint();
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
// Degenerate case: no size requested, just load
|
||||
// bitmap as-is.
|
||||
Bitmap bm = BitmapFactory.decodeStream(is, null, null);
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
if (bm != null) {
|
||||
bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
|
||||
// This is the final bitmap we want to return.
|
||||
Bitmap newbm = Bitmap.createBitmap(width, height,
|
||||
bm.getConfig());
|
||||
newbm.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
Canvas c = new Canvas(newbm);
|
||||
c.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
Rect targetRect = new Rect();
|
||||
targetRect.left = targetRect.top = 0;
|
||||
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 = 1.0f;
|
||||
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;
|
||||
// Load the bitmap with full color depth, to preserve
|
||||
// quality for later processing.
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inDither = false;
|
||||
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
Bitmap bm = BitmapFactory.decodeStream(is, null, options);
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
targetRect.offset(deltaw/2, deltah/2);
|
||||
Paint paint = new Paint();
|
||||
paint.setFilterBitmap(true);
|
||||
paint.setDither(true);
|
||||
c.drawBitmap(bm, null, targetRect, paint);
|
||||
|
||||
bm.recycle();
|
||||
return newbm;
|
||||
return generateBitmap(context, bm, width, height);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
@@ -219,9 +316,13 @@ public class WallpaperManager {
|
||||
* @return Returns a Drawable object that will draw the wallpaper.
|
||||
*/
|
||||
public Drawable getDrawable() {
|
||||
Drawable dr = peekDrawable();
|
||||
return dr != null ? dr : Resources.getSystem().getDrawable(
|
||||
com.android.internal.R.drawable.default_wallpaper);
|
||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
|
||||
if (bm != null) {
|
||||
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
|
||||
dr.setDither(false);
|
||||
return dr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,8 +335,51 @@ public class WallpaperManager {
|
||||
* null pointer if these is none.
|
||||
*/
|
||||
public Drawable peekDrawable() {
|
||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext);
|
||||
return bm != null ? new BitmapDrawable(mContext.getResources(), bm) : null;
|
||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
|
||||
if (bm != null) {
|
||||
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
|
||||
dr.setDither(false);
|
||||
return dr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #peekFastDrawable}, but always returns a valid Drawable. If
|
||||
* no wallpaper is set, the system default wallpaper is returned.
|
||||
*
|
||||
* @return Returns a Drawable object that will draw the wallpaper.
|
||||
*/
|
||||
public Drawable getFastDrawable() {
|
||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
|
||||
if (bm != null) {
|
||||
Drawable dr = new FastBitmapDrawable(bm);
|
||||
return dr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #peekDrawable()}, but the returned Drawable has a number
|
||||
* of limitations to reduce its overhead as much as possible: it will
|
||||
* never scale the wallpaper (only centering it if the requested bounds
|
||||
* do match the bitmap bounds, which should not be typical), doesn't
|
||||
* allow setting an alpha, color filter, or other attributes, etc. The
|
||||
* bounds of the returned drawable will be initialized to the same bounds
|
||||
* as the wallpaper, so normally you will not need to touch it. The
|
||||
* drawable also assumes that it will be used in a context running in
|
||||
* the same density as the screen (not in density compatibility mode).
|
||||
*
|
||||
* @return Returns an optimized Drawable object that will draw the
|
||||
* wallpaper or a null pointer if these is none.
|
||||
*/
|
||||
public Drawable peekFastDrawable() {
|
||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
|
||||
if (bm != null) {
|
||||
Drawable dr = new FastBitmapDrawable(bm);
|
||||
return dr;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,8 +573,10 @@ public class WallpaperManager {
|
||||
*/
|
||||
public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) {
|
||||
try {
|
||||
//Log.v(TAG, "Sending new wallpaper offsets from app...");
|
||||
ViewRoot.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
|
||||
windowToken, xOffset, yOffset);
|
||||
//Log.v(TAG, "...app returning after sending offsets!");
|
||||
} catch (RemoteException e) {
|
||||
// Ignore.
|
||||
}
|
||||
@@ -466,4 +612,51 @@ public class WallpaperManager {
|
||||
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 bm;
|
||||
}
|
||||
bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
|
||||
// This is the final bitmap we want to return.
|
||||
// XXX We should get the pixel depth from the system (to match the
|
||||
// physical display depth), when there is a way.
|
||||
Bitmap newbm = Bitmap.createBitmap(width, height,
|
||||
Bitmap.Config.RGB_565);
|
||||
newbm.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
Canvas c = new Canvas(newbm);
|
||||
c.setDensity(DisplayMetrics.DENSITY_DEVICE);
|
||||
Rect targetRect = new Rect();
|
||||
targetRect.left = targetRect.top = 0;
|
||||
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 = 1.0f;
|
||||
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.setDither(true);
|
||||
c.drawBitmap(bm, null, targetRect, paint);
|
||||
|
||||
bm.recycle();
|
||||
return newbm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ import com.android.internal.util.XmlUtils;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Movie;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
@@ -1699,7 +1697,7 @@ public class Resources {
|
||||
} else {
|
||||
try {
|
||||
InputStream is = mAssets.openNonAsset(
|
||||
value.assetCookie, file, AssetManager.ACCESS_BUFFER);
|
||||
value.assetCookie, file, AssetManager.ACCESS_STREAMING);
|
||||
// System.out.println("Opened file " + file + ": " + is);
|
||||
dr = Drawable.createFromResourceStream(this, value, is,
|
||||
file, null);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class HandlerThread extends Thread {
|
||||
/**
|
||||
* This method returns the Looper associated with this thread. If this thread not been started
|
||||
* or for any reason is isAlive() returns false, this method will return null. If this thread
|
||||
* has been started, this method will blocked until the looper has been initialized.
|
||||
* has been started, this method will block until the looper has been initialized.
|
||||
* @return The looper.
|
||||
*/
|
||||
public Looper getLooper() {
|
||||
@@ -84,6 +84,21 @@ public class HandlerThread extends Thread {
|
||||
return mLooper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the currently running looper to quit. If the thread has not
|
||||
* been started or has finished (that is if {@link #getLooper} returns
|
||||
* null), then false is returned. Otherwise the looper is asked to
|
||||
* quit and true is returned.
|
||||
*/
|
||||
public boolean quit() {
|
||||
Looper looper = getLooper();
|
||||
if (looper != null) {
|
||||
looper.quit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of this thread. See Process.myTid().
|
||||
*/
|
||||
|
||||
@@ -28,9 +28,11 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.LogPrinter;
|
||||
import android.view.Gravity;
|
||||
import android.view.IWindowSession;
|
||||
import android.view.MotionEvent;
|
||||
@@ -74,6 +76,8 @@ public abstract class WallpaperService extends Service {
|
||||
private static final int MSG_WINDOW_RESIZED = 10030;
|
||||
private static final int MSG_TOUCH_EVENT = 10040;
|
||||
|
||||
private Looper mCallbackLooper;
|
||||
|
||||
/**
|
||||
* The actual implementation of a wallpaper. A wallpaper service may
|
||||
* have multiple instances running (for example as a real wallpaper
|
||||
@@ -120,6 +124,7 @@ public abstract class WallpaperService extends Service {
|
||||
boolean mOffsetMessageEnqueued;
|
||||
float mPendingXOffset;
|
||||
float mPendingYOffset;
|
||||
boolean mPendingSync;
|
||||
MotionEvent mPendingMove;
|
||||
|
||||
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@@ -212,10 +217,14 @@ public abstract class WallpaperService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchWallpaperOffsets(float x, float y) {
|
||||
public void dispatchWallpaperOffsets(float x, float y, boolean sync) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y);
|
||||
mPendingXOffset = x;
|
||||
mPendingYOffset = y;
|
||||
if (sync) {
|
||||
mPendingSync = true;
|
||||
}
|
||||
if (!mOffsetMessageEnqueued) {
|
||||
mOffsetMessageEnqueued = true;
|
||||
Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
|
||||
@@ -551,9 +560,12 @@ public abstract class WallpaperService extends Service {
|
||||
|
||||
float xOffset;
|
||||
float yOffset;
|
||||
boolean sync;
|
||||
synchronized (mLock) {
|
||||
xOffset = mPendingXOffset;
|
||||
yOffset = mPendingYOffset;
|
||||
sync = mPendingSync;
|
||||
mPendingSync = false;
|
||||
mOffsetMessageEnqueued = false;
|
||||
}
|
||||
if (DEBUG) Log.v(TAG, "Offsets change in " + this
|
||||
@@ -563,6 +575,14 @@ public abstract class WallpaperService extends Service {
|
||||
final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
|
||||
final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
|
||||
onOffsetsChanged(xOffset, yOffset, xPixels, yPixels);
|
||||
|
||||
if (sync) {
|
||||
try {
|
||||
if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
|
||||
mSession.wallpaperOffsetsComplete(mWindow.asBinder());
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void detach() {
|
||||
@@ -622,7 +642,13 @@ public abstract class WallpaperService extends Service {
|
||||
IWallpaperEngineWrapper(WallpaperService context,
|
||||
IWallpaperConnection conn, IBinder windowToken,
|
||||
int windowType, boolean isPreview, int reqWidth, int reqHeight) {
|
||||
mCaller = new HandlerCaller(context, this);
|
||||
if (DEBUG && mCallbackLooper != null) {
|
||||
mCallbackLooper.setMessageLogging(new LogPrinter(Log.VERBOSE, TAG));
|
||||
}
|
||||
mCaller = new HandlerCaller(context,
|
||||
mCallbackLooper != null
|
||||
? mCallbackLooper : context.getMainLooper(),
|
||||
this);
|
||||
mConnection = conn;
|
||||
mWindowToken = windowToken;
|
||||
mWindowType = windowType;
|
||||
@@ -736,5 +762,18 @@ public abstract class WallpaperService extends Service {
|
||||
return new IWallpaperServiceWrapper(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows subclasses to change the thread that most callbacks
|
||||
* occur on. Currently hidden because it is mostly needed for the
|
||||
* image wallpaper (which runs in the system process and doesn't want
|
||||
* to get stuck running on that seriously in use main thread). Not
|
||||
* exposed right now because the semantics of this are not totally
|
||||
* well defined and some callbacks can still happen on the main thread).
|
||||
* @hide
|
||||
*/
|
||||
public void setCallbackLooper(Looper looper) {
|
||||
mCallbackLooper = looper;
|
||||
}
|
||||
|
||||
public abstract Engine onCreateEngine();
|
||||
}
|
||||
|
||||
@@ -60,5 +60,5 @@ oneway interface IWindow {
|
||||
/**
|
||||
* Called for wallpaper windows when their offsets change.
|
||||
*/
|
||||
void dispatchWallpaperOffsets(float x, float y);
|
||||
void dispatchWallpaperOffsets(float x, float y, boolean sync);
|
||||
}
|
||||
|
||||
@@ -114,4 +114,6 @@ interface IWindowSession {
|
||||
* larger than the screen, set the offset within the screen.
|
||||
*/
|
||||
void setWallpaperPosition(IBinder windowToken, float x, float y);
|
||||
|
||||
void wallpaperOffsetsComplete(IBinder window);
|
||||
}
|
||||
|
||||
@@ -2868,7 +2868,13 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchWallpaperOffsets(float x, float y) {
|
||||
public void dispatchWallpaperOffsets(float x, float y, boolean sync) {
|
||||
if (sync) {
|
||||
try {
|
||||
sWindowSession.wallpaperOffsetsComplete(asBinder());
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,13 @@ public class HandlerCaller {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public HandlerCaller(Context context, Looper looper, Callback callback) {
|
||||
mContext = context;
|
||||
mMainLooper = looper;
|
||||
mH = new MyHandler(mMainLooper);
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public SomeArgs obtainArgs() {
|
||||
synchronized (mH) {
|
||||
SomeArgs args = mArgsPool;
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.app.WallpaperManager;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Process;
|
||||
import android.service.wallpaper.WallpaperService;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
@@ -33,20 +35,29 @@ import android.content.BroadcastReceiver;
|
||||
*/
|
||||
public class ImageWallpaper extends WallpaperService {
|
||||
WallpaperManager mWallpaperManager;
|
||||
private HandlerThread mThread;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
|
||||
mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND);
|
||||
mThread.start();
|
||||
setCallbackLooper(mThread.getLooper());
|
||||
}
|
||||
|
||||
public Engine onCreateEngine() {
|
||||
return new DrawableEngine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mThread.quit();
|
||||
}
|
||||
|
||||
class DrawableEngine extends Engine {
|
||||
private final Object mLock = new Object();
|
||||
private final Rect mBounds = new Rect();
|
||||
private WallpaperObserver mReceiver;
|
||||
Drawable mBackground;
|
||||
float mXOffset;
|
||||
@@ -56,6 +67,9 @@ public class ImageWallpaper extends WallpaperService {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
updateWallpaper();
|
||||
drawFrame();
|
||||
// Assume we are the only one using the wallpaper in this
|
||||
// process, and force a GC now to release the old wallpaper.
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +81,6 @@ public class ImageWallpaper extends WallpaperService {
|
||||
registerReceiver(mReceiver, filter);
|
||||
updateWallpaper();
|
||||
surfaceHolder.setSizeFromLayout();
|
||||
//setTouchEventsEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,11 +150,7 @@ public class ImageWallpaper extends WallpaperService {
|
||||
|
||||
void updateWallpaper() {
|
||||
synchronized (mLock) {
|
||||
mBackground = mWallpaperManager.getDrawable();
|
||||
mBounds.left = mBounds.top = 0;
|
||||
mBounds.right = mBackground.getIntrinsicWidth();
|
||||
mBounds.bottom = mBackground.getIntrinsicHeight();
|
||||
mBackground.setBounds(mBounds);
|
||||
mBackground = mWallpaperManager.getFastDrawable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,12 @@ public class BaseIWindow extends IWindow.Stub {
|
||||
public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
|
||||
}
|
||||
|
||||
public void dispatchWallpaperOffsets(float x, float y) {
|
||||
public void dispatchWallpaperOffsets(float x, float y, boolean sync) {
|
||||
if (sync) {
|
||||
try {
|
||||
mSession.wallpaperOffsetsComplete(asBinder());
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user