1 /*
2  * Copyright (C) 2015 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 com.android.camera.stats.profiler;
18 
19 import com.android.camera.async.MainThread;
20 
21 /**
22  * Basic profiler that will compute start, end and "time since last event"
23  * values and pass them along to the subclass. This also provides
24  * standard formatting methods for messages to keep them consistent.
25  */
26 public abstract class ProfileBase implements Profile {
27     private final String mName;
28 
29     private long mStartNanos;
30     private long mLastMark;
31 
32     /** Create a new profile for a given name. */
ProfileBase(String name)33     public ProfileBase(String name) {
34         mName = name;
35     }
36 
37     @Override
start()38     public final Profile start() {
39         mStartNanos = System.nanoTime();
40         mLastMark = mStartNanos;
41         onStart();
42 
43         return this;
44     }
45 
46     @Override
mark()47     public final void mark() {
48         mLastMark = System.nanoTime();
49         // In most cases this will only be used to reset the lastMark time.
50     }
51 
52     @Override
mark(String reason)53     public final void mark(String reason) {
54         long time = System.nanoTime();
55         onMark(getTotalMillis(time), getTimeFromLastMillis(time), reason);
56         mLastMark = time;
57     }
58 
59     @Override
stop()60     public final void stop() {
61         long time = System.nanoTime();
62         onStop(getTotalMillis(time), getTimeFromLastMillis(time));
63         mLastMark = time;
64     }
65 
66     @Override
stop(String reason)67     public final void stop(String reason) {
68         long time = System.nanoTime();
69         onStop(getTotalMillis(time), getTimeFromLastMillis(time), reason);
70         mLastMark = time;
71     }
72 
73     /**
74      * Format a simple message with the total elapsed time and a simple event.
75      */
format(double totalMillis, String event)76     protected final String format(double totalMillis, String event) {
77         return String.format("[%7sms]%s %-6s %s",
78               String.format("%.3f", totalMillis),
79               MainThread.isMainThread() ? "[ui]" : "",
80               event + ":",
81               mName);
82     }
83 
84     /**
85      * Format a simple message with the total elapsed time, a simple event,
86      * and a string reason at the end.
87      */
format(double totalMillis, String event, String reason)88     protected final String format(double totalMillis, String event, String reason) {
89         return String.format("[%7sms]%s %-6s %s - %s",
90               String.format("%.3f", totalMillis),
91               MainThread.isMainThread() ? "[ui]" : "",
92               event + ":",
93               mName,
94               reason);
95     }
96 
97     /**
98      * Format a simple message with the total elapsed time, a simple event,
99      * a time since last event, and a string reason.
100      */
format(double totalMillis, String event, double lastMillis, String reason)101     protected final String format(double totalMillis, String event, double lastMillis, String reason) {
102         return String.format("[%7sms]%s %-6s %s - [%6sms] %s",
103               String.format("%.3f", totalMillis),
104               MainThread.isMainThread() ? "[ui]" : "",
105               event + ":",
106               mName,
107               String.format("%.3f", lastMillis),
108               reason);
109     }
110 
111     /**
112      * Called when start() is called.
113      */
onStart()114     protected void onStart() { }
115 
116     /**
117      * Called when mark() is called with computed total and time
118      * since last event values in milliseconds.
119      */
onMark(double totalMillis, double lastMillis, String reason)120     protected void onMark(double totalMillis, double lastMillis, String reason) { }
121 
122     /**
123      * Called when stop() is called with computed total and time
124      * since last event values in milliseconds.
125      */
onStop(double totalMillis, double lastMillis)126     protected void onStop(double totalMillis, double lastMillis) { }
127 
128     /**
129      * Called when stop() is called with computed total and time
130      * since last event values in milliseconds. Inclues the stop reason.
131      */
onStop(double totalMillis, double lastMillis, String reason)132     protected void onStop(double totalMillis, double lastMillis, String reason) { }
133 
getTotalMillis(long timeNanos)134     private double getTotalMillis(long timeNanos) {
135         return nanoToMillis(timeNanos - mStartNanos);
136     }
137 
getTimeFromLastMillis(long timeNanos)138     private double getTimeFromLastMillis(long timeNanos) {
139         return nanoToMillis(timeNanos - mLastMark);
140     }
141 
nanoToMillis(long timeNanos)142     private double nanoToMillis(long timeNanos) {
143         return (double)(timeNanos) / 1000000.0;
144     }
145 }
146