diff options
author | Jorim Jaggi <jjaggi@google.com> | 2014-05-21 15:45:07 +0200 |
---|---|---|
committer | Jorim Jaggi <jjaggi@google.com> | 2014-05-22 01:01:36 +0200 |
commit | b7b61ddaef4f2a2ebc79e832fb909fd4dcac8ba5 (patch) | |
tree | 1706d3f4b90b2073ecaaa1f3921481dd4dc8d54f /packages/SystemUI/src/com | |
parent | e660694c6906ff997ff03eb312cfc8f15279d6d8 (diff) | |
download | frameworks_base-b7b61ddaef4f2a2ebc79e832fb909fd4dcac8ba5.zip frameworks_base-b7b61ddaef4f2a2ebc79e832fb909fd4dcac8ba5.tar.gz frameworks_base-b7b61ddaef4f2a2ebc79e832fb909fd4dcac8ba5.tar.bz2 |
Make velocity tracker used in panel dependent on config.
The velocity tracker used in PanelView can now be configured with
a boolean value. The default is to use tha platform-standard velocity
tracker, but can be overriden to use our own velocity tracker for
noisy touch screens instead.
Change-Id: I375f4e2675ddbaa003acd6f085065bb3fe59ebf4
Diffstat (limited to 'packages/SystemUI/src/com')
5 files changed, 287 insertions, 119 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NoisyVelocityTracker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NoisyVelocityTracker.java new file mode 100644 index 0000000..214dda2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NoisyVelocityTracker.java @@ -0,0 +1,135 @@ +/* + * 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.phone; + +import android.util.Log; +import android.util.Pools; +import android.view.MotionEvent; + +import java.util.ArrayDeque; +import java.util.Iterator; + +/** + * A very simple low-pass velocity filter for motion events for noisy touch screens. + */ +public class NoisyVelocityTracker implements VelocityTrackerInterface { + + private static final Pools.SynchronizedPool<NoisyVelocityTracker> sNoisyPool = + new Pools.SynchronizedPool<>(2); + + private static final float DECAY = 0.75f; + private static final boolean DEBUG = false; + + private final int MAX_EVENTS = 8; + private ArrayDeque<MotionEventCopy> mEventBuf = new ArrayDeque<MotionEventCopy>(MAX_EVENTS); + private float mVX, mVY = 0; + + private static class MotionEventCopy { + public MotionEventCopy(float x2, float y2, long eventTime) { + this.x = x2; + this.y = y2; + this.t = eventTime; + } + float x, y; + long t; + } + + public static NoisyVelocityTracker obtain() { + NoisyVelocityTracker instance = sNoisyPool.acquire(); + return (instance != null) ? instance : new NoisyVelocityTracker(); + } + + private NoisyVelocityTracker() { + } + + public void addMovement(MotionEvent event) { + if (mEventBuf.size() == MAX_EVENTS) { + mEventBuf.remove(); + } + mEventBuf.add(new MotionEventCopy(event.getX(), event.getY(), event.getEventTime())); + } + + public void computeCurrentVelocity(int units) { + if (NoisyVelocityTracker.DEBUG) { + Log.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events"); + } + mVX = mVY = 0; + MotionEventCopy last = null; + int i = 0; + float totalweight = 0f; + float weight = 10f; + for (final Iterator<MotionEventCopy> iter = mEventBuf.iterator(); + iter.hasNext();) { + final MotionEventCopy event = iter.next(); + if (last != null) { + final float dt = (float) (event.t - last.t) / units; + final float dx = (event.x - last.x); + final float dy = (event.y - last.y); + if (NoisyVelocityTracker.DEBUG) { + Log.v("FlingTracker", String.format( + " [%d] (t=%d %.1f,%.1f) dx=%.1f dy=%.1f dt=%f vx=%.1f vy=%.1f", + i, event.t, event.x, event.y, + dx, dy, dt, + (dx/dt), + (dy/dt) + )); + } + if (event.t == last.t) { + // Really not sure what to do with events that happened at the same time, + // so we'll skip subsequent events. + continue; + } + mVX += weight * dx / dt; + mVY += weight * dy / dt; + totalweight += weight; + weight *= DECAY; + } + last = event; + i++; + } + if (totalweight > 0) { + mVX /= totalweight; + mVY /= totalweight; + } else { + // so as not to contaminate the velocities with NaN + mVX = mVY = 0; + } + + if (NoisyVelocityTracker.DEBUG) { + Log.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY); + } + } + + public float getXVelocity() { + if (Float.isNaN(mVX) || Float.isInfinite(mVX)) { + mVX = 0; + } + return mVX; + } + + public float getYVelocity() { + if (Float.isNaN(mVY) || Float.isInfinite(mVX)) { + mVY = 0; + } + return mVY; + } + + public void recycle() { + mEventBuf.clear(); + sNoisyPool.release(this); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 517f763..a89fc0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -80,123 +80,7 @@ public class PanelView extends FrameLayout { private TimeAnimator mTimeAnimator; private ObjectAnimator mPeekAnimator; - private FlingTracker mVelocityTracker; - - /** - * A very simple low-pass velocity filter for motion events; not nearly as sophisticated as - * VelocityTracker but optimized for the kinds of gestures we expect to see in status bar - * panels. - */ - private static class FlingTracker { - static final boolean DEBUG = false; - final int MAX_EVENTS = 8; - final float DECAY = 0.75f; - ArrayDeque<MotionEventCopy> mEventBuf = new ArrayDeque<MotionEventCopy>(MAX_EVENTS); - float mVX, mVY = 0; - private static class MotionEventCopy { - public MotionEventCopy(float x2, float y2, long eventTime) { - this.x = x2; - this.y = y2; - this.t = eventTime; - } - public float x, y; - public long t; - } - public FlingTracker() { - } - public void addMovement(MotionEvent event) { - if (mEventBuf.size() == MAX_EVENTS) { - mEventBuf.remove(); - } - mEventBuf.add(new MotionEventCopy(event.getX(), event.getY(), event.getEventTime())); - } - public void computeCurrentVelocity(long timebase) { - if (FlingTracker.DEBUG) { - Log.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events"); - } - mVX = mVY = 0; - MotionEventCopy last = null; - int i = 0; - float totalweight = 0f; - float weight = 10f; - for (final Iterator<MotionEventCopy> iter = mEventBuf.iterator(); - iter.hasNext();) { - final MotionEventCopy event = iter.next(); - if (last != null) { - final float dt = (float) (event.t - last.t) / timebase; - final float dx = (event.x - last.x); - final float dy = (event.y - last.y); - if (FlingTracker.DEBUG) { - Log.v("FlingTracker", String.format( - " [%d] (t=%d %.1f,%.1f) dx=%.1f dy=%.1f dt=%f vx=%.1f vy=%.1f", - i, event.t, event.x, event.y, - dx, dy, dt, - (dx/dt), - (dy/dt) - )); - } - if (event.t == last.t) { - // Really not sure what to do with events that happened at the same time, - // so we'll skip subsequent events. - if (DEBUG_NAN) { - Log.v("FlingTracker", "skipping simultaneous event at t=" + event.t); - } - continue; - } - mVX += weight * dx / dt; - mVY += weight * dy / dt; - totalweight += weight; - weight *= DECAY; - } - last = event; - i++; - } - if (totalweight > 0) { - mVX /= totalweight; - mVY /= totalweight; - } else { - if (DEBUG_NAN) { - Log.v("FlingTracker", "computeCurrentVelocity warning: totalweight=0", - new Throwable()); - } - // so as not to contaminate the velocities with NaN - mVX = mVY = 0; - } - - if (FlingTracker.DEBUG) { - Log.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY); - } - } - public float getXVelocity() { - if (Float.isNaN(mVX) || Float.isInfinite(mVX)) { - if (DEBUG_NAN) { - Log.v("FlingTracker", "warning: vx=" + mVX); - } - mVX = 0; - } - return mVX; - } - public float getYVelocity() { - if (Float.isNaN(mVY) || Float.isInfinite(mVX)) { - if (DEBUG_NAN) { - Log.v("FlingTracker", "warning: vx=" + mVY); - } - mVY = 0; - } - return mVY; - } - public void recycle() { - mEventBuf.clear(); - } - - static FlingTracker sTracker; - static FlingTracker obtain() { - if (sTracker == null) { - sTracker = new FlingTracker(); - } - return sTracker; - } - } + private VelocityTrackerInterface mVelocityTracker; PanelBar mBar; @@ -385,7 +269,9 @@ public class PanelView extends FrameLayout { mInitialTouchY = y; mInitialTouchX = x; - initVelocityTracker(); + if (mVelocityTracker == null) { + initVelocityTracker(); + } trackMovement(event); mTimeAnimator.cancel(); // end any outstanding animations onTrackingStarted(); @@ -569,7 +455,7 @@ public class PanelView extends FrameLayout { if (mVelocityTracker != null) { mVelocityTracker.recycle(); } - mVelocityTracker = FlingTracker.obtain(); + mVelocityTracker = VelocityTrackerFactory.obtain(getContext()); } protected boolean isScrolledToBottom() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PlatformVelocityTracker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PlatformVelocityTracker.java new file mode 100644 index 0000000..f589c3d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PlatformVelocityTracker.java @@ -0,0 +1,72 @@ +/* + * 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.phone; + +import android.util.Pools; +import android.view.MotionEvent; +import android.view.VelocityTracker; + +/** + * An implementation of {@link VelocityTrackerInterface} using the platform-standard + * {@link VelocityTracker}. + */ +public class PlatformVelocityTracker implements VelocityTrackerInterface { + + private static final Pools.SynchronizedPool<PlatformVelocityTracker> sPool = + new Pools.SynchronizedPool<>(2); + + private VelocityTracker mTracker; + + public static PlatformVelocityTracker obtain() { + PlatformVelocityTracker tracker = sPool.acquire(); + if (tracker == null) { + tracker = new PlatformVelocityTracker(); + } + tracker.setTracker(VelocityTracker.obtain()); + return tracker; + } + + public void setTracker(VelocityTracker tracker) { + mTracker = tracker; + } + + @Override + public void addMovement(MotionEvent event) { + mTracker.addMovement(event); + } + + @Override + public void computeCurrentVelocity(int units) { + mTracker.computeCurrentVelocity(units); + } + + @Override + public float getXVelocity() { + return mTracker.getXVelocity(); + } + + @Override + public float getYVelocity() { + return mTracker.getYVelocity(); + } + + @Override + public void recycle() { + mTracker.recycle(); + sPool.release(this); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/VelocityTrackerFactory.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/VelocityTrackerFactory.java new file mode 100644 index 0000000..4f43b4d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/VelocityTrackerFactory.java @@ -0,0 +1,44 @@ +/* + * 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.phone; + +import android.content.Context; + +import com.android.systemui.R; + +import static android.util.Pools.SynchronizedPool; + +/** + * A class to generate {@link VelocityTrackerInterface}, depending on the configuration. + */ +public class VelocityTrackerFactory { + + public static final String PLATFORM_IMPL = "platform"; + public static final String NOISY_IMPL = "noisy"; + + public static VelocityTrackerInterface obtain(Context ctx) { + String tracker = ctx.getResources().getString(R.string.velocity_tracker_impl); + switch (tracker) { + case NOISY_IMPL: + return NoisyVelocityTracker.obtain(); + case PLATFORM_IMPL: + return PlatformVelocityTracker.obtain(); + default: + throw new IllegalStateException("Invalid tracker: " + tracker); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/VelocityTrackerInterface.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/VelocityTrackerInterface.java new file mode 100644 index 0000000..a54b054 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/VelocityTrackerInterface.java @@ -0,0 +1,31 @@ +/* + * 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.phone; + +import android.view.MotionEvent; + +/** + * An interface for a velocity tracker to delegate. To be implemented by different velocity tracking + * algorithms. + */ +public interface VelocityTrackerInterface { + public void addMovement(MotionEvent event); + public void computeCurrentVelocity(int units); + public float getXVelocity(); + public float getYVelocity(); + public void recycle(); +} |