diff options
-rw-r--r-- | api/current.txt | 4 | ||||
-rw-r--r-- | core/java/android/view/GestureExclusionTracker.java | 125 | ||||
-rw-r--r-- | core/java/android/view/SurfaceView.java | 2 | ||||
-rw-r--r-- | core/java/android/view/View.java | 99 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 82 | ||||
-rw-r--r-- | core/java/android/view/ViewTreeObserver.java | 55 | ||||
-rw-r--r-- | graphics/java/android/graphics/RenderNode.java | 67 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java | 2 |
8 files changed, 402 insertions, 34 deletions
diff --git a/api/current.txt b/api/current.txt index 3cec35fd7208..968811d85d31 100644 --- a/api/current.txt +++ b/api/current.txt @@ -50502,6 +50502,7 @@ package android.view { method public android.animation.StateListAnimator getStateListAnimator(); method protected int getSuggestedMinimumHeight(); method protected int getSuggestedMinimumWidth(); + method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(); method public int getSystemUiVisibility(); method @android.view.ViewDebug.ExportedProperty public Object getTag(); method public Object getTag(int); @@ -50840,6 +50841,7 @@ package android.view { method public void setSelected(boolean); method public void setSoundEffectsEnabled(boolean); method public void setStateListAnimator(android.animation.StateListAnimator); + method public void setSystemGestureExclusionRects(@NonNull java.util.List<android.graphics.Rect>); method public void setSystemUiVisibility(int); method public void setTag(Object); method public void setTag(int, Object); @@ -51668,6 +51670,7 @@ package android.view { method public void addOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void addOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener); method public void addOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener); + method public void addOnSystemGestureExclusionRectsChangedListener(java.util.function.Consumer<java.util.List<android.graphics.Rect>>); method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void addOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void addOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); @@ -51682,6 +51685,7 @@ package android.view { method public void removeOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void removeOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener); method public void removeOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener); + method public void removeOnSystemGestureExclusionRectsChangedListener(java.util.function.Consumer<java.util.List<android.graphics.Rect>>); method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); diff --git a/core/java/android/view/GestureExclusionTracker.java b/core/java/android/view/GestureExclusionTracker.java new file mode 100644 index 000000000000..8eccc04fa647 --- /dev/null +++ b/core/java/android/view/GestureExclusionTracker.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2019 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.view; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Rect; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Used by {@link ViewRootImpl} to track system gesture exclusion rects reported by views. + */ +class GestureExclusionTracker { + private boolean mGestureExclusionViewsChanged = false; + private List<GestureExclusionViewInfo> mGestureExclusionViewInfos = new ArrayList<>(); + private List<Rect> mGestureExclusionRects = Collections.emptyList(); + + public void updateRectsForView(@NonNull View view) { + boolean found = false; + final Iterator<GestureExclusionViewInfo> i = mGestureExclusionViewInfos.iterator(); + while (i.hasNext()) { + final GestureExclusionViewInfo info = i.next(); + final View v = info.getView(); + if (v == null || !v.isAttachedToWindow()) { + mGestureExclusionViewsChanged = true; + i.remove(); + continue; + } + if (v == view) { + found = true; + info.mDirty = true; + break; + } + } + if (!found && view.isAttachedToWindow()) { + mGestureExclusionViewInfos.add(new GestureExclusionViewInfo(view)); + mGestureExclusionViewsChanged = true; + } + } + + @Nullable + public List<Rect> computeChangedRects() { + boolean changed = false; + final Iterator<GestureExclusionViewInfo> i = mGestureExclusionViewInfos.iterator(); + final List<Rect> rects = new ArrayList<>(); + while (i.hasNext()) { + final GestureExclusionViewInfo info = i.next(); + switch (info.update()) { + case GestureExclusionViewInfo.CHANGED: + changed = true; + // Deliberate fall-through + case GestureExclusionViewInfo.UNCHANGED: + rects.addAll(info.mExclusionRects); + break; + case GestureExclusionViewInfo.GONE: + mGestureExclusionViewsChanged = true; + i.remove(); + break; + } + } + if (changed || mGestureExclusionViewsChanged) { + mGestureExclusionViewsChanged = false; + if (!mGestureExclusionRects.equals(rects)) { + mGestureExclusionRects = rects; + return rects; + } + } + return null; + } + + private static class GestureExclusionViewInfo { + public static final int CHANGED = 0; + public static final int UNCHANGED = 1; + public static final int GONE = 2; + + private final WeakReference<View> mView; + boolean mDirty = true; + List<Rect> mExclusionRects = Collections.emptyList(); + + GestureExclusionViewInfo(View view) { + mView = new WeakReference<>(view); + } + + public View getView() { + return mView.get(); + } + + public int update() { + final View excludedView = getView(); + if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE; + final List<Rect> localRects = excludedView.getSystemGestureExclusionRects(); + final List<Rect> newRects = new ArrayList<>(localRects.size()); + for (Rect src : localRects) { + Rect mappedRect = new Rect(src); + ViewParent p = excludedView.getParent(); + if (p != null && p.getChildVisibleRect(excludedView, mappedRect, null)) { + newRects.add(mappedRect); + } + } + + if (mExclusionRects.equals(localRects)) return UNCHANGED; + mExclusionRects = newRects; + return CHANGED; + } + } +} diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index fe9aa234ba54..ee8d66313ea2 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -210,7 +210,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - mRenderNode.requestPositionUpdates(mPositionListener); + mRenderNode.addPositionUpdateListener(mPositionListener); setWillNotDraw(true); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 2d452a6b7c83..cc585b0294c7 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4597,6 +4597,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private ArrayList<OnUnhandledKeyEventListener> mUnhandledKeyListeners; private WindowInsetsAnimationListener mWindowInsetsAnimationListener; + + /** + * This lives here since it's only valid for interactive views. + */ + private List<Rect> mSystemGestureExclusionRects; + + /** + * Used to track {@link #mSystemGestureExclusionRects} + */ + public RenderNode.PositionUpdateListener mPositionUpdateListener; } @UnsupportedAppUsage @@ -10963,6 +10973,95 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Sets a list of areas within this view's post-layout coordinate space where the system + * should not intercept touch or other pointing device gestures. <em>This method should + * be called by {@link #onLayout(boolean, int, int, int, int)} or {@link #onDraw(Canvas)}.</em> + * + * <p>Use this to tell the system which specific sub-areas of a view need to receive gesture + * input in order to function correctly in the presence of global system gestures that may + * conflict. For example, if the system wishes to capture swipe-in-from-screen-edge gestures + * to provide system-level navigation functionality, a view such as a navigation drawer + * container can mark the left (or starting) edge of itself as requiring gesture capture + * priority using this API. The system may then choose to relax its own gesture recognition + * to allow the app to consume the user's gesture. It is not necessary for an app to register + * exclusion rects for broadly spanning regions such as the entirety of a + * <code>ScrollView</code> or for simple press and release click targets such as + * <code>Button</code>. Mark an exclusion rect when interacting with a view requires + * a precision touch gesture in a small area in either the X or Y dimension, such as + * an edge swipe or dragging a <code>SeekBar</code> thumb.</p> + * + * <p>Do not modify the provided list after this method is called.</p> + * + * @param rects A list of precision gesture regions that this view needs to function correctly + */ + public void setSystemGestureExclusionRects(@NonNull List<Rect> rects) { + if (rects.isEmpty() && mListenerInfo == null) return; + + final ListenerInfo info = getListenerInfo(); + if (rects.isEmpty()) { + info.mSystemGestureExclusionRects = null; + if (info.mPositionUpdateListener != null) { + mRenderNode.removePositionUpdateListener(info.mPositionUpdateListener); + } + } else { + info.mSystemGestureExclusionRects = rects; + if (info.mPositionUpdateListener == null) { + info.mPositionUpdateListener = new RenderNode.PositionUpdateListener() { + @Override + public void positionChanged(long n, int l, int t, int r, int b) { + postUpdateSystemGestureExclusionRects(); + } + + @Override + public void positionLost(long frameNumber) { + postUpdateSystemGestureExclusionRects(); + } + }; + mRenderNode.addPositionUpdateListener(info.mPositionUpdateListener); + } + } + postUpdateSystemGestureExclusionRects(); + } + + /** + * WARNING: this can be called by a hwui worker thread, not just the UI thread! + */ + void postUpdateSystemGestureExclusionRects() { + // Potentially racey from a background thread. It's ok if it's not perfect. + final Handler h = getHandler(); + if (h != null) { + h.postAtFrontOfQueue(this::updateSystemGestureExclusionRects); + } + } + + void updateSystemGestureExclusionRects() { + final AttachInfo ai = mAttachInfo; + if (ai != null) { + ai.mViewRootImpl.updateSystemGestureExclusionRectsForView(this); + } + } + + /** + * Retrieve the list of areas within this view's post-layout coordinate space where the system + * should not intercept touch or other pointing device gestures. + * + * <p>Do not modify the returned list.</p> + * + * @return the list set by {@link #setSystemGestureExclusionRects(List)} + */ + @NonNull + public List<Rect> getSystemGestureExclusionRects() { + final ListenerInfo info = mListenerInfo; + if (info != null) { + final List<Rect> list = info.mSystemGestureExclusionRects; + if (list != null) { + return list; + } + } + return Collections.emptyList(); + } + + /** * Compute the view's coordinate within the surface. * * <p>Computes the coordinates of this view in its surface. The argument diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index ad0aaa6edff6..65b1abd715d9 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -605,6 +605,8 @@ public final class ViewRootImpl implements ViewParent, private final InsetsController mInsetsController = new InsetsController(this); + private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); + static final class SystemUiVisibilityInfo { int seq; int globalVisibility; @@ -3977,6 +3979,20 @@ public final class ViewRootImpl implements ViewParent, return mAttachInfo.mAccessibilityFocusDrawable; } + void updateSystemGestureExclusionRectsForView(View view) { + mGestureExclusionTracker.updateRectsForView(view); + mHandler.sendEmptyMessage(MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED); + } + + void systemGestureExclusionChanged() { + final List<Rect> rectsForWindowManager = mGestureExclusionTracker.computeChangedRects(); + if (rectsForWindowManager != null) { + // TODO Send to WM + mAttachInfo.mTreeObserver + .dispatchOnSystemGestureExclusionRectsChanged(rectsForWindowManager); + } + } + /** * Requests that the root render node is invalidated next time we perform a draw, such that * {@link WindowCallbacks#onPostDraw} gets called. @@ -4433,35 +4449,36 @@ public final class ViewRootImpl implements ViewParent, } } - private final static int MSG_INVALIDATE = 1; - private final static int MSG_INVALIDATE_RECT = 2; - private final static int MSG_DIE = 3; - private final static int MSG_RESIZED = 4; - private final static int MSG_RESIZED_REPORT = 5; - private final static int MSG_WINDOW_FOCUS_CHANGED = 6; - private final static int MSG_DISPATCH_INPUT_EVENT = 7; - private final static int MSG_DISPATCH_APP_VISIBILITY = 8; - private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9; - private final static int MSG_DISPATCH_KEY_FROM_IME = 11; - private final static int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12; - private final static int MSG_CHECK_FOCUS = 13; - private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14; - private final static int MSG_DISPATCH_DRAG_EVENT = 15; - private final static int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16; - private final static int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17; - private final static int MSG_UPDATE_CONFIGURATION = 18; - private final static int MSG_PROCESS_INPUT_EVENTS = 19; - private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; - private final static int MSG_INVALIDATE_WORLD = 22; - private final static int MSG_WINDOW_MOVED = 23; - private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24; - private final static int MSG_DISPATCH_WINDOW_SHOWN = 25; - private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; - private final static int MSG_UPDATE_POINTER_ICON = 27; - private final static int MSG_POINTER_CAPTURE_CHANGED = 28; - private final static int MSG_DRAW_FINISHED = 29; - private final static int MSG_INSETS_CHANGED = 30; - private final static int MSG_INSETS_CONTROL_CHANGED = 31; + private static final int MSG_INVALIDATE = 1; + private static final int MSG_INVALIDATE_RECT = 2; + private static final int MSG_DIE = 3; + private static final int MSG_RESIZED = 4; + private static final int MSG_RESIZED_REPORT = 5; + private static final int MSG_WINDOW_FOCUS_CHANGED = 6; + private static final int MSG_DISPATCH_INPUT_EVENT = 7; + private static final int MSG_DISPATCH_APP_VISIBILITY = 8; + private static final int MSG_DISPATCH_GET_NEW_SURFACE = 9; + private static final int MSG_DISPATCH_KEY_FROM_IME = 11; + private static final int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12; + private static final int MSG_CHECK_FOCUS = 13; + private static final int MSG_CLOSE_SYSTEM_DIALOGS = 14; + private static final int MSG_DISPATCH_DRAG_EVENT = 15; + private static final int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16; + private static final int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17; + private static final int MSG_UPDATE_CONFIGURATION = 18; + private static final int MSG_PROCESS_INPUT_EVENTS = 19; + private static final int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; + private static final int MSG_INVALIDATE_WORLD = 22; + private static final int MSG_WINDOW_MOVED = 23; + private static final int MSG_SYNTHESIZE_INPUT_EVENT = 24; + private static final int MSG_DISPATCH_WINDOW_SHOWN = 25; + private static final int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; + private static final int MSG_UPDATE_POINTER_ICON = 27; + private static final int MSG_POINTER_CAPTURE_CHANGED = 28; + private static final int MSG_DRAW_FINISHED = 29; + private static final int MSG_INSETS_CHANGED = 30; + private static final int MSG_INSETS_CONTROL_CHANGED = 31; + private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 32; final class ViewRootHandler extends Handler { @Override @@ -4519,6 +4536,10 @@ public final class ViewRootImpl implements ViewParent, return "MSG_DRAW_FINISHED"; case MSG_INSETS_CHANGED: return "MSG_INSETS_CHANGED"; + case MSG_INSETS_CONTROL_CHANGED: + return "MSG_INSETS_CONTROL_CHANGED"; + case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: + return "MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED"; } return super.getMessageName(message); } @@ -4750,6 +4771,9 @@ public final class ViewRootImpl implements ViewParent, case MSG_DRAW_FINISHED: { pendingDrawFinished(); } break; + case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: { + systemGestureExclusionChanged(); + } break; } } } diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index 763ce4f45b01..2896bd049e7c 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -26,7 +26,9 @@ import android.os.Build; import android.util.Log; import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; /** * A view tree observer is used to register listeners that can be notified of global @@ -57,6 +59,7 @@ public final class ViewTreeObserver { private CopyOnWriteArray<OnScrollChangedListener> mOnScrollChangedListeners; private CopyOnWriteArray<OnPreDrawListener> mOnPreDrawListeners; private CopyOnWriteArray<OnWindowShownListener> mOnWindowShownListeners; + private CopyOnWriteArray<Consumer<List<Rect>>> mGestureExclusionListeners; // These listeners cannot be mutated during dispatch private boolean mInDispatchOnDraw; @@ -450,6 +453,14 @@ public final class ViewTreeObserver { } } + if (observer.mGestureExclusionListeners != null) { + if (mGestureExclusionListeners != null) { + mGestureExclusionListeners.addAll(observer.mGestureExclusionListeners); + } else { + mGestureExclusionListeners = observer.mGestureExclusionListeners; + } + } + observer.kill(); } @@ -913,6 +924,35 @@ public final class ViewTreeObserver { mOnEnterAnimationCompleteListeners.remove(listener); } + /** + * Add a listener to be notified when the tree's <em>transformed</em> gesture exclusion rects + * change. This could be the result of an animation or other layout change, or a view calling + * {@link View#setSystemGestureExclusionRects(List)}. + * + * @param listener listener to add + * @see View#setSystemGestureExclusionRects(List) + */ + public void addOnSystemGestureExclusionRectsChangedListener(Consumer<List<Rect>> listener) { + checkIsAlive(); + if (mGestureExclusionListeners == null) { + mGestureExclusionListeners = new CopyOnWriteArray<>(); + } + mGestureExclusionListeners.add(listener); + } + + /** + * Unsubscribe the given listener from gesture exclusion rect changes. + * @see #addOnSystemGestureExclusionRectsChangedListener(Consumer) + * @see View#setSystemGestureExclusionRects(List) + */ + public void removeOnSystemGestureExclusionRectsChangedListener(Consumer<List<Rect>> listener) { + checkIsAlive(); + if (mGestureExclusionListeners == null) { + return; + } + mGestureExclusionListeners.remove(listener); + } + private void checkIsAlive() { if (!mAlive) { throw new IllegalStateException("This ViewTreeObserver is not alive, call " @@ -1178,6 +1218,21 @@ public final class ViewTreeObserver { } } + void dispatchOnSystemGestureExclusionRectsChanged(@NonNull List<Rect> rects) { + final CopyOnWriteArray<Consumer<List<Rect>>> listeners = mGestureExclusionListeners; + if (listeners != null && listeners.size() > 0) { + CopyOnWriteArray.Access<Consumer<List<Rect>>> access = listeners.start(); + try { + final int count = access.size(); + for (int i = 0; i < count; i++) { + access.get(i).accept(rects); + } + } finally { + listeners.end(); + } + } + } + /** * Copy on write array. This array is not thread safe, and only one loop can * iterate over this array at any given time. This class avoids allocations diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index e98879d0c5bd..42b6acd3b25a 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -27,6 +27,8 @@ import android.view.RenderNodeAnimator; import android.view.Surface; import android.view.View; +import com.android.internal.util.ArrayUtils; + import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; @@ -179,6 +181,10 @@ public final class RenderNode { private final AnimationHost mAnimationHost; private RecordingCanvas mCurrentRecordingCanvas; + // Will be null if not currently registered + @Nullable + private CompositePositionUpdateListener mCompositePositionUpdateListener; + /** * Creates a new RenderNode that can be used to record batches of * drawing operations, and store / apply render properties when drawn. @@ -248,15 +254,70 @@ public final class RenderNode { } + private static final class CompositePositionUpdateListener implements PositionUpdateListener { + private final PositionUpdateListener[] mListeners; + + CompositePositionUpdateListener(PositionUpdateListener... listeners) { + mListeners = listeners; + } + + public CompositePositionUpdateListener with(PositionUpdateListener listener) { + return new CompositePositionUpdateListener( + ArrayUtils.appendElement(PositionUpdateListener.class, mListeners, listener)); + } + + public CompositePositionUpdateListener without(PositionUpdateListener listener) { + return new CompositePositionUpdateListener( + ArrayUtils.removeElement(PositionUpdateListener.class, mListeners, listener)); + } + + @Override + public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { + for (PositionUpdateListener pul : mListeners) { + pul.positionChanged(frameNumber, left, top, right, bottom); + } + } + + @Override + public void positionLost(long frameNumber) { + for (PositionUpdateListener pul : mListeners) { + pul.positionLost(frameNumber); + } + } + } + /** - * Enable callbacks for position changes. + * Enable callbacks for position changes. Call only from the UI thread or with + * external synchronization. * * @hide */ - public void requestPositionUpdates(PositionUpdateListener listener) { - nRequestPositionUpdates(mNativeRenderNode, listener); + public void addPositionUpdateListener(@NonNull PositionUpdateListener listener) { + CompositePositionUpdateListener comp = mCompositePositionUpdateListener; + if (comp == null) { + comp = new CompositePositionUpdateListener(listener); + } else { + comp = comp.with(listener); + } + mCompositePositionUpdateListener = comp; + nRequestPositionUpdates(mNativeRenderNode, comp); } + /** + * Disable a callback for position changes. Call only from the UI thread or with + * external synchronization. + * + * @param listener Callback to remove + * @hide + */ + public void removePositionUpdateListener(@NonNull PositionUpdateListener listener) { + CompositePositionUpdateListener comp = mCompositePositionUpdateListener; + if (comp != null) { + comp = comp.without(listener); + mCompositePositionUpdateListener = comp; + nRequestPositionUpdates(mNativeRenderNode, comp); + } + } /** * Starts recording a display list for the render node. All diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java index 316aad343d19..818d899413de 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java @@ -53,7 +53,7 @@ public class PositionListenerActivity extends Activity { MyPositionReporter(Context c) { super(c); mNode = new RenderNode("positionListener"); - mNode.requestPositionUpdates(this); + mNode.addPositionUpdateListener(this); setTextAlignment(TEXT_ALIGNMENT_VIEW_START); } |