1 /*
2  * Copyright (C) 2019 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 package com.android.server.utils;
17 
18 import android.annotation.NonNull;
19 import android.os.Trace;
20 import android.util.Slog;
21 import android.util.TimingsTraceLog;
22 
23 /**
24  * Helper class for reporting boot and shutdown timing metrics, also logging to {@link Slog}.
25  */
26 public final class TimingsTraceAndSlog extends TimingsTraceLog {
27 
28     /**
29     * Tag for timing measurement of main thread.
30     */
31     public static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
32 
33     /**
34      * Tag for timing measurement of non-main asynchronous operations.
35      */
36     private static final String SYSTEM_SERVER_TIMING_ASYNC_TAG = SYSTEM_SERVER_TIMING_TAG + "Async";
37 
38     /**
39      * Set this to a positive value to get a {@Slog.w} log for any trace that took longer than it.
40      */
41     private static final long BOTTLENECK_DURATION_MS = -1;
42 
43     private final String mTag;
44 
45     /**
46      * Creates a new {@link TimingsTraceAndSlog} for async operations.
47      */
48     @NonNull
newAsyncLog()49     public static TimingsTraceAndSlog newAsyncLog() {
50         return new TimingsTraceAndSlog(SYSTEM_SERVER_TIMING_ASYNC_TAG,
51                 Trace.TRACE_TAG_SYSTEM_SERVER);
52     }
53 
54     /**
55      * Default constructor using {@code system_server} tags.
56      */
TimingsTraceAndSlog()57     public TimingsTraceAndSlog() {
58         this(SYSTEM_SERVER_TIMING_TAG);
59     }
60 
61     /**
62      * Custom constructor using {@code system_server} trace tag.
63      *
64      * @param tag {@code logcat} tag
65      */
TimingsTraceAndSlog(@onNull String tag)66     public TimingsTraceAndSlog(@NonNull String tag) {
67         this(tag, Trace.TRACE_TAG_SYSTEM_SERVER);
68     }
69 
70     /**
71      * Custom constructor.
72      *
73      * @param tag {@code logcat} tag
74      * @param traceTag {@code atrace} tag
75      */
TimingsTraceAndSlog(@onNull String tag, long traceTag)76     public TimingsTraceAndSlog(@NonNull String tag, long traceTag) {
77         super(tag, traceTag);
78         mTag = tag;
79     }
80 
81     @Override
traceBegin(@onNull String name)82     public void traceBegin(@NonNull String name) {
83         Slog.i(mTag, name);
84         super.traceBegin(name);
85     }
86 
87     @Override
logDuration(String name, long timeMs)88     public void logDuration(String name, long timeMs) {
89         super.logDuration(name, timeMs);
90         if (BOTTLENECK_DURATION_MS > 0 && timeMs >= BOTTLENECK_DURATION_MS) {
91             Slog.w(mTag, "Slow duration for " + name + ": " + timeMs + "ms");
92         }
93     }
94 
95     @Override
toString()96     public String toString() {
97         return "TimingsTraceAndSlog[" + mTag + "]";
98     }
99 }
100