diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ActivityThread.java | 12 | ||||
-rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 17 | ||||
-rw-r--r-- | core/java/android/app/IApplicationThread.java | 4 | ||||
-rw-r--r-- | core/java/android/app/SearchDialog.java | 18 | ||||
-rwxr-xr-x | core/java/android/gesture/Gesture.java | 39 | ||||
-rwxr-xr-x | core/java/android/gesture/GestureOverlayView.java | 624 | ||||
-rw-r--r-- | core/java/android/gesture/GestureStroke.java | 59 | ||||
-rwxr-xr-x | core/java/android/gesture/GestureUtilities.java | 21 | ||||
-rw-r--r-- | core/java/android/gesture/TouchThroughGestureListener.java | 178 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 10 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 3 | ||||
-rw-r--r-- | core/java/android/webkit/WebSettings.java | 4 | ||||
-rw-r--r-- | core/java/android/widget/AbsListView.java | 47 | ||||
-rw-r--r-- | core/java/android/widget/FastScroller.java | 21 | ||||
-rw-r--r-- | core/java/android/widget/FrameLayout.java | 29 |
15 files changed, 620 insertions, 466 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1e15d14..06e0a45 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1513,6 +1513,18 @@ public final class ActivityThread { queueOrSendMessage(H.PROFILER_CONTROL, path, start ? 1 : 0); } + public void setSchedulingGroup(int group) { + // Note: do this immediately, since going into the foreground + // should happen regardless of what pending work we have to do + // and the activity manager will wait for us to report back that + // we are done before sending us to the background. + try { + Process.setProcessGroup(Process.myPid(), group); + } catch (Exception e) { + Log.w(TAG, "Failed setting process group to " + group, e); + } + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { long nativeMax = Debug.getNativeHeapSize() / 1024; diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index bcc9302..f243185 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -331,6 +331,14 @@ public abstract class ApplicationThreadNative extends Binder profilerControl(start, path); return true; } + + case SET_SCHEDULING_GROUP_TRANSACTION: + { + data.enforceInterface(IApplicationThread.descriptor); + int group = data.readInt(); + setSchedulingGroup(group); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -672,5 +680,14 @@ class ApplicationThreadProxy implements IApplicationThread { IBinder.FLAG_ONEWAY); data.recycle(); } + + public void setSchedulingGroup(int group) throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IApplicationThread.descriptor); + data.writeInt(group); + mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null, + IBinder.FLAG_ONEWAY); + data.recycle(); + } } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 9f3534b..ec03d3a 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -87,7 +87,8 @@ public interface IApplicationThread extends IInterface { void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException; void requestPss() throws RemoteException; void profilerControl(boolean start, String path) throws RemoteException; - + void setSchedulingGroup(int group) throws RemoteException; + String descriptor = "android.app.IApplicationThread"; int SCHEDULE_PAUSE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; @@ -117,4 +118,5 @@ public interface IApplicationThread extends IInterface { int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25; int REQUEST_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26; int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27; + int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28; } diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index aaaf7bf..ff110c8 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -49,6 +49,7 @@ import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; +import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.KeyEvent; import android.view.MotionEvent; @@ -165,7 +166,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS * @param context Application Context we can use for system acess */ public SearchDialog(Context context) { - super(context, com.android.internal.R.style.Theme_SearchBar); + super(context, com.android.internal.R.style.Theme_GlobalSearchBar); } /** @@ -393,6 +394,21 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS getContext().getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.showSoftInputUnchecked(0, null); } + + // The Dialog uses a ContextThemeWrapper for the context; use this to change the + // theme out from underneath us, between the global search theme and the in-app + // search theme. They are identical except that the global search theme does not + // dim the background of the window (because global search is full screen so it's + // not needed and this should save a little bit of time on global search invocation). + Object context = getContext(); + if (context instanceof ContextThemeWrapper) { + ContextThemeWrapper wrapper = (ContextThemeWrapper) context; + if (globalSearch) { + wrapper.setTheme(com.android.internal.R.style.Theme_GlobalSearchBar); + } else { + wrapper.setTheme(com.android.internal.R.style.Theme_SearchBar); + } + } show(); } diff --git a/core/java/android/gesture/Gesture.java b/core/java/android/gesture/Gesture.java index 14530a1..6aca105 100755 --- a/core/java/android/gesture/Gesture.java +++ b/core/java/android/gesture/Gesture.java @@ -57,6 +57,11 @@ public class Gesture implements Parcelable { mGestureID = GESTURE_ID_BASE + sGestureCount++; } + void recycle() { + mStrokes.clear(); + mBoundingBox.setEmpty(); + } + /** * @return all the strokes of the gesture */ @@ -111,6 +116,40 @@ public class Gesture implements Parcelable { return mBoundingBox; } + public Path toPath() { + return toPath(null); + } + + public Path toPath(Path path) { + if (path == null) path = new Path(); + + final ArrayList<GestureStroke> strokes = mStrokes; + final int count = strokes.size(); + + for (int i = 0; i < count; i++) { + path.addPath(strokes.get(i).getPath()); + } + + return path; + } + + public Path toPath(int width, int height, int edge, int numSample) { + return toPath(null, width, height, edge, numSample); + } + + public Path toPath(Path path, int width, int height, int edge, int numSample) { + if (path == null) path = new Path(); + + final ArrayList<GestureStroke> strokes = mStrokes; + final int count = strokes.size(); + + for (int i = 0; i < count; i++) { + path.addPath(strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample)); + } + + return path; + } + /** * Set the id of the gesture * diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java index 64ddbbd..c21cc55 100755 --- a/core/java/android/gesture/GestureOverlayView.java +++ b/core/java/android/gesture/GestureOverlayView.java @@ -18,51 +18,69 @@ package android.gesture; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; +import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; -import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.AccelerateDecelerateInterpolator; +import android.widget.FrameLayout; +import android.os.SystemClock; import com.android.internal.R; import java.util.ArrayList; /** - * A (transparent) overlay for gesture input that can be placed on top of other - * widgets. + * A transparent overlay for gesture input that can be placed on top of other + * widgets or contain other widgets. * + * @attr ref android.R.styleable#GestureOverlayView_eventsInterceptionEnabled + * @attr ref android.R.styleable#GestureOverlayView_fadeDuration + * @attr ref android.R.styleable#GestureOverlayView_fadeOffset + * @attr ref android.R.styleable#GestureOverlayView_fadeEnabled * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeWidth + * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeAngleThreshold + * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeLengthThreshold + * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeSquarenessThreshold + * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeType * @attr ref android.R.styleable#GestureOverlayView_gestureColor * @attr ref android.R.styleable#GestureOverlayView_uncertainGestureColor - * @attr ref android.R.styleable#GestureOverlayView_fadeDuration - * @attr ref android.R.styleable#GestureOverlayView_fadeOffset */ -public class GestureOverlayView extends View { - private static final int TRANSPARENT_BACKGROUND = 0x00000000; +public class GestureOverlayView extends FrameLayout { + public static final int GESTURE_STROKE_TYPE_SINGLE = 0; + public static final int GESTURE_STROKE_TYPE_MULTIPLE = 1; + + public static final int ORIENTATION_HORIZONTAL = 0; + public static final int ORIENTATION_VERTICAL = 1; + + private static final int FADE_ANIMATION_RATE = 16; private static final boolean GESTURE_RENDERING_ANTIALIAS = true; private static final boolean DITHER_FLAG = true; - private Paint mGesturePaint; - - private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG); - private Bitmap mBitmap; - private Canvas mBitmapCanvas; + private final Paint mGesturePaint = new Paint(); - private long mFadeDuration = 300; - private long mFadeOffset = 300; + private long mFadeDuration = 150; + private long mFadeOffset = 420; private long mFadingStart; + private boolean mFadingHasStarted; + private boolean mFadeEnabled = true; - private float mGestureStroke = 12.0f; + private int mCurrentColor; private int mCertainGestureColor = 0xFFFFFF00; - private int mUncertainGestureColor = 0x3CFFFF00; + private int mUncertainGestureColor = 0x48FFFF00; + private float mGestureStrokeWidth = 12.0f; private int mInvalidateExtraBorder = 10; - // for rendering immediate ink feedback + private int mGestureStrokeType = GESTURE_STROKE_TYPE_SINGLE; + private float mGestureStrokeLengthThreshold = 30.0f; + private float mGestureStrokeSquarenessTreshold = 0.275f; + private float mGestureStrokeAngleThreshold = 40.0f; + + private int mOrientation = ORIENTATION_VERTICAL; + private final Rect mInvalidRect = new Rect(); private final Path mPath = new Path(); @@ -72,41 +90,31 @@ public class GestureOverlayView extends View { private float mCurveEndX; private float mCurveEndY; + private float mTotalLength; + private boolean mIsGesturing = false; + private boolean mInterceptEvents = true; + private boolean mIsListeningForGestures; + // current gesture - private Gesture mCurrentGesture = null; + private Gesture mCurrentGesture; + private final ArrayList<GesturePoint> mStrokeBuffer = new ArrayList<GesturePoint>(100); // TODO: Make this a list of WeakReferences private final ArrayList<OnGestureListener> mOnGestureListeners = new ArrayList<OnGestureListener>(); - private final ArrayList<GesturePoint> mPointBuffer = new ArrayList<GesturePoint>(100); + // TODO: Make this a list of WeakReferences + private final ArrayList<OnGesturePerformedListener> mOnGesturePerformedListeners = + new ArrayList<OnGesturePerformedListener>(); + + private boolean mHandleGestureActions; // fading out effect private boolean mIsFadingOut = false; - private float mFadingAlpha = 1; + private float mFadingAlpha = 1.0f; private final AccelerateDecelerateInterpolator mInterpolator = new AccelerateDecelerateInterpolator(); - private final Runnable mFadingOut = new Runnable() { - public void run() { - if (mIsFadingOut) { - final long now = AnimationUtils.currentAnimationTimeMillis(); - final long duration = now - mFadingStart; - - if (duration > mFadeDuration) { - mIsFadingOut = false; - mPath.rewind(); - mCurrentGesture = null; - mBitmap.eraseColor(TRANSPARENT_BACKGROUND); - } else { - float interpolatedTime = Math.max(0.0f, - Math.min(1.0f, duration / (float) mFadeDuration)); - mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime); - postDelayed(this, 16); - } - invalidate(); - } - } - }; + private final FadeOutRunnable mFadingOut = new FadeOutRunnable(); public GestureOverlayView(Context context) { super(context); @@ -123,41 +131,63 @@ public class GestureOverlayView extends View { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GestureOverlayView, defStyle, 0); - mGestureStroke = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth, - mGestureStroke); - mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1); + mGestureStrokeWidth = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth, + mGestureStrokeWidth); + mInvalidateExtraBorder = Math.max(1, ((int) mGestureStrokeWidth) - 1); mCertainGestureColor = a.getColor(R.styleable.GestureOverlayView_gestureColor, mCertainGestureColor); mUncertainGestureColor = a.getColor(R.styleable.GestureOverlayView_uncertainGestureColor, mUncertainGestureColor); mFadeDuration = a.getInt(R.styleable.GestureOverlayView_fadeDuration, (int) mFadeDuration); mFadeOffset = a.getInt(R.styleable.GestureOverlayView_fadeOffset, (int) mFadeOffset); + mGestureStrokeType = a.getInt(R.styleable.GestureOverlayView_gestureStrokeType, + mGestureStrokeType); + mGestureStrokeLengthThreshold = a.getFloat( + R.styleable.GestureOverlayView_gestureStrokeLengthThreshold, + mGestureStrokeLengthThreshold); + mGestureStrokeAngleThreshold = a.getFloat( + R.styleable.GestureOverlayView_gestureStrokeAngleThreshold, + mGestureStrokeAngleThreshold); + mGestureStrokeSquarenessTreshold = a.getFloat( + R.styleable.GestureOverlayView_gestureStrokeSquarenessThreshold, + mGestureStrokeSquarenessTreshold); + mInterceptEvents = a.getBoolean(R.styleable.GestureOverlayView_eventsInterceptionEnabled, + mInterceptEvents); + mFadeEnabled = a.getBoolean(R.styleable.GestureOverlayView_fadeEnabled, + mFadeEnabled); + mOrientation = a.getInt(R.styleable.GestureOverlayView_orientation, mOrientation); a.recycle(); init(); } + private void init() { + setWillNotDraw(false); + + final Paint gesturePaint = mGesturePaint; + gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS); + gesturePaint.setColor(mCertainGestureColor); + gesturePaint.setStyle(Paint.Style.STROKE); + gesturePaint.setStrokeJoin(Paint.Join.ROUND); + gesturePaint.setStrokeCap(Paint.Cap.ROUND); + gesturePaint.setStrokeWidth(mGestureStrokeWidth); + gesturePaint.setDither(DITHER_FLAG); + + mCurrentColor = mCertainGestureColor; + setPaintAlpha(255); + } + public ArrayList<GesturePoint> getCurrentStroke() { - return mPointBuffer; + return mStrokeBuffer; } - public Gesture getCurrentGesture() { - return mCurrentGesture; + public int getOrientation() { + return mOrientation; } - /** - * Set Gesture color - * - * @param color - */ - public void setGestureDrawingColor(int color) { - mGesturePaint.setColor(color); - if (mCurrentGesture != null) { - mBitmap.eraseColor(TRANSPARENT_BACKGROUND); - mCurrentGesture.draw(mBitmapCanvas, mGesturePaint); - } - invalidate(); + public void setOrientation(int orientation) { + mOrientation = orientation; } public void setGestureColor(int color) { @@ -176,73 +206,85 @@ public class GestureOverlayView extends View { return mCertainGestureColor; } - public float getGestureStroke() { - return mGestureStroke; + public float getGestureStrokeWidth() { + return mGestureStrokeWidth; } - public void setGestureStroke(float gestureStroke) { - mGestureStroke = gestureStroke; - mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1); - mGesturePaint.setStrokeWidth(mGestureStroke); + public void setGestureStrokeWidth(float gestureStrokeWidth) { + mGestureStrokeWidth = gestureStrokeWidth; + mInvalidateExtraBorder = Math.max(1, ((int) gestureStrokeWidth) - 1); + mGesturePaint.setStrokeWidth(gestureStrokeWidth); } - /** - * Set the gesture to be shown in the view - * - * @param gesture - */ - public void setCurrentGesture(Gesture gesture) { - if (mCurrentGesture != null) { - clear(false); - } + public int getGestureStrokeType() { + return mGestureStrokeType; + } - mCurrentGesture = gesture; + public void setGestureStrokeType(int gestureStrokeType) { + mGestureStrokeType = gestureStrokeType; + } - if (gesture != null) { - if (mBitmapCanvas != null) { - gesture.draw(mBitmapCanvas, mGesturePaint); - invalidate(); - } - } + public float getGestureStrokeLengthThreshold() { + return mGestureStrokeLengthThreshold; } - private void init() { - mGesturePaint = new Paint(); + public void setGestureStrokeLengthThreshold(float gestureStrokeLengthThreshold) { + mGestureStrokeLengthThreshold = gestureStrokeLengthThreshold; + } - final Paint gesturePaint = mGesturePaint; - gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS); - gesturePaint.setColor(mCertainGestureColor); - gesturePaint.setStyle(Paint.Style.STROKE); - gesturePaint.setStrokeJoin(Paint.Join.ROUND); - gesturePaint.setStrokeCap(Paint.Cap.ROUND); - gesturePaint.setStrokeWidth(mGestureStroke); - gesturePaint.setDither(DITHER_FLAG); + public float getGestureStrokeSquarenessTreshold() { + return mGestureStrokeSquarenessTreshold; } - @Override - protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { - super.onSizeChanged(width, height, oldWidth, oldHeight); + public void setGestureStrokeSquarenessTreshold(float gestureStrokeSquarenessTreshold) { + mGestureStrokeSquarenessTreshold = gestureStrokeSquarenessTreshold; + } - if (width <= 0 || height <= 0) { - return; - } + public float getGestureStrokeAngleThreshold() { + return mGestureStrokeAngleThreshold; + } - int targetWidth = width > oldWidth ? width : oldWidth; - int targetHeight = height > oldHeight ? height : oldHeight; + public void setGestureStrokeAngleThreshold(float gestureStrokeAngleThreshold) { + mGestureStrokeAngleThreshold = gestureStrokeAngleThreshold; + } - if (mBitmap != null) mBitmap.recycle(); + public boolean isEventsInterceptionEnabled() { + return mInterceptEvents; + } - mBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888); - if (mBitmapCanvas != null) { - mBitmapCanvas.setBitmap(mBitmap); - } else { - mBitmapCanvas = new Canvas(mBitmap); - } - mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND); + public void setEventsInterceptionEnabled(boolean enabled) { + mInterceptEvents = enabled; + } + + public boolean isFadeEnabled() { + return mFadeEnabled; + } + + public void setFadeEnabled(boolean fadeEnabled) { + mFadeEnabled = fadeEnabled; + } + + public Gesture getGesture() { + return mCurrentGesture; + } + public void setGesture(Gesture gesture) { if (mCurrentGesture != null) { - mCurrentGesture.draw(mBitmapCanvas, mGesturePaint); + clear(false); } + + setCurrentColor(mCertainGestureColor); + mCurrentGesture = gesture; + + final Path path = mCurrentGesture.toPath(); + final RectF bounds = new RectF(); + path.computeBounds(bounds, true); + + mPath.rewind(); + mPath.addPath(path, (getWidth() - bounds.width()) / 2.0f, + (getHeight() - bounds.height()) / 2.0f); + + invalidate(); } public void addOnGestureListener(OnGestureListener listener) { @@ -257,101 +299,177 @@ public class GestureOverlayView extends View { mOnGestureListeners.clear(); } - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); + public void addOnGesturePerformedListener(OnGesturePerformedListener listener) { + mOnGesturePerformedListeners.add(listener); + if (mOnGesturePerformedListeners.size() > 0) { + mHandleGestureActions = true; + } + } + + public void removeOnGesturePerformedListener(OnGesturePerformedListener listener) { + mOnGesturePerformedListeners.remove(listener); + if (mOnGesturePerformedListeners.size() <= 0) { + mHandleGestureActions = false; + } + } + + public void removeAllOnGesturePerformedListeners() { + mOnGesturePerformedListeners.clear(); + mHandleGestureActions = false; + } - // draw double buffer - if (mIsFadingOut) { - mBitmapPaint.setAlpha((int) (255 * mFadingAlpha)); - canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); + public boolean isGesturing() { + return mIsGesturing; + } + + private void setCurrentColor(int color) { + mCurrentColor = color; + if (mFadingHasStarted) { + setPaintAlpha((int) (255 * mFadingAlpha)); } else { - mBitmapPaint.setAlpha(255); - canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); + setPaintAlpha(255); + } + invalidate(); + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + + if (mCurrentGesture != null) { + canvas.drawPath(mPath, mGesturePaint); } + } - // draw the current stroke - canvas.drawPath(mPath, mGesturePaint); + private void setPaintAlpha(int alpha) { + alpha += alpha >> 7; + final int baseAlpha = mCurrentColor >>> 24; + final int useAlpha = baseAlpha * alpha >> 8; + mGesturePaint.setColor((mCurrentColor << 8 >>> 8) | (useAlpha << 24)); } - /** - * Clear up the overlay - * - * @param fadeOut whether the gesture on the overlay should fade out - * gradually or disappear immediately - */ - public void clear(boolean fadeOut) { - if (fadeOut) { + public void clear(boolean animated) { + clear(animated, false); + } + + private void clear(boolean animated, boolean fireActionPerformed) { + setPaintAlpha(255); + removeCallbacks(mFadingOut); + mFadingOut.fireActionPerformed = fireActionPerformed; + + if (animated && mCurrentGesture != null) { mFadingAlpha = 1.0f; mIsFadingOut = true; - removeCallbacks(mFadingOut); + mFadingHasStarted = false; mFadingStart = AnimationUtils.currentAnimationTimeMillis() + mFadeOffset; + postDelayed(mFadingOut, mFadeOffset); } else { - mPath.rewind(); - mCurrentGesture = null; - if (mBitmap != null) { - mBitmap.eraseColor(TRANSPARENT_BACKGROUND); + mFadingAlpha = 1.0f; + mIsFadingOut = false; + mFadingHasStarted = false; + + if (fireActionPerformed) { + post(mFadingOut); + } else { + mCurrentGesture = null; + mPath.rewind(); invalidate(); } } } - public void cancelFadingOut() { + public void cancelClearAnimation() { + setPaintAlpha(255); mIsFadingOut = false; + mFadingHasStarted = false; removeCallbacks(mFadingOut); + mPath.rewind(); + mCurrentGesture = null; + } + + public void cancelGesture() { + mIsListeningForGestures = false; + + // add the stroke to the current gesture + mCurrentGesture.addStroke(new GestureStroke(mStrokeBuffer)); + + // pass the event to handlers + final long now = SystemClock.uptimeMillis(); + final MotionEvent event = MotionEvent.obtain(now, now, + MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); + + final ArrayList<OnGestureListener> listeners = mOnGestureListeners; + final int count = listeners.size(); + for (int i = 0; i < count; i++) { + listeners.get(i).onGestureCancelled(this, event); + } + + event.recycle(); + + clear(false); + mIsGesturing = false; + mStrokeBuffer.clear(); + } + + @Override + protected void onDetachedFromWindow() { + cancelClearAnimation(); } @Override - public boolean onTouchEvent(MotionEvent event) { - if (!isEnabled()) { + public boolean dispatchTouchEvent(MotionEvent event) { + if (isEnabled()) { + boolean cancelDispatch = (mIsGesturing || (mCurrentGesture != null && + mCurrentGesture.getStrokesCount() > 0)) && mInterceptEvents; + processEvent(event); + + if (cancelDispatch) { + event.setAction(MotionEvent.ACTION_CANCEL); + } + + super.dispatchTouchEvent(event); return true; } - processEvent(event); - - return true; + return super.dispatchTouchEvent(event); } - public void processEvent(MotionEvent event) { + private boolean processEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: - Rect rect = touchStart(event); - invalidate(rect); - break; + touchDown(event); + invalidate(); + return true; case MotionEvent.ACTION_MOVE: - rect = touchMove(event); - if (rect != null) { - invalidate(rect); + if (mIsListeningForGestures) { + Rect rect = touchMove(event); + if (rect != null) { + invalidate(rect); + } + return true; } break; case MotionEvent.ACTION_UP: - touchUp(event, false); - invalidate(); + if (mIsListeningForGestures) { + touchUp(event, false); + invalidate(); + return true; + } break; case MotionEvent.ACTION_CANCEL: - touchUp(event, true); - invalidate(); - break; + if (mIsListeningForGestures) { + touchUp(event, true); + invalidate(); + return true; + } } - } - private Rect touchStart(MotionEvent event) { - // pass the event to handlers - final ArrayList<OnGestureListener> listeners = mOnGestureListeners; - final int count = listeners.size(); - for (int i = 0; i < count; i++) { - OnGestureListener listener = listeners.get(i); - listener.onGestureStarted(this, event); - } + return false; + } - // if there is fading out going on, stop it. - if (mIsFadingOut) { - mIsFadingOut = false; - removeCallbacks(mFadingOut); - mBitmap.eraseColor(TRANSPARENT_BACKGROUND); - mCurrentGesture = null; - } + private void touchDown(MotionEvent event) { + mIsListeningForGestures = true; float x = event.getX(); float y = event.getY(); @@ -359,22 +477,46 @@ public class GestureOverlayView extends View { mX = x; mY = y; + mTotalLength = 0; + mIsGesturing = false; + + if (mGestureStrokeType == GESTURE_STROKE_TYPE_SINGLE) { + if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor); + mCurrentGesture = null; + mPath.rewind(); + } else if (mCurrentGesture == null || mCurrentGesture.getStrokesCount() == 0) { + if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor); + } + + // if there is fading out going on, stop it. + if (mFadingHasStarted) { + cancelClearAnimation(); + } else if (mIsFadingOut) { + setPaintAlpha(255); + mIsFadingOut = false; + mFadingHasStarted = false; + removeCallbacks(mFadingOut); + } + if (mCurrentGesture == null) { mCurrentGesture = new Gesture(); } - mPointBuffer.add(new GesturePoint(x, y, event.getEventTime())); - - mPath.rewind(); + mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); mPath.moveTo(x, y); - mInvalidRect.set((int) x - mInvalidateExtraBorder, (int) y - mInvalidateExtraBorder, - (int) x + mInvalidateExtraBorder, (int) y + mInvalidateExtraBorder); - + final int border = mInvalidateExtraBorder; + mInvalidRect.set((int) x - border, (int) y - border, (int) x + border, (int) y + border); + mCurveEndX = x; mCurveEndY = y; - - return mInvalidRect; + + // pass the event to handlers + final ArrayList<OnGestureListener> listeners = mOnGestureListeners; + final int count = listeners.size(); + for (int i = 0; i < count; i++) { + listeners.get(i).onGestureStarted(this, event); + } } private Rect touchMove(MotionEvent event) { @@ -393,61 +535,80 @@ public class GestureOverlayView extends View { areaToRefresh = mInvalidRect; // start with the curve end - areaToRefresh.set( - (int) mCurveEndX - mInvalidateExtraBorder, - (int) mCurveEndY - mInvalidateExtraBorder, - (int) mCurveEndX + mInvalidateExtraBorder, - (int) mCurveEndY + mInvalidateExtraBorder); + final int border = mInvalidateExtraBorder; + areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border, + (int) mCurveEndX + border, (int) mCurveEndY + border); - mCurveEndX = (x + previousX) / 2; - mCurveEndY = (y + previousY) / 2; + float cX = mCurveEndX = (x + previousX) / 2; + float cY = mCurveEndY = (y + previousY) / 2; - mPath.quadTo(previousX, previousY, mCurveEndX, mCurveEndY); + mPath.quadTo(previousX, previousY, cX, cY); // union with the control point of the new curve - areaToRefresh.union( - (int) previousX - mInvalidateExtraBorder, - (int) previousY - mInvalidateExtraBorder, - (int) previousX + mInvalidateExtraBorder, - (int) previousY + mInvalidateExtraBorder); + areaToRefresh.union((int) previousX - border, (int) previousY - border, + (int) previousX + border, (int) previousY + border); // union with the end point of the new curve - areaToRefresh.union( - (int) mCurveEndX - mInvalidateExtraBorder, - (int) mCurveEndY - mInvalidateExtraBorder, - (int) mCurveEndX + mInvalidateExtraBorder, - (int) mCurveEndY + mInvalidateExtraBorder); + areaToRefresh.union((int) cX - border, (int) cY - border, + (int) cX + border, (int) cY + border); mX = x; mY = y; } - mPointBuffer.add(new GesturePoint(x, y, event.getEventTime())); + mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); + + if (mHandleGestureActions && !mIsGesturing) { + mTotalLength += (float) Math.sqrt(dx * dx + dy * dy); + + if (mTotalLength > mGestureStrokeLengthThreshold) { + final OrientedBoundingBox box = + GestureUtilities.computeOrientedBoundingBox(mStrokeBuffer); + + float angle = Math.abs(box.orientation); + if (angle > 90) { + angle = 180 - angle; + } + + if (box.squareness > mGestureStrokeSquarenessTreshold || + (mOrientation == ORIENTATION_VERTICAL ? + angle < mGestureStrokeAngleThreshold : + angle > mGestureStrokeAngleThreshold)) { + + mIsGesturing = true; + setCurrentColor(mCertainGestureColor); + } + } + } // pass the event to handlers final ArrayList<OnGestureListener> listeners = mOnGestureListeners; final int count = listeners.size(); for (int i = 0; i < count; i++) { listeners.get(i).onGesture(this, event); - } - + } + return areaToRefresh; } private void touchUp(MotionEvent event, boolean cancel) { - // add the stroke to the current gesture - mCurrentGesture.addStroke(new GestureStroke(mPointBuffer)); + mIsListeningForGestures = false; - // add the stroke to the double buffer - mBitmapCanvas.drawPath(mPath, mGesturePaint); + // add the stroke to the current gesture + mCurrentGesture.addStroke(new GestureStroke(mStrokeBuffer)); + mStrokeBuffer.clear(); if (!cancel) { // pass the event to handlers final ArrayList<OnGestureListener> listeners = mOnGestureListeners; - final int count = listeners.size(); + int count = listeners.size(); for (int i = 0; i < count; i++) { listeners.get(i).onGestureEnded(this, event); } + + if (mHandleGestureActions) { + clear(mFadeEnabled, mIsGesturing); + } } else { // pass the event to handlers final ArrayList<OnGestureListener> listeners = mOnGestureListeners; @@ -455,15 +616,62 @@ public class GestureOverlayView extends View { for (int i = 0; i < count; i++) { listeners.get(i).onGestureCancelled(this, event); } + + clear(false); } - mPath.rewind(); - mPointBuffer.clear(); + mIsGesturing = false; + } + + private void fireOnGesturePerformed() { + final ArrayList<OnGesturePerformedListener> actionListeners = + mOnGesturePerformedListeners; + final int count = actionListeners.size(); + for (int i = 0; i < count; i++) { + actionListeners.get(i).onGesturePerformed(GestureOverlayView.this, + mCurrentGesture); + } + } + + private class FadeOutRunnable implements Runnable { + boolean fireActionPerformed; + + public void run() { + if (mIsFadingOut) { + final long now = AnimationUtils.currentAnimationTimeMillis(); + final long duration = now - mFadingStart; + + if (duration > mFadeDuration) { + if (fireActionPerformed) { + fireOnGesturePerformed(); + } + + mIsFadingOut = false; + mFadingHasStarted = false; + mPath.rewind(); + mCurrentGesture = null; + setPaintAlpha(255); + } else { + mFadingHasStarted = true; + float interpolatedTime = Math.max(0.0f, + Math.min(1.0f, duration / (float) mFadeDuration)); + mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime); + setPaintAlpha((int) (255 * mFadingAlpha)); + postDelayed(this, FADE_ANIMATION_RATE); + } + } else { + fireOnGesturePerformed(); + + mFadingHasStarted = false; + mPath.rewind(); + mCurrentGesture = null; + setPaintAlpha(255); + } + + invalidate(); + } } - /** - * An interface for processing gesture events - */ public static interface OnGestureListener { void onGestureStarted(GestureOverlayView overlay, MotionEvent event); @@ -473,4 +681,8 @@ public class GestureOverlayView extends View { void onGestureCancelled(GestureOverlayView overlay, MotionEvent event); } + + public static interface OnGesturePerformedListener { + void onGesturePerformed(GestureOverlayView overlay, Gesture gesture); + } } diff --git a/core/java/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java index 6d022b4..0d7bc2d 100644 --- a/core/java/android/gesture/GestureStroke.java +++ b/core/java/android/gesture/GestureStroke.java @@ -89,37 +89,49 @@ public class GestureStroke { */ void draw(Canvas canvas, Paint paint) { if (mCachedPath == null) { - final float[] localPoints = points; - final int count = localPoints.length; + makePath(); + } - Path path = null; + canvas.drawPath(mCachedPath, paint); + } - float mX = 0; - float mY = 0; + public Path getPath() { + if (mCachedPath == null) { + makePath(); + } + + return mCachedPath; + } + + private void makePath() { + final float[] localPoints = points; + final int count = localPoints.length; + + Path path = null; + + float mX = 0; + float mY = 0; - for (int i = 0; i < count; i += 2) { - float x = localPoints[i]; - float y = localPoints[i + 1]; - if (path == null) { - path = new Path(); - path.moveTo(x, y); + for (int i = 0; i < count; i += 2) { + float x = localPoints[i]; + float y = localPoints[i + 1]; + if (path == null) { + path = new Path(); + path.moveTo(x, y); + mX = x; + mY = y; + } else { + float dx = Math.abs(x - mX); + float dy = Math.abs(y - mY); + if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { + path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; - } else { - float dx = Math.abs(x - mX); - float dy = Math.abs(y - mY); - if (dx >= 3 || dy >= 3) { - path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); - mX = x; - mY = y; - } } } - - mCachedPath = path; } - canvas.drawPath(mCachedPath, paint); + mCachedPath = path; } /** @@ -158,8 +170,7 @@ public class GestureStroke { } else { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); - if (dx >= TOUCH_TOLERANCE || - dy >= TOUCH_TOLERANCE) { + if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; diff --git a/core/java/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java index e47856c..4a3144c 100755 --- a/core/java/android/gesture/GestureUtilities.java +++ b/core/java/android/gesture/GestureUtilities.java @@ -58,10 +58,10 @@ final class GestureUtilities { float sy = targetPatchSize / rect.height(); float scale = sx < sy ? sx : sy; - Matrix trans = new Matrix(); - trans.setScale(scale, scale); - trans.preTranslate(-rect.centerX(), -rect.centerY()); - trans.postTranslate(targetPatchSize / 2, targetPatchSize / 2); + float preDx = -rect.centerX(); + float preDy = -rect.centerY(); + float postDx = targetPatchSize / 2; + float postDy = targetPatchSize / 2; final ArrayList<GestureStroke> strokes = gesture.getStrokes(); final int count = strokes.size(); @@ -72,11 +72,16 @@ final class GestureUtilities { for (int index = 0; index < count; index++) { final GestureStroke stroke = strokes.get(index); - size = stroke.points.length; + float[] strokepoints = stroke.points; + size = strokepoints.length; final float[] pts = new float[size]; - - trans.mapPoints(pts, 0, stroke.points, 0, size / 2); + + for (int i = 0; i < size; i += 2) { + pts[i] = (strokepoints[i] + preDx) * scale + postDx; + pts[i + 1] = (strokepoints[i + 1] + preDy) * scale + postDy; + } + float segmentEndX = -1; float segmentEndY = -1; @@ -388,7 +393,7 @@ final class GestureUtilities { } else { // -PI<alpha<PI angle = (float) Math.atan2(targetVector[1], targetVector[0]); angle = (float) (180 * angle / Math.PI); - android.graphics.Matrix trans = new android.graphics.Matrix(); + Matrix trans = new Matrix(); trans.setRotate(-angle); trans.mapPoints(points); } diff --git a/core/java/android/gesture/TouchThroughGestureListener.java b/core/java/android/gesture/TouchThroughGestureListener.java deleted file mode 100644 index 09a528d..0000000 --- a/core/java/android/gesture/TouchThroughGestureListener.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2008-2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.gesture; - -import android.view.MotionEvent; -import android.view.View; - -import java.util.ArrayList; -import java.lang.ref.WeakReference; - -/** - * TouchThroughGesturing implements the interaction behavior that allows a user - * to gesture over a regular UI widget such as ListView and at the same time, - * still allows a user to perform basic interactions (clicking, scrolling and panning) - * with the underlying widget. - */ -public class TouchThroughGestureListener implements GestureOverlayView.OnGestureListener { - public static final int SINGLE_STROKE = 0; - public static final int MULTIPLE_STROKE = 1; - - // TODO: Add properties for all these - private static final float STROKE_LENGTH_THRESHOLD = 30; - private static final float SQUARENESS_THRESHOLD = 0.275f; - private static final float ANGLE_THRESHOLD = 40; - - private boolean mIsGesturing = false; - - private float mTotalLength; - - private float mX; - private float mY; - - private WeakReference<View> mModel; - - private int mGestureType = SINGLE_STROKE; - - // TODO: Use WeakReferences - private final ArrayList<OnGesturePerformedListener> mPerformedListeners = - new ArrayList<OnGesturePerformedListener>(); - - private boolean mStealEvents = false; - - public TouchThroughGestureListener(View model) { - this(model, true); - } - - public TouchThroughGestureListener(View model, boolean stealEvents) { - mModel = new WeakReference<View>(model); - mStealEvents = stealEvents; - } - - /** - * - * @param type SINGLE_STROKE or MULTIPLE_STROKE - */ - public void setGestureType(int type) { - mGestureType = type; - } - - public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) { - if (mGestureType == MULTIPLE_STROKE) { - overlay.cancelFadingOut(); - } - - mX = event.getX(); - mY = event.getY(); - mTotalLength = 0; - mIsGesturing = false; - - if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null - || overlay.getCurrentGesture().getStrokesCount() == 0) { - overlay.setGestureDrawingColor(overlay.getUncertainGestureColor()); - } - - dispatchEventToModel(event); - } - - private void dispatchEventToModel(MotionEvent event) { - View v = mModel.get(); - if (v != null) v.dispatchTouchEvent(event); - } - - public void onGesture(GestureOverlayView overlay, MotionEvent event) { - //noinspection PointlessBooleanExpression - if (!mStealEvents) { - dispatchEventToModel(event); - } - - if (mIsGesturing) { - return; - } - - final float x = event.getX(); - final float y = event.getY(); - final float dx = x - mX; - final float dy = y - mY; - - mTotalLength += (float) Math.sqrt(dx * dx + dy * dy); - mX = x; - mY = y; - - if (mTotalLength > STROKE_LENGTH_THRESHOLD) { - final OrientedBoundingBox box = - GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke()); - float angle = Math.abs(box.orientation); - if (angle > 90) { - angle = 180 - angle; - } - if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) { - mIsGesturing = true; - overlay.setGestureDrawingColor(overlay.getGestureColor()); - if (mStealEvents) { - event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(), - MotionEvent.ACTION_CANCEL, x, y, event.getPressure(), event.getSize(), - event.getMetaState(), event.getXPrecision(), event.getYPrecision(), - event.getDeviceId(), event.getEdgeFlags()); - } - } - } - - if (mStealEvents) { - dispatchEventToModel(event); - } - } - - public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) { - if (mIsGesturing) { - overlay.clear(true); - - final ArrayList<OnGesturePerformedListener> listeners = mPerformedListeners; - final int count = listeners.size(); - - for (int i = 0; i < count; i++) { - listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture()); - } - } else { - dispatchEventToModel(event); - overlay.clear(false); - } - } - - public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) { - overlay.clear(mIsGesturing); - if (!mIsGesturing) { - dispatchEventToModel(event); - } - } - - public void addOnGestureActionListener(OnGesturePerformedListener listener) { - mPerformedListeners.add(listener); - } - - public void removeOnGestureActionListener(OnGesturePerformedListener listener) { - mPerformedListeners.remove(listener); - } - - public boolean isGesturing() { - return mIsGesturing; - } - - public static interface OnGesturePerformedListener { - public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture); - } -} diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index bd45978..559f224 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2593,6 +2593,16 @@ public final class Settings { public static final String GTALK_COMPRESS = "gtalk_compress"; /** + * This is the timeout for which Google Talk will send the message using bareJID. In a + * established chat between two XMPP endpoints, Google Talk uses fullJID in the format + * of user@domain/resource in order to send the message to the specific client. However, + * if Google Talk hasn't received a message from that client after some time, it would + * fall back to use the bareJID, which would broadcast the message to all clients for + * the other user. + */ + public static final String GTALK_USE_BARE_JID_TIMEOUT_MS = "gtalk_use_barejid_timeout_ms"; + + /** * Enable use of ssl session caching. * 'db' - save each session in a (per process) database * 'file' - save each session in a (per process) file diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index c6f36a0..8b0629c 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2351,7 +2351,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION; // Check whether the child that requests the invalidate is fully opaque - final boolean isOpaque = child.isOpaque(); + final boolean isOpaque = child.isOpaque() && !drawAnimation && + child.getAnimation() != null; // Mark the child as dirty, using the appropriate flag // Make sure we do not set both flags at the same time final int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY; diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 105eacd..dcba943 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -123,7 +123,7 @@ public class WebSettings { private String mSerifFontFamily = "serif"; private String mCursiveFontFamily = "cursive"; private String mFantasyFontFamily = "fantasy"; - private String mDefaultTextEncoding = "Latin-1"; + private String mDefaultTextEncoding; private String mUserAgent; private boolean mUseDefaultUserAgent; private String mAcceptLanguage; @@ -240,6 +240,8 @@ public class WebSettings { WebSettings(Context context) { mEventHandler = new EventHandler(); mContext = context; + mDefaultTextEncoding = context.getString(com.android.internal. + R.string.default_text_encoding); if (sLockForLocaleSettings == null) { sLockForLocaleSettings = new Object(); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 8a538d7..e896d58 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -49,7 +49,6 @@ import android.view.inputmethod.InputConnectionWrapper; import android.view.inputmethod.InputMethodManager; import android.view.ContextMenu.ContextMenuInfo; import android.gesture.GestureOverlayView; -import android.gesture.TouchThroughGestureListener; import android.gesture.Gesture; import android.gesture.LetterRecognizer; import android.gesture.Prediction; @@ -472,7 +471,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private ViewTreeObserver.OnGlobalLayoutListener mGesturesLayoutListener; private boolean mGlobalLayoutListenerAddedGestures; private boolean mInstallGesturesOverlay; - private TouchThroughGestureListener mGesturesListener; private boolean mPreviousGesturing; private boolean mGlobalLayoutListenerAddedFilter; @@ -736,10 +734,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mGesturesPopup = p; mGesturesOverlay.removeAllOnGestureListeners(); - mGesturesListener = new TouchThroughGestureListener(null); - mGesturesListener.setGestureType(TouchThroughGestureListener.MULTIPLE_STROKE); - mGesturesListener.addOnGestureActionListener(new GesturesProcessor()); - mGesturesOverlay.addOnGestureListener(mGesturesListener); + mGesturesOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE); + mGesturesOverlay.addOnGesturePerformedListener(new GesturesProcessor()); mPreviousGesturing = false; } @@ -756,19 +752,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mGestures != GESTURES_NONE) { - mGesturesOverlay.processEvent(ev); - - final boolean isGesturing = mGesturesListener.isGesturing(); - - if (!isGesturing) { - mPreviousGesturing = isGesturing; - return super.dispatchTouchEvent(ev); - } else if (!mPreviousGesturing){ - mPreviousGesturing = isGesturing; - final MotionEvent event = MotionEvent.obtain(ev); - event.setAction(MotionEvent.ACTION_CANCEL); - super.dispatchTouchEvent(event); - return true; + if (ev.getAction() != MotionEvent.ACTION_DOWN || mFastScroller == null || + !mFastScroller.isPointInside(ev.getX(), ev.getY())) { + + if (mGesturesPopup.isShowing()) { + mGesturesOverlay.dispatchTouchEvent(ev); + + final boolean isGesturing = mGesturesOverlay.isGesturing(); + + if (!isGesturing) { + mPreviousGesturing = isGesturing; + return super.dispatchTouchEvent(ev); + } else if (!mPreviousGesturing){ + mPreviousGesturing = isGesturing; + final MotionEvent event = MotionEvent.obtain(ev); + event.setAction(MotionEvent.ACTION_CANCEL); + super.dispatchTouchEvent(event); + return true; + } + } } } @@ -1927,6 +1929,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int longPressPosition, final long longPressId) { boolean handled = false; + dismissGesturesPopup(); + if (mOnItemLongClickListener != null) { handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, child, longPressPosition, longPressId); @@ -2130,13 +2134,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public boolean onTouchEvent(MotionEvent ev) { - if (mFastScroller != null) { boolean intercepted = mFastScroller.onTouchEvent(ev); if (intercepted) { return true; } } + final int action = ev.getAction(); final int x = (int) ev.getX(); final int y = (int) ev.getY(); @@ -3848,8 +3852,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } - private class GesturesProcessor implements - TouchThroughGestureListener.OnGesturePerformedListener { + private class GesturesProcessor implements GestureOverlayView.OnGesturePerformedListener { private static final double SCORE_THRESHOLD = 0.1; diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index b9fd5a6..cd965fc 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -402,8 +402,7 @@ class FastScroller { boolean onInterceptTouchEvent(MotionEvent ev) { if (mState > STATE_NONE && ev.getAction() == MotionEvent.ACTION_DOWN) { - if (ev.getX() > mList.getWidth() - mThumbW && ev.getY() >= mThumbY && - ev.getY() <= mThumbY + mThumbH) { + if (isPointInside(ev.getX(), ev.getY())) { setState(STATE_DRAGGING); return true; } @@ -415,11 +414,11 @@ class FastScroller { if (mState == STATE_NONE) { return false; } - if (me.getAction() == MotionEvent.ACTION_DOWN) { - if (me.getX() > mList.getWidth() - mThumbW - && me.getY() >= mThumbY - && me.getY() <= mThumbY + mThumbH) { - + + final int action = me.getAction(); + + if (action == MotionEvent.ACTION_DOWN) { + if (isPointInside(me.getX(), me.getY())) { setState(STATE_DRAGGING); if (mListAdapter == null && mList != null) { getSectionsFromIndexer(); @@ -428,7 +427,7 @@ class FastScroller { cancelFling(); return true; } - } else if (me.getAction() == MotionEvent.ACTION_UP) { + } else if (action == MotionEvent.ACTION_UP) { if (mState == STATE_DRAGGING) { setState(STATE_VISIBLE); final Handler handler = mHandler; @@ -436,7 +435,7 @@ class FastScroller { handler.postDelayed(mScrollFade, 1000); return true; } - } else if (me.getAction() == MotionEvent.ACTION_MOVE) { + } else if (action == MotionEvent.ACTION_MOVE) { if (mState == STATE_DRAGGING) { final int viewHeight = mList.getHeight(); // Jitter @@ -460,6 +459,10 @@ class FastScroller { return false; } + boolean isPointInside(float x, float y) { + return x > mList.getWidth() - mThumbW && y >= mThumbY && y <= mThumbY + mThumbH; + } + public class ScrollFade implements Runnable { long mStartTime; diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 80fbf9e..3afd5d4 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -353,25 +353,24 @@ public class FrameLayout extends ViewGroup { if (mForeground != null) { final Drawable foreground = mForeground; + if (mForegroundBoundsChanged) { mForegroundBoundsChanged = false; - if (foreground != null) { - final Rect selfBounds = mSelfBounds; - final Rect overlayBounds = mOverlayBounds; - - final int w = mRight-mLeft; - final int h = mBottom-mTop; - - if (mForegroundInPadding) { - selfBounds.set(0, 0, w, h); - } else { - selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom); - } + final Rect selfBounds = mSelfBounds; + final Rect overlayBounds = mOverlayBounds; - Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(), - foreground.getIntrinsicHeight(), selfBounds, overlayBounds); - foreground.setBounds(overlayBounds); + final int w = mRight-mLeft; + final int h = mBottom-mTop; + + if (mForegroundInPadding) { + selfBounds.set(0, 0, w, h); + } else { + selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom); } + + Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(), + foreground.getIntrinsicHeight(), selfBounds, overlayBounds); + foreground.setBounds(overlayBounds); } foreground.draw(canvas); |