auto import from //depot/cupcake/@132589

This commit is contained in:
The Android Open Source Project
2009-03-03 14:04:24 -08:00
parent 3dec7d563a
commit 076357b856
310 changed files with 4072 additions and 18131 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}
}
}