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