Merge "Use RenderThread for navigation bar ripples" into lmp-dev
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 076f1e2..1b57c24 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -725,6 +725,19 @@
long propCy, long propRadius, long propPaint);
@Override
+ public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
+ CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
+ CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
+ nDrawRoundRect(mRenderer, left.getNativeContainer(), top.getNativeContainer(),
+ right.getNativeContainer(), bottom.getNativeContainer(),
+ rx.getNativeContainer(), ry.getNativeContainer(),
+ paint.getNativeContainer());
+ }
+
+ private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
+ long propRight, long propBottom, long propRx, long propRy, long propPaint);
+
+ @Override
public void drawColor(int color) {
drawColor(color, PorterDuff.Mode.SRC_OVER);
}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index c172969..e3eee71 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -113,6 +113,11 @@
public abstract void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint);
+ public abstract void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
+ CanvasProperty<Float> right, CanvasProperty<Float> bottom,
+ CanvasProperty<Float> rx, CanvasProperty<Float> ry,
+ CanvasProperty<Paint> paint);
+
public static void setProperty(String name, String value) {
GLES20Canvas.setProperty(name, value);
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 6080f2a..2e2b23f 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -480,6 +480,20 @@
renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
}
+static void android_view_GLES20Canvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
+ jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
+ jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
+ DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
+ CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
+ CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
+ CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
+ CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
+ CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
+ CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
+ CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
+ renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
+}
+
static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
@@ -912,6 +926,7 @@
{ "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects },
{ "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect },
+ { "nDrawRoundRect", "(JJJJJJJJ)V", (void*) android_view_GLES20Canvas_drawRoundRectProps },
{ "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps },
{ "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval },
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 5ff7b7f..cb3ef9b 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1105,6 +1105,34 @@
float mRy;
};
+class DrawRoundRectPropsOp : public DrawOp {
+public:
+ DrawRoundRectPropsOp(float* left, float* top, float* right, float* bottom,
+ float *rx, float *ry, const SkPaint* paint)
+ : DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom),
+ mRx(rx), mRy(ry) {}
+
+ virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+ return renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom,
+ *mRx, *mRy, getPaint(renderer));
+ }
+
+ virtual void output(int level, uint32_t logFlags) const {
+ OP_LOG("Draw RoundRect Props " RECT_STRING ", rx %f, ry %f",
+ *mLeft, *mTop, *mRight, *mBottom, *mRx, *mRy);
+ }
+
+ virtual const char* name() { return "DrawRoundRectProps"; }
+
+private:
+ float* mLeft;
+ float* mTop;
+ float* mRight;
+ float* mBottom;
+ float* mRx;
+ float* mRy;
+};
+
class DrawCircleOp : public DrawStrokableOp {
public:
DrawCircleOp(float x, float y, float radius, const SkPaint* paint)
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 7ee83e6..1f70921 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -275,6 +275,23 @@
return DrawGlInfo::kStatusDone;
}
+status_t DisplayListRenderer::drawRoundRect(
+ CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+ CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
+ CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
+ CanvasPropertyPaint* paint) {
+ mDisplayListData->refProperty(left);
+ mDisplayListData->refProperty(top);
+ mDisplayListData->refProperty(right);
+ mDisplayListData->refProperty(bottom);
+ mDisplayListData->refProperty(rx);
+ mDisplayListData->refProperty(ry);
+ mDisplayListData->refProperty(paint);
+ addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
+ &right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
+ return DrawGlInfo::kStatusDone;
+}
+
status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
paint = refPaint(paint);
addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index e9c937cb..3a3fc3a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -123,6 +123,10 @@
virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
virtual status_t drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* paint);
+ virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+ CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
+ CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
+ CanvasPropertyPaint* paint);
virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index c9e1618..47e24e8 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,8 +1,11 @@
-keep class com.android.systemui.statusbar.policy.KeyButtonView {
public float getDrawingAlpha();
+ public void setDrawingAlpha(float);
+}
+
+-keep class com.android.systemui.statusbar.policy.KeyButtonRipple {
public float getGlowAlpha();
public float getGlowScale();
- public void setDrawingAlpha(float);
public void setGlowAlpha(float);
public void setGlowScale(float);
}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8fe0af8..37ee0aea 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -489,4 +489,7 @@
<!-- Extra padding between the mobile data type icon and the strength indicator when the data
type icon is wide for the tile in quick settings. -->
<dimen name="wide_type_icon_start_padding_qs">3dp</dimen>
+
+ <!-- The maximum width of the navigation bar ripples. -->
+ <dimen name="key_button_ripple_max_width">95dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
new file mode 100644
index 0000000..a3765aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2014 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 com.android.systemui.statusbar.policy;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.CanvasProperty;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+import android.view.HardwareCanvas;
+import android.view.RenderNodeAnimator;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class KeyButtonRipple extends Drawable {
+
+ private static final float GLOW_MAX_SCALE_FACTOR = 1.35f;
+ private static final float GLOW_MAX_ALPHA = 0.2f;
+ private static final int ANIMATION_DURATION_SCALE = 350;
+ private static final int ANIMATION_DURATION_FADE = 450;
+
+ private Paint mRipplePaint;
+ private CanvasProperty<Float> mLeftProp;
+ private CanvasProperty<Float> mTopProp;
+ private CanvasProperty<Float> mRightProp;
+ private CanvasProperty<Float> mBottomProp;
+ private CanvasProperty<Float> mRxProp;
+ private CanvasProperty<Float> mRyProp;
+ private CanvasProperty<Paint> mPaintProp;
+ private float mGlowAlpha = 0f;
+ private float mGlowScale = 1f;
+ private boolean mPressed;
+ private boolean mDrawingHardwareGlow;
+ private int mMaxWidth;
+
+ private final Interpolator mInterpolator = new LogInterpolator();
+ private final Interpolator mAlphaExitInterpolator = PhoneStatusBar.ALPHA_OUT;
+ private boolean mSupportHardware;
+ private final View mTargetView;
+
+ private final HashSet<Animator> mRunningAnimations = new HashSet<>();
+ private final ArrayList<Animator> mTmpArray = new ArrayList<>();
+
+ public KeyButtonRipple(Context ctx, View targetView) {
+ mMaxWidth = ctx.getResources().getDimensionPixelSize(R.dimen.key_button_ripple_max_width);
+ mTargetView = targetView;
+ }
+
+ private Paint getRipplePaint() {
+ if (mRipplePaint == null) {
+ mRipplePaint = new Paint();
+ mRipplePaint.setAntiAlias(true);
+ mRipplePaint.setColor(0xffffffff);
+ }
+ return mRipplePaint;
+ }
+
+ private void drawSoftware(Canvas canvas) {
+ if (mGlowAlpha > 0f) {
+ final Paint p = getRipplePaint();
+ p.setAlpha((int)(mGlowAlpha * 255f));
+
+ final float w = getBounds().width();
+ final float h = getBounds().height();
+ final boolean horizontal = w > h;
+ final float diameter = getRippleSize() * mGlowScale;
+ final float radius = diameter * .5f;
+ final float cx = w * .5f;
+ final float cy = h * .5f;
+ final float rx = horizontal ? radius : cx;
+ final float ry = horizontal ? cy : radius;
+ final float corner = horizontal ? cy : cx;
+
+ canvas.drawRoundRect(cx - rx, cy - ry,
+ cx + rx, cy + ry,
+ corner, corner, p);
+ }
+ }
+
+
+ @Override
+ public void draw(Canvas canvas) {
+ mSupportHardware = canvas.isHardwareAccelerated();
+ if (mSupportHardware) {
+ drawHardware((HardwareCanvas) canvas);
+ } else {
+ drawSoftware(canvas);
+ }
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ // Not supported.
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ // Not supported.
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ private boolean isHorizontal() {
+ return getBounds().width() > getBounds().height();
+ }
+
+ private void drawHardware(HardwareCanvas c) {
+ if (mDrawingHardwareGlow) {
+ c.drawRoundRect(mLeftProp, mTopProp, mRightProp, mBottomProp, mRxProp, mRyProp,
+ mPaintProp);
+ }
+ }
+
+ public float getGlowAlpha() {
+ return mGlowAlpha;
+ }
+
+ public void setGlowAlpha(float x) {
+ mGlowAlpha = x;
+ invalidateSelf();
+ }
+
+ public float getGlowScale() {
+ return mGlowScale;
+ }
+
+ public void setGlowScale(float x) {
+ mGlowScale = x;
+ invalidateSelf();
+ }
+
+ @Override
+ protected boolean onStateChange(int[] state) {
+ boolean pressed = false;
+ for (int i = 0; i < state.length; i++) {
+ if (state[i] == android.R.attr.state_pressed) {
+ pressed = true;
+ break;
+ }
+ }
+ if (pressed != mPressed) {
+ setPressed(pressed);
+ mPressed = pressed;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isStateful() {
+ return true;
+ }
+
+ public void setPressed(boolean pressed) {
+ if (mSupportHardware) {
+ setPressedHardware(pressed);
+ } else {
+ setPressedSoftware(pressed);
+ }
+ }
+
+ private void cancelAnimations() {
+ mTmpArray.addAll(mRunningAnimations);
+ int size = mTmpArray.size();
+ for (int i = 0; i < size; i++) {
+ Animator a = mTmpArray.get(i);
+ a.cancel();
+ }
+ mTmpArray.clear();
+ mRunningAnimations.clear();
+ }
+
+ private void setPressedSoftware(boolean pressed) {
+ if (pressed) {
+ enterSoftware();
+ } else {
+ exitSoftware();
+ }
+ }
+
+ private void enterSoftware() {
+ cancelAnimations();
+ mGlowAlpha = GLOW_MAX_ALPHA;
+ ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this, "glowScale",
+ 0f, GLOW_MAX_SCALE_FACTOR);
+ scaleAnimator.setInterpolator(mInterpolator);
+ scaleAnimator.setDuration(ANIMATION_DURATION_SCALE);
+ scaleAnimator.addListener(mAnimatorListener);
+ scaleAnimator.start();
+ mRunningAnimations.add(scaleAnimator);
+ }
+
+ private void exitSoftware() {
+ ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, 0f);
+ alphaAnimator.setInterpolator(mAlphaExitInterpolator);
+ alphaAnimator.setDuration(ANIMATION_DURATION_FADE);
+ alphaAnimator.addListener(mAnimatorListener);
+ alphaAnimator.start();
+ mRunningAnimations.add(alphaAnimator);
+ }
+
+ private void setPressedHardware(boolean pressed) {
+ if (pressed) {
+ enterHardware();
+ } else {
+ exitHardware();
+ }
+ }
+
+ /**
+ * Sets the left/top property for the round rect to {@code prop} depending on whether we are
+ * horizontal or vertical mode.
+ */
+ private void setExtendStart(CanvasProperty<Float> prop) {
+ if (isHorizontal()) {
+ mLeftProp = prop;
+ } else {
+ mTopProp = prop;
+ }
+ }
+
+ private CanvasProperty<Float> getExtendStart() {
+ return isHorizontal() ? mLeftProp : mTopProp;
+ }
+
+ /**
+ * Sets the right/bottom property for the round rect to {@code prop} depending on whether we are
+ * horizontal or vertical mode.
+ */
+ private void setExtendEnd(CanvasProperty<Float> prop) {
+ if (isHorizontal()) {
+ mRightProp = prop;
+ } else {
+ mBottomProp = prop;
+ }
+ }
+
+ private CanvasProperty<Float> getExtendEnd() {
+ return isHorizontal() ? mRightProp : mBottomProp;
+ }
+
+ private int getExtendSize() {
+ return isHorizontal() ? getBounds().width() : getBounds().height();
+ }
+
+ private int getRippleSize() {
+ int size = isHorizontal() ? getBounds().width() : getBounds().height();
+ return Math.min(size, mMaxWidth);
+ }
+
+ private void enterHardware() {
+ cancelAnimations();
+ mDrawingHardwareGlow = true;
+ setExtendStart(CanvasProperty.createFloat(getExtendSize() / 2));
+ final RenderNodeAnimator startAnim = new RenderNodeAnimator(getExtendStart(),
+ getExtendSize()/2 - GLOW_MAX_SCALE_FACTOR * getRippleSize()/2);
+ startAnim.setDuration(ANIMATION_DURATION_SCALE);
+ startAnim.setInterpolator(mInterpolator);
+ startAnim.addListener(mAnimatorListener);
+ startAnim.setTarget(mTargetView);
+
+ setExtendEnd(CanvasProperty.createFloat(getExtendSize() / 2));
+ final RenderNodeAnimator endAnim = new RenderNodeAnimator(getExtendEnd(),
+ getExtendSize()/2 + GLOW_MAX_SCALE_FACTOR * getRippleSize()/2);
+ endAnim.setDuration(ANIMATION_DURATION_SCALE);
+ endAnim.setInterpolator(mInterpolator);
+ endAnim.addListener(mAnimatorListener);
+ endAnim.setTarget(mTargetView);
+
+ if (isHorizontal()) {
+ mTopProp = CanvasProperty.createFloat(0f);
+ mBottomProp = CanvasProperty.createFloat(getBounds().height());
+ mRxProp = CanvasProperty.createFloat(getBounds().height()/2);
+ mRyProp = CanvasProperty.createFloat(getBounds().height()/2);
+ } else {
+ mLeftProp = CanvasProperty.createFloat(0f);
+ mRightProp = CanvasProperty.createFloat(getBounds().width());
+ mRxProp = CanvasProperty.createFloat(getBounds().width()/2);
+ mRyProp = CanvasProperty.createFloat(getBounds().width()/2);
+ }
+
+ mGlowScale = GLOW_MAX_SCALE_FACTOR;
+ mGlowAlpha = GLOW_MAX_ALPHA;
+ mRipplePaint = getRipplePaint();
+ mRipplePaint.setAlpha((int) (mGlowAlpha * 255));
+ mPaintProp = CanvasProperty.createPaint(mRipplePaint);
+
+ startAnim.start();
+ endAnim.start();
+ mRunningAnimations.add(startAnim);
+ mRunningAnimations.add(endAnim);
+
+ invalidateSelf();
+ }
+
+ private void exitHardware() {
+ mPaintProp = CanvasProperty.createPaint(getRipplePaint());
+ final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPaintProp,
+ RenderNodeAnimator.PAINT_ALPHA, 0);
+ opacityAnim.setDuration(ANIMATION_DURATION_FADE);
+ opacityAnim.setInterpolator(mAlphaExitInterpolator);
+ opacityAnim.addListener(mAnimatorListener);
+ opacityAnim.setTarget(mTargetView);
+
+ opacityAnim.start();
+ mRunningAnimations.add(opacityAnim);
+
+ invalidateSelf();
+ }
+
+ private final AnimatorListenerAdapter mAnimatorListener =
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRunningAnimations.remove(animation);
+ if (mRunningAnimations.isEmpty() && !mPressed) {
+ mDrawingHardwareGlow = false;
+ invalidateSelf();
+ }
+ }
+ };
+
+ /**
+ * Interpolator with a smooth log deceleration
+ */
+ private static final class LogInterpolator implements Interpolator {
+ @Override
+ public float getInterpolation(float input) {
+ return 1 - (float) Math.pow(400, -input * 1.4);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index b814b61..7cc75da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.CanvasProperty;
import android.graphics.Paint;
import android.graphics.RectF;
import android.hardware.input.InputManager;
@@ -32,11 +33,14 @@
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.MathUtils;
import android.view.HapticFeedbackConstants;
+import android.view.HardwareCanvas;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.RenderNodeAnimator;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
@@ -44,6 +48,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
import java.lang.Math;
+import java.util.ArrayList;
import com.android.systemui.R;
@@ -56,22 +61,15 @@
// TODO: Get rid of this
public static final float DEFAULT_QUIESCENT_ALPHA = 1f;
- public static final float MAX_ALPHA = 0.15f;
- public static final float GLOW_MAX_SCALE_FACTOR = 1.5f;
private long mDownTime;
private int mCode;
private int mTouchSlop;
- private float mGlowAlpha = 0f;
- private float mGlowScale = 1f;
private float mDrawingAlpha = 1f;
private float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
private boolean mSupportsLongpress = true;
- private AnimatorSet mPressedAnim;
- private Animator mAnimateToQuiescent = new ObjectAnimator();
- private Paint mRipplePaint;
- private final TimeInterpolator mInterpolator = (TimeInterpolator) new LogInterpolator();
private AudioManager mAudioManager;
+ private Animator mAnimateToQuiescent = new ObjectAnimator();
private final Runnable mCheckLongPress = new Runnable() {
public void run() {
@@ -110,6 +108,7 @@
setClickable(true);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ setBackground(new KeyButtonRipple(context, this));
}
@Override
@@ -141,38 +140,6 @@
return super.performAccessibilityAction(action, arguments);
}
- private Paint getRipplePaint() {
- if (mRipplePaint == null) {
- mRipplePaint = new Paint();
- mRipplePaint.setAntiAlias(true);
- mRipplePaint.setColor(0xffffffff);
- }
- return mRipplePaint;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- final Paint p = getRipplePaint();
- p.setAlpha((int)(MAX_ALPHA * mDrawingAlpha * mGlowAlpha * 255));
-
- final float w = getWidth();
- final float h = getHeight();
- final boolean horizontal = w > h;
- final float diameter = (horizontal ? w : h) * mGlowScale;
- final float radius = diameter * .5f;
- final float cx = w * .5f;
- final float cy = h * .5f;
- final float rx = horizontal ? radius : cx;
- final float ry = horizontal ? cy : radius;
- final float corner = horizontal ? cy : cx;
-
- canvas.drawRoundRect(cx - rx, cy - ry,
- cx + rx, cy + ry,
- corner, corner, p);
-
- super.onDraw(canvas);
- }
-
public void setQuiescentAlpha(float alpha, boolean animate) {
mAnimateToQuiescent.cancel();
alpha = Math.min(Math.max(alpha, 0), 1);
@@ -204,76 +171,6 @@
mDrawingAlpha = x;
}
- public float getGlowAlpha() {
- return mGlowAlpha;
- }
-
- public void setGlowAlpha(float x) {
- mGlowAlpha = x;
- invalidate();
- }
-
- public float getGlowScale() {
- return mGlowScale;
- }
-
- public void setGlowScale(float x) {
- mGlowScale = x;
- final float w = getWidth();
- final float h = getHeight();
- if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
- // this only works if we know the glow will never leave our bounds
- invalidate();
- } else {
- final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
- final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
- com.android.systemui.SwipeHelper.invalidateGlobalRegion(
- this,
- new RectF(getLeft() - rx,
- getTop() - ry,
- getRight() + rx,
- getBottom() + ry));
-
- // also invalidate our immediate parent to help avoid situations where nearby glows
- // interfere
- ((View)getParent()).invalidate();
- }
- }
-
- public void setPressed(boolean pressed) {
- if (pressed != isPressed()) {
- if (mPressedAnim != null && mPressedAnim.isRunning()) {
- mPressedAnim.cancel();
- }
- final AnimatorSet as = mPressedAnim = new AnimatorSet();
- final ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this,
- "glowScale", GLOW_MAX_SCALE_FACTOR);
- scaleAnimator.setInterpolator(mInterpolator);
- if (pressed) {
- mGlowScale = 0f;
- if (mGlowAlpha < mQuiescentAlpha)
- mGlowAlpha = mQuiescentAlpha;
- setDrawingAlpha(1f);
- as.playTogether(
- ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
- scaleAnimator
- );
- as.setDuration(500);
- } else {
- mAnimateToQuiescent.cancel();
- mAnimateToQuiescent = animateToQuiescent();
- as.playTogether(
- ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, mGlowAlpha * .2f, 0f),
- scaleAnimator,
- mAnimateToQuiescent
- );
- as.setDuration(500);
- }
- as.start();
- }
- super.setPressed(pressed);
- }
-
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
int x, y;
@@ -354,17 +251,6 @@
InputManager.getInstance().injectInputEvent(ev,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
-
- /**
- * Interpolator with a smooth log deceleration
- */
- private static final class LogInterpolator implements TimeInterpolator {
- @Override
- public float getInterpolation(float input) {
- return 1 - (float) Math.pow(400, -input * 1.4);
- }
- }
-
}