Adding render stats APIs to UiAutomation (framework).
bug:12927198 Change-Id: Iae21481c75ae58dcdab3731bf5f1e2844e29d434
This commit is contained in:
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -26,7 +28,7 @@ import android.os.ParcelFileDescriptor;
|
||||
* on behalf of an instrumentation that it runs. These operations require
|
||||
* special permissions which the shell user has but the instrumentation does
|
||||
* not. Running privileged operations by the shell user on behalf of an
|
||||
* instrumentation is needed for running UiTestCases.
|
||||
* instrumentation is needed for running UiTestCases.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
19
core/java/android/view/AnimationRenderStats.aidl
Normal file
19
core/java/android/view/AnimationRenderStats.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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 android.view;
|
||||
|
||||
parcelable AnimationRenderStats;
|
||||
97
core/java/android/view/FrameStats.java
Normal file
97
core/java/android/view/FrameStats.java
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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 android.view;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* This is the base class for frame statistics.
|
||||
*/
|
||||
public abstract class FrameStats {
|
||||
/**
|
||||
* Undefined time.
|
||||
*/
|
||||
public static final long UNDEFINED_TIME_NANO = -1;
|
||||
|
||||
protected long mRefreshPeriodNano;
|
||||
protected long[] mFramesPresentedTimeNano;
|
||||
|
||||
/**
|
||||
* Gets the refresh period of the display hosting the window(s) for
|
||||
* which these statistics apply.
|
||||
*
|
||||
* @return The refresh period in nanoseconds.
|
||||
*/
|
||||
public final long getRefreshPeriodNano() {
|
||||
return mRefreshPeriodNano;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of frames for which there is data.
|
||||
*
|
||||
* @return The number of frames.
|
||||
*/
|
||||
public final int getFrameCount() {
|
||||
return mFramesPresentedTimeNano != null
|
||||
? mFramesPresentedTimeNano.length : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start time of the interval for which these statistics
|
||||
* apply. The start interval is the time when the first frame was
|
||||
* presented.
|
||||
*
|
||||
* @return The start time in nanoseconds or {@link #UNDEFINED_TIME_NANO}
|
||||
* if there is no frame data.
|
||||
*/
|
||||
public final long getStartTimeNano() {
|
||||
if (getFrameCount() <= 0) {
|
||||
return UNDEFINED_TIME_NANO;
|
||||
}
|
||||
return mFramesPresentedTimeNano[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end time of the interval for which these statistics
|
||||
* apply. The end interval is the time when the last frame was
|
||||
* presented.
|
||||
*
|
||||
* @return The end time in nanoseconds or {@link #UNDEFINED_TIME_NANO}
|
||||
* if there is no frame data.
|
||||
*/
|
||||
public final long getEndTimeNano() {
|
||||
if (getFrameCount() <= 0) {
|
||||
return UNDEFINED_TIME_NANO;
|
||||
}
|
||||
return mFramesPresentedTimeNano[mFramesPresentedTimeNano.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time a frame at a given index was presented.
|
||||
*
|
||||
* @param index The frame index.
|
||||
* @return The presented time in nanoseconds or {@link #UNDEFINED_TIME_NANO}
|
||||
* if the frame is not presented yet.
|
||||
*/
|
||||
public final long getFramePresentedTimeNano(int index) {
|
||||
if (mFramesPresentedTimeNano == null) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return mFramesPresentedTimeNano[index];
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import android.view.MotionEvent;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InputDevice;
|
||||
import android.view.IInputFilter;
|
||||
import android.view.WindowContentFrameStats;
|
||||
|
||||
/**
|
||||
* System private interface to the window manager.
|
||||
@@ -233,4 +234,20 @@ interface IWindowManager
|
||||
* Device is in safe mode.
|
||||
*/
|
||||
boolean isSafeModeEnabled();
|
||||
|
||||
/**
|
||||
* Clears the frame statistics for a given window.
|
||||
*
|
||||
* @param token The window token.
|
||||
* @return Whether the frame statistics were cleared.
|
||||
*/
|
||||
boolean clearWindowContentFrameStats(IBinder token);
|
||||
|
||||
/**
|
||||
* Gets the content frame statistics for a given window.
|
||||
*
|
||||
* @param token The window token.
|
||||
* @return The frame statistics or null if the window does not exist.
|
||||
*/
|
||||
WindowContentFrameStats getWindowContentFrameStats(IBinder token);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import dalvik.system.CloseGuard;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.view.Surface;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.view.Surface.OutOfResourcesException;
|
||||
@@ -59,6 +58,11 @@ public class SurfaceControl {
|
||||
private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
|
||||
private static native void nativeSetLayerStack(long nativeObject, int layerStack);
|
||||
|
||||
private static native boolean nativeClearContentFrameStats(long nativeObject);
|
||||
private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
|
||||
private static native boolean nativeClearAnimationFrameStats();
|
||||
private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
|
||||
|
||||
private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
|
||||
private static native IBinder nativeCreateDisplay(String name, boolean secure);
|
||||
private static native void nativeDestroyDisplay(IBinder displayToken);
|
||||
@@ -357,6 +361,24 @@ public class SurfaceControl {
|
||||
nativeSetTransparentRegionHint(mNativeObject, region);
|
||||
}
|
||||
|
||||
public boolean clearContentFrameStats() {
|
||||
checkNotReleased();
|
||||
return nativeClearContentFrameStats(mNativeObject);
|
||||
}
|
||||
|
||||
public boolean getContentFrameStats(WindowContentFrameStats outStats) {
|
||||
checkNotReleased();
|
||||
return nativeGetContentFrameStats(mNativeObject, outStats);
|
||||
}
|
||||
|
||||
public static boolean clearAnimationFrameStats() {
|
||||
return nativeClearAnimationFrameStats();
|
||||
}
|
||||
|
||||
public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) {
|
||||
return nativeGetAnimationFrameStats(outStats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alpha value for the entire Surface. This value is combined with the
|
||||
* per-pixel alpha. It may be used with opaque Surfaces.
|
||||
@@ -542,7 +564,6 @@ public class SurfaceControl {
|
||||
return nativeGetBuiltInDisplay(builtInDisplayId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the current screen contents into the provided {@link Surface}
|
||||
*
|
||||
@@ -592,7 +613,6 @@ public class SurfaceControl {
|
||||
screenshot(display, consumer, 0, 0, 0, 0, true, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the current screen contents into a bitmap and return it.
|
||||
*
|
||||
@@ -626,8 +646,8 @@ public class SurfaceControl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link SurfaceControl#screenshot(int, int, int, int)} but includes all
|
||||
* Surfaces in the screenshot.
|
||||
* Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
|
||||
* includes all Surfaces in the screenshot.
|
||||
*
|
||||
* @param width The desired width of the returned bitmap; the raw
|
||||
* screen will be scaled down to this size.
|
||||
|
||||
19
core/java/android/view/WindowAnimationFrameStats.aidl
Normal file
19
core/java/android/view/WindowAnimationFrameStats.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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 android.view;
|
||||
|
||||
parcelable WindowAnimationFrameStats;
|
||||
94
core/java/android/view/WindowAnimationFrameStats.java
Normal file
94
core/java/android/view/WindowAnimationFrameStats.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 android.view;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* This class contains window animation frame statistics. For example, a window
|
||||
* animation is usually performed when the application is transitioning from one
|
||||
* activity to another. The frame statistics are a snapshot for the time interval
|
||||
* from {@link #getStartTimeNano()} to {@link #getEndTimeNano()}.
|
||||
* <p>
|
||||
* The key idea is that in order to provide a smooth user experience the system should
|
||||
* run window animations at a specific time interval obtained by calling {@link
|
||||
* #getRefreshPeriodNano()}. If the system does not render a frame every refresh
|
||||
* period the user will see irregular window transitions. The time when the frame was
|
||||
* actually presented on the display by calling {@link #getFramePresentedTimeNano(int)}.
|
||||
*/
|
||||
public final class WindowAnimationFrameStats extends FrameStats implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public WindowAnimationFrameStats() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this isntance.
|
||||
*
|
||||
* @param refreshPeriodNano The display refresh period.
|
||||
* @param framesPresentedTimeNano The presented frame times.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void init(long refreshPeriodNano, long[] framesPresentedTimeNano) {
|
||||
mRefreshPeriodNano = refreshPeriodNano;
|
||||
mFramesPresentedTimeNano = framesPresentedTimeNano;
|
||||
}
|
||||
|
||||
private WindowAnimationFrameStats(Parcel parcel) {
|
||||
mRefreshPeriodNano = parcel.readLong();
|
||||
mFramesPresentedTimeNano = parcel.createLongArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeLong(mRefreshPeriodNano);
|
||||
parcel.writeLongArray(mFramesPresentedTimeNano);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("WindowAnimationFrameStats[");
|
||||
builder.append("frameCount:" + getFrameCount());
|
||||
builder.append(", fromTimeNano:" + getStartTimeNano());
|
||||
builder.append(", toTimeNano:" + getEndTimeNano());
|
||||
builder.append(']');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static final Creator<WindowAnimationFrameStats> CREATOR =
|
||||
new Creator<WindowAnimationFrameStats>() {
|
||||
@Override
|
||||
public WindowAnimationFrameStats createFromParcel(Parcel parcel) {
|
||||
return new WindowAnimationFrameStats(parcel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowAnimationFrameStats[] newArray(int size) {
|
||||
return new WindowAnimationFrameStats[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
19
core/java/android/view/WindowContentFrameStats.aidl
Normal file
19
core/java/android/view/WindowContentFrameStats.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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 android.view;
|
||||
|
||||
parcelable WindowContentFrameStats;
|
||||
152
core/java/android/view/WindowContentFrameStats.java
Normal file
152
core/java/android/view/WindowContentFrameStats.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 android.view;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* This class contains window content frame statistics. For example, a window content
|
||||
* is rendred in frames when a view is scrolled. The frame statistics are a snapshot
|
||||
* for the time interval from {@link #getStartTimeNano()} to {@link #getEndTimeNano()}.
|
||||
* <p>
|
||||
* The key idea is that in order to provide a smooth user experience an application
|
||||
* has to draw a frame at a specific time interval obtained by calling {@link
|
||||
* #getRefreshPeriodNano()}. If the application does not render a frame every refresh
|
||||
* period the user will see irregular UI transitions.
|
||||
* </p>
|
||||
* <p>
|
||||
* An application posts a frame for presentation by synchronously rendering its contents
|
||||
* in a buffer which is then posted or posting a buffer to which the application is
|
||||
* asychronously rendering the content via GL. After the frame is posted and rendered
|
||||
* (potentially asynchronosly) it is presented to the user. The time a frame was posted
|
||||
* can be obtained via {@link #getFramePostedTimeNano(int)}, the time a frame content
|
||||
* was rendered and ready for dsiplay (GL case) via {@link #getFrameReadyTimeNano(int)},
|
||||
* and the time a frame was presented on the screen via {@link #getFramePresentedTimeNano(int)}.
|
||||
* </p>
|
||||
*/
|
||||
public final class WindowContentFrameStats extends FrameStats implements Parcelable {
|
||||
private long[] mFramesPostedTimeNano;
|
||||
private long[] mFramesReadyTimeNano;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public WindowContentFrameStats() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this isntance.
|
||||
*
|
||||
* @param refreshPeriodNano The display refresh period.
|
||||
* @param framesPostedTimeNano The times in milliseconds for when the frame contents were posted.
|
||||
* @param framesPresentedTimeNano The times in milliseconds for when the frame contents were presented.
|
||||
* @param framesReadyTimeNano The times in milliseconds for when the frame contents were ready to be presented.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void init(long refreshPeriodNano, long[] framesPostedTimeNano,
|
||||
long[] framesPresentedTimeNano, long[] framesReadyTimeNano) {
|
||||
mRefreshPeriodNano = refreshPeriodNano;
|
||||
mFramesPostedTimeNano = framesPostedTimeNano;
|
||||
mFramesPresentedTimeNano = framesPresentedTimeNano;
|
||||
mFramesReadyTimeNano = framesReadyTimeNano;
|
||||
}
|
||||
|
||||
private WindowContentFrameStats(Parcel parcel) {
|
||||
mRefreshPeriodNano = parcel.readLong();
|
||||
mFramesPostedTimeNano = parcel.createLongArray();
|
||||
mFramesPresentedTimeNano = parcel.createLongArray();
|
||||
mFramesReadyTimeNano = parcel.createLongArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time a frame at a given index was posted by the producer (e.g. the application).
|
||||
* It is either explicitly set or defaulted to the time when the render buffer was posted.
|
||||
* <p>
|
||||
* <strong>Note:</strong> A frame can be posted and still it contents being rendered
|
||||
* asynchronously in GL. To get the time the frame content was completely rendered and
|
||||
* ready to display call {@link #getFrameReadyTimeNano(int)}.
|
||||
* </p>
|
||||
*
|
||||
* @param index The frame index.
|
||||
* @return The posted time in nanoseconds.
|
||||
*/
|
||||
public long getFramePostedTimeNano(int index) {
|
||||
if (mFramesPostedTimeNano == null) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return mFramesPostedTimeNano[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time a frame at a given index was ready for presentation.
|
||||
* <p>
|
||||
* <strong>Note:</strong> A frame can be posted and still it contents being rendered
|
||||
* asynchronously in GL. In such a case this is the time when the frame contents were
|
||||
* completely rendered.
|
||||
* </p>
|
||||
*
|
||||
* @param index The frame index.
|
||||
* @return The ready time in nanoseconds or {@link #UNDEFINED_TIME_NANO}
|
||||
* if the frame is not ready yet.
|
||||
*/
|
||||
public long getFrameReadyTimeNano(int index) {
|
||||
if (mFramesReadyTimeNano == null) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return mFramesReadyTimeNano[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeLong(mRefreshPeriodNano);
|
||||
parcel.writeLongArray(mFramesPostedTimeNano);
|
||||
parcel.writeLongArray(mFramesPresentedTimeNano);
|
||||
parcel.writeLongArray(mFramesReadyTimeNano);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("WindowContentFrameStats[");
|
||||
builder.append("frameCount:" + getFrameCount());
|
||||
builder.append(", fromTimeNano:" + getStartTimeNano());
|
||||
builder.append(", toTimeNano:" + getEndTimeNano());
|
||||
builder.append(']');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<WindowContentFrameStats> CREATOR =
|
||||
new Creator<WindowContentFrameStats>() {
|
||||
@Override
|
||||
public WindowContentFrameStats createFromParcel(Parcel parcel) {
|
||||
return new WindowContentFrameStats(parcel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowContentFrameStats[] newArray(int size) {
|
||||
return new WindowContentFrameStats[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -57,4 +57,6 @@ interface IAccessibilityManager {
|
||||
|
||||
void temporaryEnableAccessibilityStateUntilKeyguardRemoved(in ComponentName service,
|
||||
boolean touchExplorationEnabled);
|
||||
|
||||
IBinder getWindowToken(int windowId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user