Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ab32f87 authored by John Reck's avatar John Reck
Browse files

Add a frame commit callback test API

Bug: 111719753
Test: CtsUiRenderingTestCases
Change-Id: Ie08d49b735f5a42a2f06e9049547a2287ecce575
parent ce419f13
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -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);
@@ -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 {
+5 −0
Original line number Original line Diff line number Diff line
@@ -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
+21 −7
Original line number Original line Diff line number Diff line
@@ -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 {
+57 −0
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
@@ -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.
     *
     *