| /* |
| * 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.util; |
| |
| /** |
| * This class tracks the timing of important state changes in camera app (e.g latency |
| * of cold/warm start of the activity, mode switch duration, etc). We can then query |
| * these values from the instrument tests, which will be helpful for tracking camera |
| * app performance and regression tests. |
| */ |
| public class CameraPerformanceTracker { |
| |
| // Event types to track. |
| public static final int ACTIVITY_START = 0; |
| public static final int ACTIVITY_PAUSE = 1; |
| public static final int ACTIVITY_RESUME = 2; |
| public static final int MODE_SWITCH_START = 3; |
| public static final int FIRST_PREVIEW_FRAME = 5; |
| public static final int UNSET = -1; |
| |
| private static final String TAG = "CameraPerformanceTracker"; |
| private static final boolean DEBUG = false; |
| private static CameraPerformanceTracker sInstance; |
| |
| // Internal tracking time. |
| private long mAppStartTime = UNSET; |
| private long mAppResumeTime = UNSET; |
| private long mModeSwitchStartTime = UNSET; |
| |
| // Duration and/or latency or later querying. |
| private long mFirstPreviewFrameLatencyColdStart = UNSET; |
| private long mFirstPreviewFrameLatencyWarmStart = UNSET; |
| // TODO: Need to how to best track the duration for each switch from/to pair. |
| private long mModeSwitchDuration = UNSET; |
| |
| private CameraPerformanceTracker() { |
| // Private constructor to ensure that it can only be created from within |
| // the class. |
| } |
| |
| /** |
| * This gets called when an important state change happens. Based on the type |
| * of the event/state change, either we will record the time of the event, or |
| * calculate the duration/latency. |
| * |
| * @param eventType type of a event to track |
| */ |
| public static void onEvent(int eventType) { |
| if (sInstance == null) { |
| sInstance = new CameraPerformanceTracker(); |
| } |
| long currentTime = System.currentTimeMillis(); |
| switch (eventType) { |
| case ACTIVITY_START: |
| sInstance.mAppStartTime = currentTime; |
| break; |
| case ACTIVITY_PAUSE: |
| sInstance.mFirstPreviewFrameLatencyWarmStart = UNSET; |
| break; |
| case ACTIVITY_RESUME: |
| sInstance.mAppResumeTime = currentTime; |
| break; |
| case FIRST_PREVIEW_FRAME: |
| Log.d(TAG, "First preview frame received"); |
| if (sInstance.mFirstPreviewFrameLatencyColdStart == UNSET) { |
| // Cold start. |
| sInstance.mFirstPreviewFrameLatencyColdStart = |
| currentTime - sInstance.mAppStartTime; |
| } else { |
| // Warm Start. |
| sInstance.mFirstPreviewFrameLatencyWarmStart = |
| currentTime - sInstance.mAppResumeTime; |
| } |
| // If the new frame is triggered by the mode switch, track the duration. |
| if (sInstance.mModeSwitchStartTime != UNSET) { |
| sInstance.mModeSwitchDuration = currentTime - sInstance.mModeSwitchStartTime; |
| sInstance.mModeSwitchStartTime = UNSET; |
| } |
| break; |
| case MODE_SWITCH_START: |
| sInstance.mModeSwitchStartTime = currentTime; |
| break; |
| default: |
| break; |
| } |
| if (DEBUG && eventType == FIRST_PREVIEW_FRAME) { |
| Log.d(TAG, "Mode switch duration: " + (sInstance.mModeSwitchDuration |
| == UNSET ? "UNSET" : sInstance.mModeSwitchDuration)); |
| Log.d(TAG, "Cold start latency: " + (sInstance.mFirstPreviewFrameLatencyColdStart |
| == UNSET ? "UNSET" : sInstance.mFirstPreviewFrameLatencyColdStart)); |
| Log.d(TAG, "Warm start latency: " + (sInstance.mFirstPreviewFrameLatencyWarmStart |
| == UNSET ? "UNSET" : sInstance.mFirstPreviewFrameLatencyWarmStart)); |
| } |
| } |
| |
| //TODO: Hook up these getters in the instrument tests. |
| /** |
| * Gets the latency of a cold start of the app, measured from the time onCreate |
| * gets called to the time first preview frame gets received. |
| * |
| * @return latency of a cold start. If no instances have been created, return |
| * UNSET. |
| */ |
| public static long getColdStartLatency() { |
| if (sInstance == null) { |
| return UNSET; |
| } |
| return sInstance.mFirstPreviewFrameLatencyColdStart; |
| } |
| |
| /** |
| * Gets the latency of a warm start of the app, measured from the time onResume |
| * gets called to the time next preview frame gets received. |
| * |
| * @return latency of a warm start. If no instances have been created, |
| * return UNSET. |
| */ |
| public static long getWarmStartLatency() { |
| if (sInstance == null) { |
| return UNSET; |
| } |
| return sInstance.mFirstPreviewFrameLatencyWarmStart; |
| } |
| |
| /** |
| * Gets the duration of the mode switch, measured from the start of a mode switch |
| * to the time next preview frame gets received. |
| * |
| * @return duration of the mode switch. If no instances have been created, |
| * return UNSET. |
| */ |
| public static long getModeSwitchDuration() { |
| if (sInstance == null) { |
| return UNSET; |
| } |
| return sInstance.mModeSwitchDuration; |
| } |
| } |