Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-24523] Android: Implement support for Frame metrics API #9445

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions android/titanium/src/java/org/appcelerator/titanium/TiC.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ public class TiC
*/
public static final String EVENT_FOCUSED = "focused";

/**
* @module.api
*/
public static final String EVENT_FRAME_METRICS = "framemetrics";

/**
* @module.api
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.appcelerator.titanium.proxy;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.view.FrameMetrics;

import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;

import ti.modules.titanium.TitaniumModule;

@Kroll.proxy(parentModule = TitaniumModule.class)
public class FrameMetricsProxy extends KrollProxy {

@Kroll.constant public final static int ANIMATION_DURATION = FrameMetrics.ANIMATION_DURATION;
@Kroll.constant public final static int COMMAND_ISSUE_DURATION = FrameMetrics.COMMAND_ISSUE_DURATION;
@Kroll.constant public final static int DRAW_DURATION = FrameMetrics.DRAW_DURATION;
@Kroll.constant public final static int FIRST_DRAW_FRAME = FrameMetrics.FIRST_DRAW_FRAME;
@Kroll.constant public final static int INPUT_HANDLING_DURATION = FrameMetrics.INPUT_HANDLING_DURATION;
@Kroll.constant public final static int INTENDED_VSYNC_TIMESTAMP = FrameMetrics.INTENDED_VSYNC_TIMESTAMP;
@Kroll.constant public final static int LAYOUT_MEASURE_DURATION = FrameMetrics.LAYOUT_MEASURE_DURATION;
@Kroll.constant public final static int SWAP_BUFFERS_DURATION = FrameMetrics.SWAP_BUFFERS_DURATION;
@Kroll.constant public final static int SYNC_DURATION = FrameMetrics.SYNC_DURATION;
@Kroll.constant public final static int TOTAL_DURATION = FrameMetrics.TOTAL_DURATION;
@Kroll.constant public final static int UNKNOWN_DELAY_DURATION = FrameMetrics.UNKNOWN_DELAY_DURATION;
@Kroll.constant public final static int VSYNC_TIMESTAMP = FrameMetrics.VSYNC_TIMESTAMP;

private FrameMetrics frameMetrics;

public FrameMetricsProxy(FrameMetrics source) {
frameMetrics = source;
}

@RequiresApi(api = Build.VERSION_CODES.N)
@Kroll.method
public long getMetric(int id) {
return frameMetrics.getMetric(id);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.Display;
import android.view.FrameMetrics;
import android.view.View;
import android.view.Window;

@Kroll.proxy(propertyAccessors={
TiC.PROPERTY_EXIT_ON_CLOSE,
Expand Down Expand Up @@ -71,6 +74,15 @@ public abstract class TiWindowProxy extends TiViewProxy
protected boolean windowActivityCreated = false;
protected List< Pair<View, String> > sharedElementPairs;

private Window.OnFrameMetricsAvailableListener frameMetricsAvailableListener = new Window.OnFrameMetricsAvailableListener() {
@Override
public void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics, int i) {
KrollDict frameMetricsDic = new KrollDict();
frameMetricsDic.put("framemetrics", new FrameMetricsProxy(frameMetrics));
fireEvent(TiC.EVENT_FRAME_METRICS, frameMetricsDic);
}
};

public static interface PostOpenListener
{
public void onPostOpen(TiWindowProxy window);
Expand Down Expand Up @@ -179,6 +191,10 @@ public void close(@Kroll.argument(optional = true) Object arg)
return;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getWindowActivity().getWindow().removeOnFrameMetricsAvailableListener(frameMetricsAvailableListener);
}

TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_CLOSE), options);
}

Expand Down Expand Up @@ -470,6 +486,9 @@ public void run() {
if (nativeView != null) {
nativeView.postInvalidate();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getActivityProxy().getActivity().getWindow().addOnFrameMetricsAvailableListener(frameMetricsAvailableListener, new Handler());
}
}

@Kroll.method @Kroll.getProperty
Expand Down
121 changes: 121 additions & 0 deletions apidoc/Titanium/FrameMetrics.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
name: Titanium.FrameMetrics
summary: Proxy containing performance information about rendered frames.
description: |
On Android N and above FrameMetrics provides access to performance information
in a rendered frame lifecycle.

Various milestones can be accessed through the proxy's constants.

More information at:
[FrameMetrics API for Android N](https://developer.android.com/about/versions/nougat/android-7.0.html#framemetrics_api)
since: "7.0.0"
platforms: [android]

properties:
- name: ANIMATION_DURATION
summary: Identifier for animation callback duration.
description: |
Represents the number of nanoseconds elapsed issuing animation callbacks.
type: Number
permission: read-only

- name: COMMAND_ISSUE_DURATION
summary: Identifier for command issue duration.
description: |
Represents the number of nanoseconds elapsed issuing draw commands to the GPU.
type: Number
permission: read-only

- name: DRAW_DURATION
summary: Identifier for draw duration.
description: |
Represents the number of nanoseconds elapsed computing DisplayLists for
transformations applied to the view hierarchy.
type: Number
permission: read-only

- name: FIRST_DRAW_FRAME
summary: Boolean value determining whether this frame was the first to draw in a new Window layout.
description: |
[getMetric](Titanium.FrameMetrics.getMetric) will return 0 for false, 1 for true.

First draw frames are expected to be slow and should usually be exempt from display jank
calculations as they do not cause skips in animations and are usually hidden by window
animations or other tricks.
type: Number
permission: read-only

- name: INPUT_HANDLING_DURATION
summary: Identifier for input handling duration.
description: |
Represents the number of nanoseconds elapsed issuing input handling callbacks.
type: Number
permission: read-only

- name: INTENDED_VSYNC_TIMESTAMP
summary: Identifier for the timestamp of the intended vsync for this frame.
description: |
The intended start point for the frame. If this value is different from VSYNC_TIMESTAMP,
there was work occurring on the UI thread that prevented it from responding to the vsync
signal on time.
type: Number
permission: read-only

- name: LAYOUT_MEASURE_DURATION
summary: Identifier for layout/measure duration.
description: |
Represents the number of nanoseconds elapsed measuring and laying out the invalidated
pieces of the view hierarchy.
type: Number
permission: read-only

- name: SWAP_BUFFERS_DURATION
summary: Identifier for swap buffers duration.
description: |
Represents the number of nanoseconds elapsed issuing the frame buffer for this frame to
the display subsystem.
type: Number
permission: read-only

- name: SYNC_DURATION
summary: Identifier for sync duration.
description: |
Represents the number of nanoseconds elapsed synchronizing the computed display lists
with the render thread.
type: Number
permission: read-only

- name: TOTAL_DURATION
summary: Identifier for total frame duration.
description: |
Represents the total time in nanoseconds this frame took to render and be issued to the
display subsystem. Equal to the sum of the values of all other time-valued metric identifiers.
type: Number
permission: read-only

- name: UNKNOWN_DELAY_DURATION
summary: Identifier for unknown delay.
description: |
Represents the number of nanoseconds elapsed waiting for the UI thread to become responsive and
process the frame. This should be 0 most of the time.
type: Number
permission: read-only

- name: VSYNC_TIMESTAMP
summary: Identifier for the timestamp of the actual vsync for this frame.
description: |
The time value that was used in all the vsync listeners and drawing for the frame.
type: Number
permission: read-only

methods:
- name: getMetric
summary: Returns the value for the passed identifier.
parameters:
- name: identifier
summary: Identifier to get a metric for.
type: Number
constants: Titanium.FrameMetrics.*
returns:
type: Number
13 changes: 13 additions & 0 deletions apidoc/Titanium/UI/TabGroup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ events:
the previous tab.
type: Titanium.UI.Tab

- name: framemetrics
summary: Fired when the subsytem renders a frame.
description: |
For every rendered frame returns a [FrameMetrics](Titanium.FrameMetrics) containing
information for it's lifecycle.
properties:
- name: framemetrics
summary: |
FrameMetrics for the frame.
type: Titanium.FrameMetrics
since: "7.0.0"
platforms: [android]

methods:
- name: addTab
summary: Adds a tab to the tab group.
Expand Down
13 changes: 13 additions & 0 deletions apidoc/Titanium/UI/Window.yml
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,19 @@ events:
The listener for this event must be defined before this window
is opened.

- name: framemetrics
summary: Fired when the subsytem renders a frame.
description: |
For every rendered frame returns a [FrameMetrics](Titanium.FrameMetrics) containing
information for it's lifecycle.
properties:
- name: framemetrics
summary: |
FrameMetrics for the frame.
type: Titanium.FrameMetrics
since: "7.0.0"
platforms: [android]

properties:
- name: activity
summary: |
Expand Down