1 /*
2  * Copyright 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 
17 package android.webkit;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27 
28 /**
29  * Holds tracing configuration information and predefined settings.
30  */
31 public class TracingConfig {
32 
33     private @PredefinedCategories int mPredefinedCategories;
34     private final List<String> mCustomIncludedCategories = new ArrayList<String>();
35     private @TracingMode int mTracingMode;
36 
37     /** @hide */
38     @IntDef(flag = true, value = {CATEGORIES_NONE, CATEGORIES_ALL, CATEGORIES_ANDROID_WEBVIEW,
39             CATEGORIES_WEB_DEVELOPER, CATEGORIES_INPUT_LATENCY, CATEGORIES_RENDERING,
40             CATEGORIES_JAVASCRIPT_AND_RENDERING, CATEGORIES_FRAME_VIEWER})
41     @Retention(RetentionPolicy.SOURCE)
42     public @interface PredefinedCategories {}
43 
44     /**
45      * Indicates that there are no predefined categories.
46      */
47     public static final int CATEGORIES_NONE = 0;
48 
49     /**
50      * Predefined set of categories, includes all categories enabled by default in chromium.
51      * Use with caution: this setting may produce large trace output.
52      */
53     public static final int CATEGORIES_ALL = 1 << 0;
54 
55     /**
56      * Predefined set of categories typically useful for analyzing WebViews.
57      * Typically includes "android_webview" and "Java" categories.
58      */
59     public static final int CATEGORIES_ANDROID_WEBVIEW = 1 << 1;
60 
61     /**
62      * Predefined set of categories typically useful for web developers.
63      * Typically includes "blink", "compositor", "renderer.scheduler" and "v8" categories.
64      */
65     public static final int CATEGORIES_WEB_DEVELOPER = 1 << 2;
66 
67     /**
68      * Predefined set of categories for analyzing input latency issues.
69      * Typically includes "input", "renderer.scheduler" categories.
70      */
71     public static final int CATEGORIES_INPUT_LATENCY = 1 << 3;
72 
73     /**
74      * Predefined set of categories for analyzing rendering issues.
75      * Typically includes "blink", "compositor" and "gpu" categories.
76      */
77     public static final int CATEGORIES_RENDERING = 1 << 4;
78 
79     /**
80      * Predefined set of categories for analyzing javascript and rendering issues.
81      * Typically includes "blink", "compositor", "gpu", "renderer.scheduler" and "v8" categories.
82      */
83     public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 1 << 5;
84 
85     /**
86      * Predefined set of categories for studying difficult rendering performance problems.
87      * Typically includes "blink", "compositor", "gpu", "renderer.scheduler", "v8" and
88      * some other compositor categories which are disabled by default.
89      */
90     public static final int CATEGORIES_FRAME_VIEWER = 1 << 6;
91 
92     /** @hide */
93     @IntDef({RECORD_UNTIL_FULL, RECORD_CONTINUOUSLY})
94     @Retention(RetentionPolicy.SOURCE)
95     public @interface TracingMode {}
96 
97     /**
98      * Record trace events until the internal tracing buffer is full.
99      *
100      * Typically the buffer memory usage is larger than {@link #RECORD_CONTINUOUSLY}.
101      * Depending on the implementation typically allows up to 256k events to be stored.
102      */
103     public static final int RECORD_UNTIL_FULL = 0;
104 
105     /**
106      * Record trace events continuously using an internal ring buffer. Default tracing mode.
107      *
108      * Overwrites old events if they exceed buffer capacity. Uses less memory than the
109      * {@link #RECORD_UNTIL_FULL} mode. Depending on the implementation typically allows
110      * up to 64k events to be stored.
111      */
112     public static final int RECORD_CONTINUOUSLY = 1;
113 
114     /**
115      * @hide
116      */
TracingConfig(@redefinedCategories int predefinedCategories, @NonNull List<String> customIncludedCategories, @TracingMode int tracingMode)117     public TracingConfig(@PredefinedCategories int predefinedCategories,
118             @NonNull List<String> customIncludedCategories,
119             @TracingMode int tracingMode) {
120         mPredefinedCategories = predefinedCategories;
121         mCustomIncludedCategories.addAll(customIncludedCategories);
122         mTracingMode = tracingMode;
123     }
124 
125     /**
126      * Returns a bitmask of the predefined category sets of this configuration.
127      *
128      * @return Bitmask of predefined category sets.
129      */
130     @PredefinedCategories
getPredefinedCategories()131     public int getPredefinedCategories() {
132         return mPredefinedCategories;
133     }
134 
135     /**
136      * Returns the list of included custom category patterns for this configuration.
137      *
138      * @return Empty list if no custom category patterns are specified.
139      */
140     @NonNull
getCustomIncludedCategories()141     public List<String> getCustomIncludedCategories() {
142         return mCustomIncludedCategories;
143     }
144 
145     /**
146      * Returns the tracing mode of this configuration.
147      *
148      * @return The tracing mode of this configuration.
149      */
150     @TracingMode
getTracingMode()151     public int getTracingMode() {
152         return mTracingMode;
153     }
154 
155     /**
156      * Builder used to create {@link TracingConfig} objects.
157      * <p>
158      * Examples:
159      * <pre class="prettyprint">
160      *   // Create a configuration with default options: {@link #CATEGORIES_NONE},
161      *   // {@link #RECORD_CONTINUOUSLY}.
162      *   <code>new TracingConfig.Builder().build()</code>
163      *
164      *   // Record trace events from the "web developer" predefined category sets.
165      *   // Uses a ring buffer (the default {@link #RECORD_CONTINUOUSLY} mode) for
166      *   // internal storage during tracing.
167      *   <code>new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER).build()</code>
168      *
169      *   // Record trace events from the "rendering" and "input latency" predefined
170      *   // category sets.
171      *   <code>new TracingConfig.Builder().addCategories(CATEGORIES_RENDERING,
172      *                                     CATEGORIES_INPUT_LATENCY).build()</code>
173      *
174      *   // Record only the trace events from the "browser" category.
175      *   <code>new TracingConfig.Builder().addCategories("browser").build()</code>
176      *
177      *   // Record only the trace events matching the "blink*" and "renderer*" patterns
178      *   // (e.g. "blink.animations", "renderer_host" and "renderer.scheduler" categories).
179      *   <code>new TracingConfig.Builder().addCategories("blink*","renderer*").build()</code>
180      *
181      *   // Record events from the "web developer" predefined category set and events from
182      *   // the "disabled-by-default-v8.gc" category to understand where garbage collection
183      *   // is being triggered. Uses a limited size buffer for internal storage during tracing.
184      *   <code>new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER)
185      *                              .addCategories("disabled-by-default-v8.gc")
186      *                              .setTracingMode(RECORD_UNTIL_FULL).build()</code>
187      * </pre>
188      */
189     public static class Builder {
190         private @PredefinedCategories int mPredefinedCategories = CATEGORIES_NONE;
191         private final List<String> mCustomIncludedCategories = new ArrayList<String>();
192         private @TracingMode int mTracingMode = RECORD_CONTINUOUSLY;
193 
194         /**
195          * Default constructor for Builder.
196          */
Builder()197         public Builder() {}
198 
199         /**
200          * Build {@link TracingConfig} using the current settings.
201          *
202          * @return The {@link TracingConfig} with the current settings.
203          */
build()204         public TracingConfig build() {
205             return new TracingConfig(mPredefinedCategories, mCustomIncludedCategories,
206                     mTracingMode);
207         }
208 
209         /**
210          * Adds predefined sets of categories to be included in the trace output.
211          *
212          * A predefined category set can be one of {@link #CATEGORIES_NONE},
213          * {@link #CATEGORIES_ALL}, {@link #CATEGORIES_ANDROID_WEBVIEW},
214          * {@link #CATEGORIES_WEB_DEVELOPER}, {@link #CATEGORIES_INPUT_LATENCY},
215          * {@link #CATEGORIES_RENDERING}, {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or
216          * {@link #CATEGORIES_FRAME_VIEWER}.
217          *
218          * @param predefinedCategories A list or bitmask of predefined category sets.
219          * @return The builder to facilitate chaining.
220          */
addCategories(@redefinedCategories int... predefinedCategories)221         public Builder addCategories(@PredefinedCategories int... predefinedCategories) {
222             for (int categorySet : predefinedCategories) {
223                 mPredefinedCategories |= categorySet;
224             }
225             return this;
226         }
227 
228         /**
229          * Adds custom categories to be included in trace output.
230          *
231          * Note that the categories are defined by the currently-in-use version of WebView. They
232          * live in chromium code and are not part of the Android API.
233          * See <a href="https://www.chromium.org/developers/how-tos/trace-event-profiling-tool">
234          * chromium documentation on tracing</a> for more details.
235          *
236          * @param categories A list of category patterns. A category pattern can contain wildcards,
237          *        e.g. "blink*" or full category name e.g. "renderer.scheduler".
238          * @return The builder to facilitate chaining.
239          */
addCategories(String... categories)240         public Builder addCategories(String... categories) {
241             for (String category: categories) {
242                 mCustomIncludedCategories.add(category);
243             }
244             return this;
245         }
246 
247         /**
248          * Adds custom categories to be included in trace output.
249          *
250          * Same as {@link #addCategories(String...)} but allows to pass a Collection as a parameter.
251          *
252          * @param categories A list of category patterns.
253          * @return The builder to facilitate chaining.
254          */
addCategories(Collection<String> categories)255         public Builder addCategories(Collection<String> categories) {
256             mCustomIncludedCategories.addAll(categories);
257             return this;
258         }
259 
260         /**
261          * Sets the tracing mode for this configuration.
262          * When tracingMode is not set explicitly, the default is {@link #RECORD_CONTINUOUSLY}.
263          *
264          * @param tracingMode The tracing mode to use, one of {@link #RECORD_UNTIL_FULL} or
265          *                    {@link #RECORD_CONTINUOUSLY}.
266          * @return The builder to facilitate chaining.
267          */
setTracingMode(@racingMode int tracingMode)268         public Builder setTracingMode(@TracingMode int tracingMode) {
269             mTracingMode = tracingMode;
270             return this;
271         }
272     }
273 
274 }
275