1ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang/*
2ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * Copyright (C) 2009 The Android Open Source Project
3ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang *
4ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * Licensed under the Apache License, Version 2.0 (the "License");
5ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * you may not use this file except in compliance with the License.
6ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * You may obtain a copy of the License at
7ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang *
8ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang *      http://www.apache.org/licenses/LICENSE-2.0
9ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang *
10ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * Unless required by applicable law or agreed to in writing, software
11ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * distributed under the License is distributed on an "AS IS" BASIS,
12ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * See the License for the specific language governing permissions and
14ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * limitations under the License.
15ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang */
16ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
17ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wangpackage android.os;
18ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
19ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
20ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wangimport java.util.ArrayList;
21ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
22ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang/**
23ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * Collects performance data between two function calls in Bundle objects and
24ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * outputs the results using writer of type {@link PerformanceResultsWriter}.
25ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <p>
26ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * {@link #beginSnapshot(String)} and {@link #endSnapshot()} functions collect
27ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * memory usage information and measure runtime between calls to begin and end.
28ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * These functions logically wrap around an entire test, and should be called
29ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * with name of test as the label, e.g. EmailPerformanceTest.
30ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <p>
31ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * {@link #startTiming(String)} and {@link #stopTiming(String)} functions
32ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * measure runtime between calls to start and stop. These functions logically
33ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * wrap around a single test case or a small block of code, and should be called
34ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * with the name of test case as the label, e.g. testSimpleSendMailSequence.
35ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <p>
36ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * {@link #addIteration(String)} inserts intermediate measurement point which
37ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * can be labeled with a String, e.g. Launch email app, compose, send, etc.
38ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <p>
39ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * Snapshot and timing functions do not interfere with each other, and thus can
40ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * be called in any order. The intended structure is to wrap begin/endSnapshot
41ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * around calls to start/stopTiming, for example:
42ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <p>
43ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <code>beginSnapshot("EmailPerformanceTest");
44ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * startTiming("testSimpleSendSequence");
45ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * addIteration("Launch email app");
46ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * addIteration("Compose");
47ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * stopTiming("Send");
48ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * startTiming("testComplexSendSequence");
49ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * stopTiming("");
50ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * startTiming("testAddLabel");
51ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * stopTiming("");
52ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * endSnapshot();</code>
53ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * <p>
54ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * Structure of results output is up to implementor of
55ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * {@link PerformanceResultsWriter }.
56ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang *
57ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang * {@hide} Pending approval for public API.
58ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang */
59ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wangpublic class PerformanceCollector {
60ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
61ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
62ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Interface for reporting performance data.
63ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
64ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public interface PerformanceResultsWriter {
65ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
66ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        /**
67ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * Callback invoked as first action in
68ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * PerformanceCollector#beginSnapshot(String) for reporting the start of
69ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * a performance snapshot.
70ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *
71ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @param label description of code block between beginSnapshot and
72ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *              PerformanceCollector#endSnapshot()
73ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @see PerformanceCollector#beginSnapshot(String)
74ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         */
75ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        public void writeBeginSnapshot(String label);
76ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
77ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        /**
78ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * Callback invoked as last action in PerformanceCollector#endSnapshot()
79ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * for reporting performance data collected in the snapshot.
80ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *
81ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @param results memory and runtime metrics stored as key/value pairs,
82ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *        in the same structure as returned by
83ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *        PerformanceCollector#endSnapshot()
84ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @see PerformanceCollector#endSnapshot()
85ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         */
86ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        public void writeEndSnapshot(Bundle results);
87ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
88ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        /**
89ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * Callback invoked as first action in
90ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * PerformanceCollector#startTiming(String) for reporting the start of
91ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * a timing measurement.
92ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *
93ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @param label description of code block between startTiming and
94ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *              PerformanceCollector#stopTiming(String)
95ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @see PerformanceCollector#startTiming(String)
96ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         */
97ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        public void writeStartTiming(String label);
98ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
99ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        /**
100ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * Callback invoked as last action in
101ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * {@link PerformanceCollector#stopTiming(String)} for reporting the
102ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * sequence of timings measured.
103ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *
104ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @param results runtime metrics of code block between calls to
105ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *                startTiming and stopTiming, in the same structure as
106ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         *                returned by PerformanceCollector#stopTiming(String)
107ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         * @see PerformanceCollector#stopTiming(String)
108ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang         */
109ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        public void writeStopTiming(Bundle results);
110075997f12e2fb2b646172a92926be0f26f739099Jack Wang
111075997f12e2fb2b646172a92926be0f26f739099Jack Wang        /**
112075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * Callback invoked as last action in
113075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * {@link PerformanceCollector#addMeasurement(String, long)} for
114075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * reporting an integer type measurement.
115075997f12e2fb2b646172a92926be0f26f739099Jack Wang         *
116075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * @param label short description of the metric that was measured
117075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * @param value long value of the measurement
118075997f12e2fb2b646172a92926be0f26f739099Jack Wang         */
119075997f12e2fb2b646172a92926be0f26f739099Jack Wang        public void writeMeasurement(String label, long value);
120075997f12e2fb2b646172a92926be0f26f739099Jack Wang
121075997f12e2fb2b646172a92926be0f26f739099Jack Wang        /**
122075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * Callback invoked as last action in
123075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * {@link PerformanceCollector#addMeasurement(String, float)} for
124075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * reporting a float type measurement.
125075997f12e2fb2b646172a92926be0f26f739099Jack Wang         *
126075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * @param label short description of the metric that was measured
127075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * @param value float value of the measurement
128075997f12e2fb2b646172a92926be0f26f739099Jack Wang         */
129075997f12e2fb2b646172a92926be0f26f739099Jack Wang        public void writeMeasurement(String label, float value);
130075997f12e2fb2b646172a92926be0f26f739099Jack Wang
131075997f12e2fb2b646172a92926be0f26f739099Jack Wang        /**
132075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * Callback invoked as last action in
133075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * {@link PerformanceCollector#addMeasurement(String, String)} for
134075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * reporting a string field.
135075997f12e2fb2b646172a92926be0f26f739099Jack Wang         *
136075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * @param label short description of the metric that was measured
137075997f12e2fb2b646172a92926be0f26f739099Jack Wang         * @param value string summary of the measurement
138075997f12e2fb2b646172a92926be0f26f739099Jack Wang         */
139075997f12e2fb2b646172a92926be0f26f739099Jack Wang        public void writeMeasurement(String label, String value);
140ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
141ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
142ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
143ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a results Bundle, this key references a List of iteration Bundles.
144ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
145ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_ITERATIONS = "iterations";
146ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
147ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In an iteration Bundle, this key describes the iteration.
148ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
149ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_LABEL = "label";
150ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
151ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a results Bundle, this key reports the cpu time of the code block
152ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * under measurement.
153ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
154ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_CPU_TIME = "cpu_time";
155ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
156ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a results Bundle, this key reports the execution time of the code
157ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * block under measurement.
158ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
159ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_EXECUTION_TIME = "execution_time";
160ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
161ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of received
162ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * transactions from the binder driver before collection started.
163ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
164ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_PRE_RECEIVED_TRANSACTIONS = "pre_received_transactions";
165ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
166ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of transactions sent by
167ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * the running program before collection started.
168ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
169ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_PRE_SENT_TRANSACTIONS = "pre_sent_transactions";
170ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
171ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of received
172ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * transactions from the binder driver.
173ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
174ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_RECEIVED_TRANSACTIONS = "received_transactions";
175ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
176ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of transactions sent by
177ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * the running program.
178ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
179ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_SENT_TRANSACTIONS = "sent_transactions";
180ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
181ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of garbage collection
182ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * invocations.
183ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
184ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_GC_INVOCATION_COUNT = "gc_invocation_count";
185ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
186ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the amount of allocated memory
187ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by the running program.
188ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
189ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_JAVA_ALLOCATED = "java_allocated";
190ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
191ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the amount of free memory
192ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * available to the running program.
193ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
194ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_JAVA_FREE = "java_free";
195ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
196ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of private dirty pages
197ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by dalvik.
198ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
199ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_JAVA_PRIVATE_DIRTY = "java_private_dirty";
200ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
201ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the proportional set size for
202ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * dalvik.
203ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
204ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_JAVA_PSS = "java_pss";
205ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
206ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of shared dirty pages
207ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by dalvik.
208ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
209ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_JAVA_SHARED_DIRTY = "java_shared_dirty";
210ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
211ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the total amount of memory
212ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * available to the running program.
213ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
214ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_JAVA_SIZE = "java_size";
215ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
216ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the amount of allocated memory in
217ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * the native heap.
218ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
219ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_NATIVE_ALLOCATED = "native_allocated";
220ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
221ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the amount of free memory in the
222ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * native heap.
223ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
224ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_NATIVE_FREE = "native_free";
225ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
226ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of private dirty pages
227ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by the native heap.
228ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
229ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_NATIVE_PRIVATE_DIRTY = "native_private_dirty";
230ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
231ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the proportional set size for the
232ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * native heap.
233ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
234ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_NATIVE_PSS = "native_pss";
235ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
236ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of shared dirty pages
237ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by the native heap.
238ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
239ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_NATIVE_SHARED_DIRTY = "native_shared_dirty";
240ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
241ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the size of the native heap.
242ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
243ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_NATIVE_SIZE = "native_size";
244ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
245ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of objects allocated
246ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * globally.
247ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
248ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_GLOBAL_ALLOC_COUNT = "global_alloc_count";
249ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
250ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the size of all objects allocated
251ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * globally.
252ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
253ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_GLOBAL_ALLOC_SIZE = "global_alloc_size";
254ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
255ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of objects freed
256ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * globally.
257ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
258ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_GLOBAL_FREED_COUNT = "global_freed_count";
259ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
260ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the size of all objects freed
261ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * globally.
262ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
263ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_GLOBAL_FREED_SIZE = "global_freed_size";
264ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
265ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of private dirty pages
266ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by everything else.
267ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
268ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_OTHER_PRIVATE_DIRTY = "other_private_dirty";
269ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
270ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the proportional set size for
271ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * everything else.
272ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
273ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_OTHER_PSS = "other_pss";
274ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
275ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * In a snapshot Bundle, this key reports the number of shared dirty pages
276ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * used by everything else.
277ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
278ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public static final String METRIC_KEY_OTHER_SHARED_DIRTY = "other_shared_dirty";
279ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
280ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private PerformanceResultsWriter mPerfWriter;
281ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private Bundle mPerfSnapshot;
282ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private Bundle mPerfMeasurement;
283ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private long mSnapshotCpuTime;
284ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private long mSnapshotExecTime;
285ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private long mCpuTime;
286ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private long mExecTime;
287ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
288ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public PerformanceCollector() {
289ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
290ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
291ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public PerformanceCollector(PerformanceResultsWriter writer) {
292ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        setPerformanceResultsWriter(writer);
293ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
294ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
295ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public void setPerformanceResultsWriter(PerformanceResultsWriter writer) {
296ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfWriter = writer;
297ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
298ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
299ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
300ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Begin collection of memory usage information.
301ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *
302ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @param label description of code block between beginSnapshot and
303ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *              endSnapshot, used to label output
304ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
305ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public void beginSnapshot(String label) {
306ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        if (mPerfWriter != null)
307ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfWriter.writeBeginSnapshot(label);
308ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        startPerformanceSnapshot();
309ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
310ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
311ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
312ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * End collection of memory usage information. Returns collected data in a
313ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Bundle object.
314ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *
315ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @return Memory and runtime metrics stored as key/value pairs. Values are
316ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         of type long, and keys include:
317ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <ul>
318ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_CPU_TIME cpu_time}
319ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time}
320ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_PRE_RECEIVED_TRANSACTIONS
321ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         pre_received_transactions}
322ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_PRE_SENT_TRANSACTIONS
323ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         pre_sent_transactions}
324ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_RECEIVED_TRANSACTIONS
325ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         received_transactions}
326ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_SENT_TRANSACTIONS sent_transactions}
327ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_GC_INVOCATION_COUNT gc_invocation_count}
328ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_JAVA_ALLOCATED java_allocated}
329ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_JAVA_FREE java_free}
330ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_JAVA_PRIVATE_DIRTY java_private_dirty}
331ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_JAVA_PSS java_pss}
332ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_JAVA_SHARED_DIRTY java_shared_dirty}
333ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_JAVA_SIZE java_size}
334ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_NATIVE_ALLOCATED native_allocated}
335ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_NATIVE_FREE native_free}
336ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_NATIVE_PRIVATE_DIRTY native_private_dirty}
337ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_NATIVE_PSS native_pss}
338ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_NATIVE_SHARED_DIRTY native_shared_dirty}
339ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_NATIVE_SIZE native_size}
340ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_GLOBAL_ALLOC_COUNT global_alloc_count}
341ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_GLOBAL_ALLOC_SIZE global_alloc_size}
342ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_GLOBAL_FREED_COUNT global_freed_count}
343ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_GLOBAL_FREED_SIZE global_freed_size}
344ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_OTHER_PRIVATE_DIRTY other_private_dirty}
345ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_OTHER_PSS other_pss}
346ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_OTHER_SHARED_DIRTY other_shared_dirty}
347ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         </ul>
348ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
349ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public Bundle endSnapshot() {
350ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        endPerformanceSnapshot();
351ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        if (mPerfWriter != null)
352ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfWriter.writeEndSnapshot(mPerfSnapshot);
353ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        return mPerfSnapshot;
354ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
355ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
356ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
357ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Start measurement of user and cpu time.
358ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *
359ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @param label description of code block between startTiming and
360ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *        stopTiming, used to label output
361ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
362ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public void startTiming(String label) {
363ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        if (mPerfWriter != null)
364ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfWriter.writeStartTiming(label);
365ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfMeasurement = new Bundle();
366ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfMeasurement.putParcelableArrayList(
367ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang                METRIC_KEY_ITERATIONS, new ArrayList<Parcelable>());
368ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mExecTime = SystemClock.uptimeMillis();
369ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mCpuTime = Process.getElapsedCpuTime();
370ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
371ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
372ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
373ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Add a measured segment, and start measuring the next segment. Returns
374ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * collected data in a Bundle object.
375ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *
376ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @param label description of code block between startTiming and
377ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *              addIteration, and between two calls to addIteration, used
378ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *              to label output
379ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @return Runtime metrics stored as key/value pairs. Values are of type
380ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         long, and keys include:
381ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <ul>
382ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_LABEL label}
383ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_CPU_TIME cpu_time}
384ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time}
385ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         </ul>
386ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
387ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public Bundle addIteration(String label) {
388ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mCpuTime = Process.getElapsedCpuTime() - mCpuTime;
389ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mExecTime = SystemClock.uptimeMillis() - mExecTime;
390ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
391ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Bundle iteration = new Bundle();
392ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        iteration.putString(METRIC_KEY_LABEL, label);
393ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        iteration.putLong(METRIC_KEY_EXECUTION_TIME, mExecTime);
394ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        iteration.putLong(METRIC_KEY_CPU_TIME, mCpuTime);
395ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfMeasurement.getParcelableArrayList(METRIC_KEY_ITERATIONS).add(iteration);
396ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
397ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mExecTime = SystemClock.uptimeMillis();
398ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mCpuTime = Process.getElapsedCpuTime();
399ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        return iteration;
400ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
401ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
402ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /**
403ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Stop measurement of user and cpu time.
404ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *
405ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @param label description of code block between addIteration or
406ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *              startTiming and stopTiming, used to label output
407ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * @return Runtime metrics stored in a bundle, including all iterations
408ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         between calls to startTiming and stopTiming. List of iterations
409ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     *         is keyed by {@link #METRIC_KEY_ITERATIONS iterations}.
410ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
411ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    public Bundle stopTiming(String label) {
412ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        addIteration(label);
413ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        if (mPerfWriter != null)
414ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfWriter.writeStopTiming(mPerfMeasurement);
415ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        return mPerfMeasurement;
416ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
417ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
418075997f12e2fb2b646172a92926be0f26f739099Jack Wang    /**
419075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * Add an integer type measurement to the collector.
420075997f12e2fb2b646172a92926be0f26f739099Jack Wang     *
421075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * @param label short description of the metric that was measured
422075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * @param value long value of the measurement
423075997f12e2fb2b646172a92926be0f26f739099Jack Wang     */
424075997f12e2fb2b646172a92926be0f26f739099Jack Wang    public void addMeasurement(String label, long value) {
425075997f12e2fb2b646172a92926be0f26f739099Jack Wang        if (mPerfWriter != null)
426075997f12e2fb2b646172a92926be0f26f739099Jack Wang            mPerfWriter.writeMeasurement(label, value);
427075997f12e2fb2b646172a92926be0f26f739099Jack Wang    }
428075997f12e2fb2b646172a92926be0f26f739099Jack Wang
429075997f12e2fb2b646172a92926be0f26f739099Jack Wang    /**
430075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * Add a float type measurement to the collector.
431075997f12e2fb2b646172a92926be0f26f739099Jack Wang     *
432075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * @param label short description of the metric that was measured
433075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * @param value float value of the measurement
434075997f12e2fb2b646172a92926be0f26f739099Jack Wang     */
435075997f12e2fb2b646172a92926be0f26f739099Jack Wang    public void addMeasurement(String label, float value) {
436075997f12e2fb2b646172a92926be0f26f739099Jack Wang        if (mPerfWriter != null)
437075997f12e2fb2b646172a92926be0f26f739099Jack Wang            mPerfWriter.writeMeasurement(label, value);
438075997f12e2fb2b646172a92926be0f26f739099Jack Wang    }
439075997f12e2fb2b646172a92926be0f26f739099Jack Wang
440075997f12e2fb2b646172a92926be0f26f739099Jack Wang    /**
441075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * Add a string field to the collector.
442075997f12e2fb2b646172a92926be0f26f739099Jack Wang     *
443075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * @param label short description of the metric that was measured
444075997f12e2fb2b646172a92926be0f26f739099Jack Wang     * @param value string summary of the measurement
445075997f12e2fb2b646172a92926be0f26f739099Jack Wang     */
446075997f12e2fb2b646172a92926be0f26f739099Jack Wang    public void addMeasurement(String label, String value) {
447075997f12e2fb2b646172a92926be0f26f739099Jack Wang        if (mPerfWriter != null)
448075997f12e2fb2b646172a92926be0f26f739099Jack Wang            mPerfWriter.writeMeasurement(label, value);
449075997f12e2fb2b646172a92926be0f26f739099Jack Wang    }
450075997f12e2fb2b646172a92926be0f26f739099Jack Wang
451ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /*
452ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Starts tracking memory usage, binder transactions, and real & cpu timing.
453ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
454ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private void startPerformanceSnapshot() {
455ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Create new snapshot
456ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot = new Bundle();
457ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
458ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Add initial binder counts
459ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Bundle binderCounts = getBinderCounts();
460ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        for (String key : binderCounts.keySet()) {
461ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfSnapshot.putLong("pre_" + key, binderCounts.getLong(key));
462ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        }
463ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
464ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Force a GC and zero out the performance counters. Do this
465ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // before reading initial CPU/wall-clock times so we don't include
466ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // the cost of this setup in our final metrics.
467ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        startAllocCounting();
468ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
469ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Record CPU time up to this point, and start timing. Note: this
470ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // must happen at the end of this method, otherwise the timing will
471ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // include noise.
472ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mSnapshotExecTime = SystemClock.uptimeMillis();
473ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mSnapshotCpuTime = Process.getElapsedCpuTime();
474ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
475ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
476ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /*
477ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Stops tracking memory usage, binder transactions, and real & cpu timing.
478ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Stores collected data as type long into Bundle object for reporting.
479ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
480ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private void endPerformanceSnapshot() {
481ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Stop the timing. This must be done first before any other counting is
482ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // stopped.
483ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mSnapshotCpuTime = Process.getElapsedCpuTime() - mSnapshotCpuTime;
484ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mSnapshotExecTime = SystemClock.uptimeMillis() - mSnapshotExecTime;
485ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
486ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        stopAllocCounting();
487ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
488ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        long nativeMax = Debug.getNativeHeapSize() / 1024;
489ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
490ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
491ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
492ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
493ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Debug.getMemoryInfo(memInfo);
494ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
495ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime runtime = Runtime.getRuntime();
496ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
497ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        long dalvikMax = runtime.totalMemory() / 1024;
498ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        long dalvikFree = runtime.freeMemory() / 1024;
499ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        long dalvikAllocated = dalvikMax - dalvikFree;
500ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
501ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Add final binder counts
502ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Bundle binderCounts = getBinderCounts();
503ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        for (String key : binderCounts.keySet()) {
504ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfSnapshot.putLong(key, binderCounts.getLong(key));
505ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        }
506ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
507ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Add alloc counts
508ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Bundle allocCounts = getAllocCounts();
509ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        for (String key : allocCounts.keySet()) {
510ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang            mPerfSnapshot.putLong(key, allocCounts.getLong(key));
511ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        }
512ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
513ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_EXECUTION_TIME, mSnapshotExecTime);
514ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_CPU_TIME, mSnapshotCpuTime);
515ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
516ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax);
517ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated);
518ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree);
519ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PSS, memInfo.nativePss);
520ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PRIVATE_DIRTY, memInfo.nativePrivateDirty);
521ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SHARED_DIRTY, memInfo.nativeSharedDirty);
522ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
523ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_JAVA_SIZE, dalvikMax);
524ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_JAVA_ALLOCATED, dalvikAllocated);
525ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_JAVA_FREE, dalvikFree);
526ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_JAVA_PSS, memInfo.dalvikPss);
527ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_JAVA_PRIVATE_DIRTY, memInfo.dalvikPrivateDirty);
528ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_JAVA_SHARED_DIRTY, memInfo.dalvikSharedDirty);
529ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
530ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_OTHER_PSS, memInfo.otherPss);
531ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_OTHER_PRIVATE_DIRTY, memInfo.otherPrivateDirty);
532ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        mPerfSnapshot.putLong(METRIC_KEY_OTHER_SHARED_DIRTY, memInfo.otherSharedDirty);
533ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
534ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
535ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /*
536ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Starts allocation counting. This triggers a gc and resets the counts.
537ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
538ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private static void startAllocCounting() {
539ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // Before we start trigger a GC and reset the debug counts. Run the
540ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // finalizers and another GC before starting and stopping the alloc
541ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // counts. This will free up any objects that were just sitting around
542ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // waiting for their finalizers to be run.
543ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime.getRuntime().gc();
544ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime.getRuntime().runFinalization();
545ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime.getRuntime().gc();
546ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
547ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Debug.resetAllCounts();
548ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
549ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        // start the counts
550ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Debug.startAllocCounting();
551ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
552ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
553ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /*
554ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Stops allocation counting.
555ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
556ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private static void stopAllocCounting() {
557ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime.getRuntime().gc();
558ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime.getRuntime().runFinalization();
559ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Runtime.getRuntime().gc();
560ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Debug.stopAllocCounting();
561ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
562ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
563ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /*
564ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Returns a bundle with the current results from the allocation counting.
565ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
566ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private static Bundle getAllocCounts() {
567ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Bundle results = new Bundle();
568ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_GLOBAL_ALLOC_COUNT, Debug.getGlobalAllocCount());
569ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_GLOBAL_ALLOC_SIZE, Debug.getGlobalAllocSize());
570ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_GLOBAL_FREED_COUNT, Debug.getGlobalFreedCount());
571ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_GLOBAL_FREED_SIZE, Debug.getGlobalFreedSize());
572ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_GC_INVOCATION_COUNT, Debug.getGlobalGcInvocationCount());
573ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        return results;
574ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
575ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang
576ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    /*
577ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * Returns a bundle with the counts for various binder counts for this
578ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * process. Currently the only two that are reported are the number of send
579ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     * and the number of received transactions.
580ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang     */
581ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    private static Bundle getBinderCounts() {
582ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        Bundle results = new Bundle();
583ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_SENT_TRANSACTIONS, Debug.getBinderSentTransactions());
584ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        results.putLong(METRIC_KEY_RECEIVED_TRANSACTIONS, Debug.getBinderReceivedTransactions());
585ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang        return results;
586ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang    }
587ff1df69dd4835c177c724e1b5f1ba02d1f674047Jack Wang}
588