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

Commit 1376d600 authored by Svetoslav's avatar Svetoslav
Browse files

Adding render stats APIs to UiAutomation (framework).

bug:12927198

Change-Id: Iae21481c75ae58dcdab3731bf5f1e2844e29d434
parent ed3db02c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -412,6 +412,8 @@ aidl_files := \
	frameworks/base/core/java/android/view/MotionEvent.aidl \
	frameworks/base/core/java/android/view/Surface.aidl \
	frameworks/base/core/java/android/view/WindowManager.aidl \
	frameworks/base/core/java/android/view/WindowAnimationFrameStats.aidl \
	frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
	frameworks/base/core/java/android/widget/RemoteViews.aidl \
	frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerService.aidl \
	frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \
+30 −0
Original line number Diff line number Diff line
@@ -4741,9 +4741,13 @@ package android.app {
  }
  public final class UiAutomation {
    method public void clearWindowAnimationFrameStats();
    method public boolean clearWindowContentFrameStats(int);
    method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
    method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
    method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
    method public android.view.WindowAnimationFrameStats getWindowAnimationFrameStats();
    method public android.view.WindowContentFrameStats getWindowContentFrameStats(int);
    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
    method public boolean injectInputEvent(android.view.InputEvent, boolean);
    method public final boolean performGlobalAction(int);
@@ -28223,6 +28227,18 @@ package android.view {
    method public static android.view.FocusFinder getInstance();
  }
  public abstract class FrameStats {
    ctor public FrameStats();
    method public final long getEndTimeNano();
    method public final int getFrameCount();
    method public final long getFramePresentedTimeNano(int);
    method public final long getRefreshPeriodNano();
    method public final long getStartTimeNano();
    field public static final long UNDEFINED_TIME_NANO = -1L; // 0xffffffffffffffffL
    field protected long[] mFramesPresentedTimeNano;
    field protected long mRefreshPeriodNano;
  }
  public class GestureDetector {
    ctor public deprecated GestureDetector(android.view.GestureDetector.OnGestureListener, android.os.Handler);
    ctor public deprecated GestureDetector(android.view.GestureDetector.OnGestureListener);
@@ -30546,6 +30562,20 @@ package android.view {
    method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
  }
  public final class WindowAnimationFrameStats extends android.view.FrameStats implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
  }
  public final class WindowContentFrameStats extends android.view.FrameStats implements android.os.Parcelable {
    method public int describeContents();
    method public long getFramePostedTimeNano(int);
    method public long getFrameReadyTimeNano(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
  }
  public class WindowId implements android.os.Parcelable {
    method public int describeContents();
    method public boolean isFocused();
+7 −1
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.app;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.graphics.Bitmap;
import android.view.InputEvent;
import android.view.WindowContentFrameStats;
import android.view.WindowAnimationFrameStats;
import android.os.ParcelFileDescriptor;

/**
@@ -37,4 +39,8 @@ interface IUiAutomationConnection {
    boolean setRotation(int rotation);
    Bitmap takeScreenshot(int width, int height);
    void shutdown();
    boolean clearWindowContentFrameStats(int windowId);
    WindowContentFrameStats getWindowContentFrameStats(int windowId);
    void clearWindowAnimationFrameStats();
    WindowAnimationFrameStats getWindowAnimationFrameStats();
}
+144 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import android.view.Display;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.WindowAnimationFrameStats;
import android.view.WindowContentFrameStats;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -674,6 +676,148 @@ public final class UiAutomation {
        }
    }

    /**
     * Clears the frame statistics for the content of a given window. These
     * statistics contain information about the most recently rendered content
     * frames.
     *
     * @param windowId The window id.
     * @return Whether the window is present and its frame statistics
     *         were cleared.
     *
     * @see android.view.WindowContentFrameStats
     * @see #getWindowContentFrameStats(int)
     * @see #getWindows()
     * @see AccessibilityWindowInfo#getId() AccessibilityWindowInfo.getId()
     */
    public boolean clearWindowContentFrameStats(int windowId) {
        synchronized (mLock) {
            throwIfNotConnectedLocked();
        }
        try {
            if (DEBUG) {
                Log.i(LOG_TAG, "Clearing content frame stats for window: " + windowId);
            }
            // Calling out without a lock held.
            return mUiAutomationConnection.clearWindowContentFrameStats(windowId);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error clearing window content frame stats!", re);
        }
        return false;
    }

    /**
     * Gets the frame statistics for a given window. These statistics contain
     * information about the most recently rendered content frames.
     * <p>
     * A typical usage requires clearing the window frame statistics via {@link
     * #clearWindowContentFrameStats(int)} followed by an interaction with the UI and
     * finally getting the window frame statistics via calling this method.
     * </p>
     * <pre>
     * // Assume we have at least one window.
     * final int windowId = getWindows().get(0).getId();
     *
     * // Start with a clean slate.
     * uiAutimation.clearWindowContentFrameStats(windowId);
     *
     * // Do stuff with the UI.
     *
     * // Get the frame statistics.
     * WindowContentFrameStats stats = uiAutomation.getWindowContentFrameStats(windowId);
     * </pre>
     *
     * @param windowId The window id.
     * @return The window frame statistics, or null if the window is not present.
     *
     * @see android.view.WindowContentFrameStats
     * @see #clearWindowContentFrameStats(int)
     * @see #getWindows()
     * @see AccessibilityWindowInfo#getId() AccessibilityWindowInfo.getId()
     */
    public WindowContentFrameStats getWindowContentFrameStats(int windowId) {
        synchronized (mLock) {
            throwIfNotConnectedLocked();
        }
        try {
            if (DEBUG) {
                Log.i(LOG_TAG, "Getting content frame stats for window: " + windowId);
            }
            // Calling out without a lock held.
            return mUiAutomationConnection.getWindowContentFrameStats(windowId);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error getting window content frame stats!", re);
        }
        return null;
    }

    /**
     * Clears the window animation rendering statistics. These statistics contain
     * information about the most recently rendered window animation frames, i.e.
     * for window transition animations.
     *
     * @see android.view.WindowAnimationFrameStats
     * @see #getWindowAnimationFrameStats()
     * @see android.R.styleable#WindowAnimation
     */
    public void clearWindowAnimationFrameStats() {
        synchronized (mLock) {
            throwIfNotConnectedLocked();
        }
        try {
            if (DEBUG) {
                Log.i(LOG_TAG, "Clearing window animation frame stats");
            }
            // Calling out without a lock held.
            mUiAutomationConnection.clearWindowAnimationFrameStats();
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error clearing window animation frame stats!", re);
        }
    }

    /**
     * Gets the window animation frame statistics. These statistics contain
     * information about the most recently rendered window animation frames, i.e.
     * for window transition animations.
     *
     * <p>
     * A typical usage requires clearing the window animation frame statistics via
     * {@link #clearWindowAnimationFrameStats()} followed by an interaction that causes
     * a window transition which uses a window animation and finally getting the window
     * animation frame statistics by calling this method.
     * </p>
     * <pre>
     * // Start with a clean slate.
     * uiAutimation.clearWindowAnimationFrameStats();
     *
     * // Do stuff to trigger a window transition.
     *
     * // Get the frame statistics.
     * WindowAnimationFrameStats stats = uiAutomation.getWindowAnimationFrameStats();
     * </pre>
     *
     * @return The window animation frame statistics.
     *
     * @see android.view.WindowAnimationFrameStats
     * @see #clearWindowAnimationFrameStats()
     * @see android.R.styleable#WindowAnimation
     */
    public WindowAnimationFrameStats getWindowAnimationFrameStats() {
        synchronized (mLock) {
            throwIfNotConnectedLocked();
        }
        try {
            if (DEBUG) {
                Log.i(LOG_TAG, "Getting window animation frame stats");
            }
            // Calling out without a lock held.
            return mUiAutomationConnection.getWindowAnimationFrameStats();
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error getting window animation frame stats!", re);
        }
        return null;
    }

    private static float getDegreesForRotation(int value) {
        switch (value) {
            case Surface.ROTATION_90: {
+76 −0
Original line number Diff line number Diff line
@@ -22,12 +22,15 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.view.IWindowManager;
import android.view.InputEvent;
import android.view.SurfaceControl;
import android.view.WindowAnimationFrameStats;
import android.view.WindowContentFrameStats;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.IAccessibilityManager;

@@ -47,6 +50,9 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
    private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
            ServiceManager.getService(Service.WINDOW_SERVICE));

    private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub.asInterface(
            ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));

    private final Object mLock = new Object();

    private final Binder mToken = new Binder();
@@ -143,6 +149,76 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
        }
    }

    @Override
    public boolean clearWindowContentFrameStats(int windowId) throws RemoteException {
        synchronized (mLock) {
            throwIfCalledByNotTrustedUidLocked();
            throwIfShutdownLocked();
            throwIfNotConnectedLocked();
        }
        final long identity = Binder.clearCallingIdentity();
        try {
            IBinder token = mAccessibilityManager.getWindowToken(windowId);
            if (token == null) {
                return false;
            }
            return mWindowManager.clearWindowContentFrameStats(token);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public WindowContentFrameStats getWindowContentFrameStats(int windowId) throws RemoteException {
        synchronized (mLock) {
            throwIfCalledByNotTrustedUidLocked();
            throwIfShutdownLocked();
            throwIfNotConnectedLocked();
        }
        final long identity = Binder.clearCallingIdentity();
        try {
            IBinder token = mAccessibilityManager.getWindowToken(windowId);
            if (token == null) {
                return null;
            }
            return mWindowManager.getWindowContentFrameStats(token);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public void clearWindowAnimationFrameStats() {
        synchronized (mLock) {
            throwIfCalledByNotTrustedUidLocked();
            throwIfShutdownLocked();
            throwIfNotConnectedLocked();
        }
        final long identity = Binder.clearCallingIdentity();
        try {
            SurfaceControl.clearAnimationFrameStats();
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public WindowAnimationFrameStats getWindowAnimationFrameStats() {
        synchronized (mLock) {
            throwIfCalledByNotTrustedUidLocked();
            throwIfShutdownLocked();
            throwIfNotConnectedLocked();
        }
        final long identity = Binder.clearCallingIdentity();
        try {
            WindowAnimationFrameStats stats = new WindowAnimationFrameStats();
            SurfaceControl.getAnimationFrameStats(stats);
            return stats;
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public void shutdown() {
        synchronized (mLock) {
Loading