Loading api/current.txt +2 −0 Original line number Original line Diff line number Diff line Loading @@ -48817,6 +48817,7 @@ package android.view { method public void dispatchOnGlobalLayout(); method public void dispatchOnGlobalLayout(); method public boolean dispatchOnPreDraw(); method public boolean dispatchOnPreDraw(); method public boolean isAlive(); method public boolean isAlive(); method public void registerFrameCommitCallback(java.lang.Runnable); method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener); method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener); method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener); method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener); Loading @@ -48826,6 +48827,7 @@ package android.view { method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); method public boolean unregisterFrameCommitCallback(java.lang.Runnable); } } public static abstract interface ViewTreeObserver.OnDrawListener { public static abstract interface ViewTreeObserver.OnDrawListener { api/test-current.txt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -1467,6 +1467,11 @@ package android.view { method public static int getLongPressTooltipHideTimeout(); method public static int getLongPressTooltipHideTimeout(); } } public final class ViewTreeObserver { method public void registerFrameCommitCallback(java.lang.Runnable); method public boolean unregisterFrameCommitCallback(java.lang.Runnable); } public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000 field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000 field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40 field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40 Loading core/java/android/view/ViewRootImpl.java +21 −7 Original line number Original line Diff line number Diff line Loading @@ -3097,13 +3097,27 @@ public final class ViewRootImpl implements ViewParent, Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw"); Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw"); boolean usingAsyncReport = false; boolean usingAsyncReport = false; if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) { && mAttachInfo.mThreadedRenderer.isEnabled()) { ArrayList<Runnable> commitCallbacks = mAttachInfo.mTreeObserver .captureFrameCommitCallbacks(); if (mReportNextDraw) { usingAsyncReport = true; usingAsyncReport = true; mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { // TODO: Use the frame number // TODO: Use the frame number pendingDrawFinished(); pendingDrawFinished(); if (commitCallbacks != null) { for (int i = 0; i < commitCallbacks.size(); i++) { commitCallbacks.get(i).run(); } } }); }); } else if (commitCallbacks != null && commitCallbacks.size() > 0) { mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { for (int i = 0; i < commitCallbacks.size(); i++) { commitCallbacks.get(i).run(); } }); } } } try { try { Loading core/java/android/view/ViewTreeObserver.java +57 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.view; package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.content.Context; import android.content.Context; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region; Loading Loading @@ -56,6 +59,9 @@ public final class ViewTreeObserver { private ArrayList<OnDrawListener> mOnDrawListeners; private ArrayList<OnDrawListener> mOnDrawListeners; private static boolean sIllegalOnDrawModificationIsFatal; private static boolean sIllegalOnDrawModificationIsFatal; // These listeners are one-shot private ArrayList<Runnable> mOnFrameCommitListeners; /** Remains false until #dispatchOnWindowShown() is called. If a listener registers after /** Remains false until #dispatchOnWindowShown() is called. If a listener registers after * that the listener will be immediately called. */ * that the listener will be immediately called. */ private boolean mWindowShown; private boolean mWindowShown; Loading Loading @@ -393,6 +399,14 @@ public final class ViewTreeObserver { } } } } if (observer.mOnFrameCommitListeners != null) { if (mOnFrameCommitListeners != null) { mOnFrameCommitListeners.addAll(observer.captureFrameCommitCallbacks()); } else { mOnFrameCommitListeners = observer.captureFrameCommitCallbacks(); } } if (observer.mOnTouchModeChangeListeners != null) { if (observer.mOnTouchModeChangeListeners != null) { if (mOnTouchModeChangeListeners != null) { if (mOnTouchModeChangeListeners != null) { mOnTouchModeChangeListeners.addAll(observer.mOnTouchModeChangeListeners); mOnTouchModeChangeListeners.addAll(observer.mOnTouchModeChangeListeners); Loading Loading @@ -712,6 +726,49 @@ public final class ViewTreeObserver { mOnDrawListeners.remove(victim); mOnDrawListeners.remove(victim); } } /** * Adds a frame commit callback. This callback will be invoked when the current rendering * content has been rendered into a frame and submitted to the swap chain. The frame may * not currently be visible on the display when this is invoked, but it has been submitted. * This callback is useful in combination with {@link PixelCopy} to capture the current * rendered content of the UI reliably. * * Note: Only works with hardware rendering. Does nothing otherwise. * * @param callback The callback to invoke when the frame is committed. */ @TestApi public void registerFrameCommitCallback(@NonNull Runnable callback) { checkIsAlive(); if (mOnFrameCommitListeners == null) { mOnFrameCommitListeners = new ArrayList<>(); } mOnFrameCommitListeners.add(callback); } @Nullable ArrayList<Runnable> captureFrameCommitCallbacks() { ArrayList<Runnable> ret = mOnFrameCommitListeners; mOnFrameCommitListeners = null; return ret; } /** * Attempts to remove the given callback from the list of pending frame complete callbacks. * * @param callback The callback to remove * @return Whether or not the callback was removed. If this returns true the callback will * not be invoked. If false is returned then the callback was either never added * or may already be pending execution and was unable to be removed */ @TestApi public boolean unregisterFrameCommitCallback(@NonNull Runnable callback) { checkIsAlive(); if (mOnFrameCommitListeners == null) { return false; } return mOnFrameCommitListeners.remove(callback); } /** /** * Register a callback to be invoked when a view has been scrolled. * Register a callback to be invoked when a view has been scrolled. * * Loading Loading
api/current.txt +2 −0 Original line number Original line Diff line number Diff line Loading @@ -48817,6 +48817,7 @@ package android.view { method public void dispatchOnGlobalLayout(); method public void dispatchOnGlobalLayout(); method public boolean dispatchOnPreDraw(); method public boolean dispatchOnPreDraw(); method public boolean isAlive(); method public boolean isAlive(); method public void registerFrameCommitCallback(java.lang.Runnable); method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener); method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener); method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener); method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener); Loading @@ -48826,6 +48827,7 @@ package android.view { method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); method public boolean unregisterFrameCommitCallback(java.lang.Runnable); } } public static abstract interface ViewTreeObserver.OnDrawListener { public static abstract interface ViewTreeObserver.OnDrawListener {
api/test-current.txt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -1467,6 +1467,11 @@ package android.view { method public static int getLongPressTooltipHideTimeout(); method public static int getLongPressTooltipHideTimeout(); } } public final class ViewTreeObserver { method public void registerFrameCommitCallback(java.lang.Runnable); method public boolean unregisterFrameCommitCallback(java.lang.Runnable); } public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000 field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000 field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40 field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40 Loading
core/java/android/view/ViewRootImpl.java +21 −7 Original line number Original line Diff line number Diff line Loading @@ -3097,13 +3097,27 @@ public final class ViewRootImpl implements ViewParent, Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw"); Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw"); boolean usingAsyncReport = false; boolean usingAsyncReport = false; if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) { && mAttachInfo.mThreadedRenderer.isEnabled()) { ArrayList<Runnable> commitCallbacks = mAttachInfo.mTreeObserver .captureFrameCommitCallbacks(); if (mReportNextDraw) { usingAsyncReport = true; usingAsyncReport = true; mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { // TODO: Use the frame number // TODO: Use the frame number pendingDrawFinished(); pendingDrawFinished(); if (commitCallbacks != null) { for (int i = 0; i < commitCallbacks.size(); i++) { commitCallbacks.get(i).run(); } } }); }); } else if (commitCallbacks != null && commitCallbacks.size() > 0) { mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { for (int i = 0; i < commitCallbacks.size(); i++) { commitCallbacks.get(i).run(); } }); } } } try { try { Loading
core/java/android/view/ViewTreeObserver.java +57 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.view; package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.content.Context; import android.content.Context; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region; Loading Loading @@ -56,6 +59,9 @@ public final class ViewTreeObserver { private ArrayList<OnDrawListener> mOnDrawListeners; private ArrayList<OnDrawListener> mOnDrawListeners; private static boolean sIllegalOnDrawModificationIsFatal; private static boolean sIllegalOnDrawModificationIsFatal; // These listeners are one-shot private ArrayList<Runnable> mOnFrameCommitListeners; /** Remains false until #dispatchOnWindowShown() is called. If a listener registers after /** Remains false until #dispatchOnWindowShown() is called. If a listener registers after * that the listener will be immediately called. */ * that the listener will be immediately called. */ private boolean mWindowShown; private boolean mWindowShown; Loading Loading @@ -393,6 +399,14 @@ public final class ViewTreeObserver { } } } } if (observer.mOnFrameCommitListeners != null) { if (mOnFrameCommitListeners != null) { mOnFrameCommitListeners.addAll(observer.captureFrameCommitCallbacks()); } else { mOnFrameCommitListeners = observer.captureFrameCommitCallbacks(); } } if (observer.mOnTouchModeChangeListeners != null) { if (observer.mOnTouchModeChangeListeners != null) { if (mOnTouchModeChangeListeners != null) { if (mOnTouchModeChangeListeners != null) { mOnTouchModeChangeListeners.addAll(observer.mOnTouchModeChangeListeners); mOnTouchModeChangeListeners.addAll(observer.mOnTouchModeChangeListeners); Loading Loading @@ -712,6 +726,49 @@ public final class ViewTreeObserver { mOnDrawListeners.remove(victim); mOnDrawListeners.remove(victim); } } /** * Adds a frame commit callback. This callback will be invoked when the current rendering * content has been rendered into a frame and submitted to the swap chain. The frame may * not currently be visible on the display when this is invoked, but it has been submitted. * This callback is useful in combination with {@link PixelCopy} to capture the current * rendered content of the UI reliably. * * Note: Only works with hardware rendering. Does nothing otherwise. * * @param callback The callback to invoke when the frame is committed. */ @TestApi public void registerFrameCommitCallback(@NonNull Runnable callback) { checkIsAlive(); if (mOnFrameCommitListeners == null) { mOnFrameCommitListeners = new ArrayList<>(); } mOnFrameCommitListeners.add(callback); } @Nullable ArrayList<Runnable> captureFrameCommitCallbacks() { ArrayList<Runnable> ret = mOnFrameCommitListeners; mOnFrameCommitListeners = null; return ret; } /** * Attempts to remove the given callback from the list of pending frame complete callbacks. * * @param callback The callback to remove * @return Whether or not the callback was removed. If this returns true the callback will * not be invoked. If false is returned then the callback was either never added * or may already be pending execution and was unable to be removed */ @TestApi public boolean unregisterFrameCommitCallback(@NonNull Runnable callback) { checkIsAlive(); if (mOnFrameCommitListeners == null) { return false; } return mOnFrameCommitListeners.remove(callback); } /** /** * Register a callback to be invoked when a view has been scrolled. * Register a callback to be invoked when a view has been scrolled. * * Loading