auto import from //depot/cupcake/@132589
This commit is contained in:
@@ -19,7 +19,6 @@ package android.gadget;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -63,11 +62,7 @@ public class GadgetHost {
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateHandler extends Handler {
|
||||
public UpdateHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
Handler mHandler = new Handler() {
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case HANDLE_UPDATE: {
|
||||
@@ -80,9 +75,7 @@ public class GadgetHost {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handler mHandler;
|
||||
};
|
||||
|
||||
int mHostId;
|
||||
Callbacks mCallbacks = new Callbacks();
|
||||
@@ -91,7 +84,6 @@ public class GadgetHost {
|
||||
public GadgetHost(Context context, int hostId) {
|
||||
mContext = context;
|
||||
mHostId = hostId;
|
||||
mHandler = new UpdateHandler(context.getMainLooper());
|
||||
synchronized (sServiceLock) {
|
||||
if (sService == null) {
|
||||
IBinder b = ServiceManager.getService(Context.GADGET_SERVICE);
|
||||
|
||||
@@ -18,13 +18,7 @@ package android.gadget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
@@ -35,23 +29,16 @@ import android.view.animation.Animation;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ViewAnimator;
|
||||
|
||||
/**
|
||||
* Provides the glue to show gadget views. This class offers automatic animation
|
||||
* between updates, and will try recycling old views for each incoming
|
||||
* {@link RemoteViews}.
|
||||
*/
|
||||
public class GadgetHostView extends FrameLayout {
|
||||
public class GadgetHostView extends ViewAnimator implements Animation.AnimationListener {
|
||||
static final String TAG = "GadgetHostView";
|
||||
static final boolean LOGD = false;
|
||||
static final boolean CROSSFADE = false;
|
||||
|
||||
static final int VIEW_MODE_NOINIT = 0;
|
||||
static final int VIEW_MODE_CONTENT = 1;
|
||||
static final int VIEW_MODE_ERROR = 2;
|
||||
static final int VIEW_MODE_DEFAULT = 3;
|
||||
|
||||
static final int FADE_DURATION = 1000;
|
||||
static final boolean LOGD = Config.LOGD || true;
|
||||
|
||||
// When we're inflating the initialLayout for a gadget, we only allow
|
||||
// views that are allowed in RemoteViews.
|
||||
@@ -60,17 +47,28 @@ public class GadgetHostView extends FrameLayout {
|
||||
return clazz.isAnnotationPresent(RemoteViews.RemoteView.class);
|
||||
}
|
||||
};
|
||||
|
||||
Context mContext;
|
||||
|
||||
Context mLocalContext;
|
||||
|
||||
int mGadgetId;
|
||||
GadgetProviderInfo mInfo;
|
||||
View mView;
|
||||
int mViewMode = VIEW_MODE_NOINIT;
|
||||
int mLayoutId = -1;
|
||||
long mFadeStartTime = -1;
|
||||
Bitmap mOld;
|
||||
Paint mOldPaint = new Paint();
|
||||
|
||||
View mActiveView = null;
|
||||
View mStaleView = null;
|
||||
|
||||
int mActiveLayoutId = -1;
|
||||
int mStaleLayoutId = -1;
|
||||
|
||||
/**
|
||||
* Last set of {@link RemoteViews} applied to {@link #mActiveView}
|
||||
*/
|
||||
RemoteViews mActiveActions = null;
|
||||
|
||||
/**
|
||||
* Flag indicating that {@link #mActiveActions} has been applied to
|
||||
* {@link #mStaleView}, meaning it's readyto recycle.
|
||||
*/
|
||||
boolean mStalePrepared = false;
|
||||
|
||||
/**
|
||||
* Create a host view. Uses default fade animations.
|
||||
@@ -88,13 +86,27 @@ public class GadgetHostView extends FrameLayout {
|
||||
*/
|
||||
public GadgetHostView(Context context, int animationIn, int animationOut) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mLocalContext = context;
|
||||
|
||||
// Prepare our default transition animations
|
||||
setAnimateFirstView(true);
|
||||
setInAnimation(context, animationIn);
|
||||
setOutAnimation(context, animationOut);
|
||||
|
||||
// Watch for animation events to prepare recycling
|
||||
Animation inAnimation = getInAnimation();
|
||||
if (inAnimation != null) {
|
||||
inAnimation.setAnimationListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the gadget that will be displayed by this view.
|
||||
*/
|
||||
public void setGadget(int gadgetId, GadgetProviderInfo info) {
|
||||
if (mInfo != null) {
|
||||
// TODO: remove the old view, or whatever
|
||||
}
|
||||
mGadgetId = gadgetId;
|
||||
mInfo = info;
|
||||
}
|
||||
@@ -107,141 +119,92 @@ public class GadgetHostView extends FrameLayout {
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
// When our transition animation finishes, we should try bringing our
|
||||
// newly-stale view up to the current view.
|
||||
if (mActiveActions != null &&
|
||||
mStaleLayoutId == mActiveActions.getLayoutId()) {
|
||||
if (LOGD) Log.d(TAG, "after animation, layoutId matched so we're recycling old view");
|
||||
mActiveActions.reapply(mLocalContext, mStaleView);
|
||||
mStalePrepared = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
}
|
||||
|
||||
public void onAnimationStart(Animation animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a set of {@link RemoteViews} coming in as an update from the
|
||||
* gadget provider. Will animate into these new views as needed.
|
||||
*/
|
||||
public void updateGadget(RemoteViews remoteViews) {
|
||||
if (LOGD) Log.d(TAG, "updateGadget called mOld=" + mOld);
|
||||
if (LOGD) Log.d(TAG, "updateGadget called");
|
||||
|
||||
boolean recycled = false;
|
||||
View content = null;
|
||||
View newContent = null;
|
||||
Exception exception = null;
|
||||
|
||||
// Capture the old view into a bitmap so we can do the crossfade.
|
||||
if (CROSSFADE) {
|
||||
if (mFadeStartTime < 0) {
|
||||
if (mView != null) {
|
||||
final int width = mView.getWidth();
|
||||
final int height = mView.getHeight();
|
||||
try {
|
||||
mOld = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
} catch (OutOfMemoryError e) {
|
||||
// we just won't do the fade
|
||||
mOld = null;
|
||||
}
|
||||
if (mOld != null) {
|
||||
//mView.drawIntoBitmap(mOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remoteViews == null) {
|
||||
if (mViewMode == VIEW_MODE_DEFAULT) {
|
||||
// We've already done this -- nothing to do.
|
||||
return;
|
||||
}
|
||||
content = getDefaultView();
|
||||
mLayoutId = -1;
|
||||
mViewMode = VIEW_MODE_DEFAULT;
|
||||
} else {
|
||||
int layoutId = remoteViews.getLayoutId();
|
||||
|
||||
// If our stale view has been prepared to match active, and the new
|
||||
// layout matches, try recycling it
|
||||
if (content == null && layoutId == mLayoutId) {
|
||||
try {
|
||||
remoteViews.reapply(mContext, mView);
|
||||
content = mView;
|
||||
recycled = true;
|
||||
if (LOGD) Log.d(TAG, "was able to recycled existing layout");
|
||||
} catch (RuntimeException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
// Try normal RemoteView inflation
|
||||
if (content == null) {
|
||||
try {
|
||||
content = remoteViews.apply(mContext, this);
|
||||
if (LOGD) Log.d(TAG, "had to inflate new layout");
|
||||
} catch (RuntimeException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
mLayoutId = layoutId;
|
||||
mViewMode = VIEW_MODE_CONTENT;
|
||||
newContent = getDefaultView();
|
||||
}
|
||||
|
||||
if (content == null) {
|
||||
if (mViewMode == VIEW_MODE_ERROR) {
|
||||
// We've already done this -- nothing to do.
|
||||
return ;
|
||||
// If our stale view has been prepared to match active, and the new
|
||||
// layout matches, try recycling it
|
||||
if (newContent == null && mStalePrepared &&
|
||||
remoteViews.getLayoutId() == mStaleLayoutId) {
|
||||
try {
|
||||
remoteViews.reapply(mLocalContext, mStaleView);
|
||||
newContent = mStaleView;
|
||||
recycled = true;
|
||||
if (LOGD) Log.d(TAG, "was able to recycled existing layout");
|
||||
} catch (RuntimeException e) {
|
||||
exception = e;
|
||||
}
|
||||
Log.w(TAG, "updateGadget couldn't find any view, using error view", exception);
|
||||
content = getErrorView();
|
||||
mViewMode = VIEW_MODE_ERROR;
|
||||
}
|
||||
|
||||
// Try normal RemoteView inflation
|
||||
if (newContent == null) {
|
||||
try {
|
||||
newContent = remoteViews.apply(mLocalContext, this);
|
||||
if (LOGD) Log.d(TAG, "had to inflate new layout");
|
||||
} catch (RuntimeException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (exception != null && LOGD) {
|
||||
Log.w(TAG, "Error inflating gadget " + getGadgetInfo(), exception);
|
||||
}
|
||||
|
||||
if (newContent == null) {
|
||||
// TODO: Should we throw an exception here for the host activity to catch?
|
||||
// Maybe we should show a generic error widget.
|
||||
if (LOGD) Log.d(TAG, "updateGadget couldn't find any view, so inflating error");
|
||||
newContent = getErrorView();
|
||||
}
|
||||
|
||||
if (!recycled) {
|
||||
prepareView(content);
|
||||
addView(content);
|
||||
prepareView(newContent);
|
||||
addView(newContent);
|
||||
}
|
||||
|
||||
if (mView != content) {
|
||||
removeView(mView);
|
||||
mView = content;
|
||||
}
|
||||
|
||||
if (CROSSFADE) {
|
||||
if (mFadeStartTime < 0) {
|
||||
// if there is already an animation in progress, don't do anything --
|
||||
// the new view will pop in on top of the old one during the cross fade,
|
||||
// and that looks okay.
|
||||
mFadeStartTime = SystemClock.uptimeMillis();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
if (CROSSFADE) {
|
||||
int alpha;
|
||||
int l = child.getLeft();
|
||||
int t = child.getTop();
|
||||
if (mFadeStartTime > 0) {
|
||||
alpha = (int)(((drawingTime-mFadeStartTime)*255)/FADE_DURATION);
|
||||
if (alpha > 255) {
|
||||
alpha = 255;
|
||||
}
|
||||
Log.d(TAG, "drawChild alpha=" + alpha + " l=" + l + " t=" + t
|
||||
+ " w=" + child.getWidth());
|
||||
if (alpha != 255 && mOld != null) {
|
||||
mOldPaint.setAlpha(255-alpha);
|
||||
//canvas.drawBitmap(mOld, l, t, mOldPaint);
|
||||
}
|
||||
} else {
|
||||
alpha = 255;
|
||||
}
|
||||
int restoreTo = canvas.saveLayerAlpha(l, t, child.getWidth(), child.getHeight(), alpha,
|
||||
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
|
||||
boolean rv = super.drawChild(canvas, child, drawingTime);
|
||||
canvas.restoreToCount(restoreTo);
|
||||
if (alpha < 255) {
|
||||
invalidate();
|
||||
} else {
|
||||
mFadeStartTime = -1;
|
||||
if (mOld != null) {
|
||||
mOld.recycle();
|
||||
mOld = null;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
} else {
|
||||
return super.drawChild(canvas, child, drawingTime);
|
||||
|
||||
showNext();
|
||||
|
||||
if (!recycled) {
|
||||
removeView(mStaleView);
|
||||
}
|
||||
|
||||
mStalePrepared = false;
|
||||
mActiveActions = remoteViews;
|
||||
|
||||
mStaleView = mActiveView;
|
||||
mActiveView = newContent;
|
||||
|
||||
mStaleLayoutId = mActiveLayoutId;
|
||||
mActiveLayoutId = (remoteViews == null) ? -1 : remoteViews.getLayoutId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,7 +234,7 @@ public class GadgetHostView extends FrameLayout {
|
||||
|
||||
try {
|
||||
if (mInfo != null) {
|
||||
Context theirContext = mContext.createPackageContext(
|
||||
Context theirContext = mLocalContext.createPackageContext(
|
||||
mInfo.provider.getPackageName(), 0 /* no flags */);
|
||||
LayoutInflater inflater = (LayoutInflater)
|
||||
theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
@@ -303,9 +266,9 @@ public class GadgetHostView extends FrameLayout {
|
||||
* Inflate and return a view that represents an error state.
|
||||
*/
|
||||
protected View getErrorView() {
|
||||
TextView tv = new TextView(mContext);
|
||||
tv.setText(com.android.internal.R.string.gadget_host_error_inflating);
|
||||
// TODO: get this color from somewhere.
|
||||
TextView tv = new TextView(mLocalContext);
|
||||
// TODO: move this error string and background color into resources
|
||||
tv.setText("Error inflating gadget");
|
||||
tv.setBackgroundColor(Color.argb(127, 0, 0, 0));
|
||||
return tv;
|
||||
}
|
||||
|
||||
@@ -300,21 +300,5 @@ public class GadgetManager {
|
||||
throw new RuntimeException("system server dead?", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of gadgetIds that have been bound to the given gadget
|
||||
* provider.
|
||||
*
|
||||
* @param provider The {@link android.content.BroadcastReceiver} that is the
|
||||
* gadget provider to find gadgetIds for.
|
||||
*/
|
||||
public int[] getGadgetIds(ComponentName provider) {
|
||||
try {
|
||||
return sService.getGadgetIds(provider);
|
||||
}
|
||||
catch (RemoteException e) {
|
||||
throw new RuntimeException("system server dead?", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user