CameraPerformanceTracker.java revision 7cbeceed6d03d0550797c435f3db6205714cd49f
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19/**
20 * This class tracks the timing of important state changes in camera app (e.g latency
21 * of cold/warm start of the activity, mode switch duration, etc). We can then query
22 * these values from the instrument tests, which will be helpful for tracking camera
23 * app performance and regression tests.
24 */
25public class CameraPerformanceTracker {
26
27    // Event types to track.
28    public static final int ACTIVITY_START = 0;
29    public static final int ACTIVITY_PAUSE = 1;
30    public static final int ACTIVITY_RESUME = 2;
31    public static final int MODE_SWITCH_START = 3;
32    public static final int FIRST_PREVIEW_FRAME = 5;
33    public static final int UNSET = -1;
34
35    private static final String TAG = "CameraPerformanceTracker";
36    private static final boolean DEBUG = false;
37    private static CameraPerformanceTracker sInstance;
38
39    // Internal tracking time.
40    private long mAppStartTime = UNSET;
41    private long mAppResumeTime = UNSET;
42    private long mModeSwitchStartTime = UNSET;
43
44    // Duration and/or latency or later querying.
45    private long mFirstPreviewFrameLatencyColdStart = UNSET;
46    private long mFirstPreviewFrameLatencyWarmStart = UNSET;
47    // TODO: Need to how to best track the duration for each switch from/to pair.
48    private long mModeSwitchDuration = UNSET;
49
50    private CameraPerformanceTracker() {
51        // Private constructor to ensure that it can only be created from within
52        // the class.
53    }
54
55    /**
56     * This gets called when an important state change happens. Based on the type
57     * of the event/state change, either we will record the time of the event, or
58     * calculate the duration/latency.
59     *
60     * @param eventType type of a event to track
61     */
62    public static void onEvent(int eventType) {
63        if (sInstance == null) {
64            sInstance = new CameraPerformanceTracker();
65        }
66        long currentTime = System.currentTimeMillis();
67        switch (eventType) {
68            case ACTIVITY_START:
69                sInstance.mAppStartTime = currentTime;
70                break;
71            case ACTIVITY_PAUSE:
72                sInstance.mFirstPreviewFrameLatencyWarmStart = UNSET;
73                break;
74            case ACTIVITY_RESUME:
75                sInstance.mAppResumeTime = currentTime;
76                break;
77            case FIRST_PREVIEW_FRAME:
78                if (sInstance.mFirstPreviewFrameLatencyColdStart == UNSET) {
79                    // Cold start.
80                    sInstance.mFirstPreviewFrameLatencyColdStart =
81                            currentTime - sInstance.mAppStartTime;
82                } else {
83                    // Warm Start.
84                    sInstance.mFirstPreviewFrameLatencyWarmStart =
85                            currentTime - sInstance.mAppResumeTime;
86                }
87                // If the new frame is triggered by the mode switch, track the duration.
88                if (sInstance.mModeSwitchStartTime != UNSET) {
89                    sInstance.mModeSwitchDuration = currentTime - sInstance.mModeSwitchStartTime;
90                    sInstance.mModeSwitchStartTime = UNSET;
91                }
92                break;
93            case MODE_SWITCH_START:
94                sInstance.mModeSwitchStartTime = currentTime;
95                break;
96            default:
97                break;
98        }
99        if (DEBUG) {
100            Log.d(TAG, "Mode switch duration: " + sInstance.mModeSwitchDuration);
101            Log.d(TAG, "Cold start latency: " + sInstance.mFirstPreviewFrameLatencyColdStart);
102            Log.d(TAG, "Warm start latency: " + sInstance.mFirstPreviewFrameLatencyWarmStart);
103        }
104    }
105
106    //TODO: Hook up these getters in the instrument tests.
107    /**
108     * Gets the latency of a cold start of the app, measured from the time onCreate
109     * gets called to the time first preview frame gets received.
110     *
111     * @return latency of a cold start. If no instances have been created, return
112     *         UNSET.
113     */
114    public static long getColdStartLatency() {
115        if (sInstance == null) {
116            return UNSET;
117        }
118        return sInstance.mFirstPreviewFrameLatencyColdStart;
119    }
120
121    /**
122     * Gets the latency of a warm start of the app, measured from the time onResume
123     * gets called to the time next preview frame gets received.
124     *
125     * @return latency of a warm start. If no instances have been created,
126     *         return UNSET.
127     */
128    public static long getWarmStartLatency() {
129        if (sInstance == null) {
130            return UNSET;
131        }
132        return sInstance.mFirstPreviewFrameLatencyWarmStart;
133    }
134
135    /**
136     * Gets the duration of the mode switch, measured from the start of a mode switch
137     * to the time next preview frame gets received.
138     *
139     * @return duration of the mode switch. If no instances have been created,
140     *         return UNSET.
141     */
142    public static long getModeSwitchDuration() {
143        if (sInstance == null) {
144            return UNSET;
145        }
146        return sInstance.mModeSwitchDuration;
147    }
148}
149