Home | History | Annotate | Download | only in util
      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 
     17 package 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  */
     25 public 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                 Log.d(TAG, "First preview frame received");
     79                 if (sInstance.mFirstPreviewFrameLatencyColdStart == UNSET) {
     80                     // Cold start.
     81                     sInstance.mFirstPreviewFrameLatencyColdStart =
     82                             currentTime - sInstance.mAppStartTime;
     83                 } else {
     84                     // Warm Start.
     85                     sInstance.mFirstPreviewFrameLatencyWarmStart =
     86                             currentTime - sInstance.mAppResumeTime;
     87                 }
     88                 // If the new frame is triggered by the mode switch, track the duration.
     89                 if (sInstance.mModeSwitchStartTime != UNSET) {
     90                     sInstance.mModeSwitchDuration = currentTime - sInstance.mModeSwitchStartTime;
     91                     sInstance.mModeSwitchStartTime = UNSET;
     92                 }
     93                 break;
     94             case MODE_SWITCH_START:
     95                 sInstance.mModeSwitchStartTime = currentTime;
     96                 break;
     97             default:
     98                 break;
     99         }
    100         if (DEBUG && eventType == FIRST_PREVIEW_FRAME) {
    101             Log.d(TAG, "Mode switch duration: " + (sInstance.mModeSwitchDuration
    102                 == UNSET ? "UNSET" : sInstance.mModeSwitchDuration));
    103             Log.d(TAG, "Cold start latency: " + (sInstance.mFirstPreviewFrameLatencyColdStart
    104                 == UNSET ? "UNSET" : sInstance.mFirstPreviewFrameLatencyColdStart));
    105             Log.d(TAG, "Warm start latency: " + (sInstance.mFirstPreviewFrameLatencyWarmStart
    106                 == UNSET ? "UNSET" : sInstance.mFirstPreviewFrameLatencyWarmStart));
    107         }
    108     }
    109 
    110     //TODO: Hook up these getters in the instrument tests.
    111     /**
    112      * Gets the latency of a cold start of the app, measured from the time onCreate
    113      * gets called to the time first preview frame gets received.
    114      *
    115      * @return latency of a cold start. If no instances have been created, return
    116      *         UNSET.
    117      */
    118     public static long getColdStartLatency() {
    119         if (sInstance == null) {
    120             return UNSET;
    121         }
    122         return sInstance.mFirstPreviewFrameLatencyColdStart;
    123     }
    124 
    125     /**
    126      * Gets the latency of a warm start of the app, measured from the time onResume
    127      * gets called to the time next preview frame gets received.
    128      *
    129      * @return latency of a warm start. If no instances have been created,
    130      *         return UNSET.
    131      */
    132     public static long getWarmStartLatency() {
    133         if (sInstance == null) {
    134             return UNSET;
    135         }
    136         return sInstance.mFirstPreviewFrameLatencyWarmStart;
    137     }
    138 
    139     /**
    140      * Gets the duration of the mode switch, measured from the start of a mode switch
    141      * to the time next preview frame gets received.
    142      *
    143      * @return duration of the mode switch. If no instances have been created,
    144      *         return UNSET.
    145      */
    146     public static long getModeSwitchDuration() {
    147         if (sInstance == null) {
    148             return UNSET;
    149         }
    150         return sInstance.mModeSwitchDuration;
    151     }
    152 }
    153