1 /*
2  * Copyright (C) 2017 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.launcher3.util;
17 
18 import android.os.Trace;
19 
20 import androidx.annotation.MainThread;
21 
22 import java.util.function.Supplier;
23 
24 /**
25  * A wrapper around {@link Trace} to allow better testing.
26  *
27  * To enable any tracing log, execute the following command:
28  * $ adb shell setprop log.tag.LAUNCHER_TRACE VERBOSE
29  * $ adb shell setprop log.tag.TAGNAME VERBOSE
30  */
31 public class TraceHelper {
32 
33     // Track binder class for this trace
34     public static final int FLAG_ALLOW_BINDER_TRACKING = 1 << 0;
35 
36     // Temporarily ignore blocking binder calls for this trace.
37     public static final int FLAG_IGNORE_BINDERS = 1 << 1;
38 
39     public static final int FLAG_CHECK_FOR_RACE_CONDITIONS = 1 << 2;
40 
41     public static final int FLAG_UI_EVENT =
42             FLAG_ALLOW_BINDER_TRACKING | FLAG_CHECK_FOR_RACE_CONDITIONS;
43 
44     /**
45      * Static instance of Trace helper, overridden in tests.
46      */
47     public static TraceHelper INSTANCE = new TraceHelper();
48 
49     /**
50      * @return a token to pass into {@link #endSection(Object)}.
51      */
beginSection(String sectionName)52     public Object beginSection(String sectionName) {
53         return beginSection(sectionName, 0);
54     }
55 
beginSection(String sectionName, int flags)56     public Object beginSection(String sectionName, int flags) {
57         Trace.beginSection(sectionName);
58         return null;
59     }
60 
61     /**
62      * @param token the token returned from {@link #beginSection(String, int)}
63      */
endSection(Object token)64     public void endSection(Object token) {
65         Trace.endSection();
66     }
67 
68     /**
69      * Similar to {@link #beginSection} but doesn't add a trace section.
70      */
beginFlagsOverride(int flags)71     public Object beginFlagsOverride(int flags) {
72         return null;
73     }
74 
endFlagsOverride(Object token)75     public void endFlagsOverride(Object token) { }
76 
77     /**
78      * Temporarily ignore blocking binder calls for the duration of this {@link Supplier}.
79      */
80     @MainThread
whitelistIpcs(String rpcName, Supplier<T> supplier)81     public static <T> T whitelistIpcs(String rpcName, Supplier<T> supplier) {
82         Object traceToken = INSTANCE.beginSection(rpcName, FLAG_IGNORE_BINDERS);
83         try {
84             return supplier.get();
85         } finally {
86             INSTANCE.endSection(traceToken);
87         }
88     }
89 }
90