• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotation.SuppressLint;
19 import android.os.Trace;
20 
21 import androidx.annotation.MainThread;
22 
23 import kotlin.random.Random;
24 
25 import java.util.function.Supplier;
26 
27 /**
28  * A wrapper around {@link Trace} to allow better testing.
29  *
30  * To enable any tracing log, execute the following command:
31  * $ adb shell setprop log.tag.LAUNCHER_TRACE VERBOSE
32  * $ adb shell setprop log.tag.TAGNAME VERBOSE
33  */
34 public class TraceHelper {
35 
36     // Track binder class for this trace
37     public static final int FLAG_ALLOW_BINDER_TRACKING = 1 << 0;
38 
39     // Temporarily ignore blocking binder calls for this trace.
40     public static final int FLAG_IGNORE_BINDERS = 1 << 1;
41 
42     /**
43      * Static instance of Trace helper, overridden in tests.
44      */
45     public static TraceHelper INSTANCE = new TraceHelper();
46 
47     /**
48      * @see Trace#beginSection(String)
49      */
beginSection(String sectionName)50     public void beginSection(String sectionName) {
51         Trace.beginSection(sectionName);
52     }
53 
54     /**
55      * @see Trace#endSection()
56      */
endSection()57     public void endSection() {
58         Trace.endSection();
59     }
60 
61     /**
62      * @see Trace#beginAsyncSection(String, int)
63      * @return a SafeCloseable that can be used to end the session
64      */
65     @SuppressWarnings("NewApi")
66     @SuppressLint("NewApi")
beginAsyncSection(String sectionName)67     public SafeCloseable beginAsyncSection(String sectionName) {
68         int cookie = Random.Default.nextInt();
69         Trace.beginAsyncSection(sectionName, cookie);
70         return () -> Trace.endAsyncSection(sectionName, cookie);
71     }
72 
73     /**
74      * Returns a SafeCloseable to temporarily ignore blocking binder calls.
75      */
76     @SuppressWarnings("NewApi")
77     @SuppressLint("NewApi")
allowIpcs(String rpcName)78     public SafeCloseable allowIpcs(String rpcName) {
79         int cookie = Random.Default.nextInt();
80         Trace.beginAsyncSection(rpcName, cookie);
81         return () -> Trace.endAsyncSection(rpcName, cookie);
82     }
83 
84     /**
85      * Temporarily ignore blocking binder calls for the duration of this {@link Supplier}.
86      *
87      * Note, new features should be designed to not rely on mainThread RPCs.
88      */
89     @MainThread
allowIpcs(String rpcName, Supplier<T> supplier)90     public static <T> T allowIpcs(String rpcName, Supplier<T> supplier) {
91         try (SafeCloseable c = INSTANCE.allowIpcs(rpcName)) {
92             return supplier.get();
93         }
94     }
95 }
96