• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.net.impl;
6 
7 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
8 
9 import java.time.Duration;
10 import java.util.regex.Matcher;
11 import java.util.regex.Pattern;
12 
13 /**
14  * Base class for implementing a CronetLogger.
15  */
16 public abstract class CronetLogger {
17     public static enum CronetSource {
18         // Safe default, don't use explicitly.
19         CRONET_SOURCE_UNSPECIFIED,
20         // The library is bundled with the application.
21         CRONET_SOURCE_STATICALLY_LINKED,
22         // The library is loaded from GooglePlayServices
23         CRONET_SOURCE_PLAY_SERVICES,
24         // The application is using the fallback implementation
25         CRONET_SOURCE_FALLBACK,
26     }
27 
28     /**
29      * Logs a cronetEngine creation action with the details of the creation.
30      *
31      * @param cronetEngineId the id of the engine being created.
32      * @param engineBuilderInfo the configuration of the CronetEngine being created. See {@link
33      *        CronetEngineBuilderInfo}
34      * @param version the version of cronet used for the engine. See {@link CronetVersion}
35      * @param source the source of the cronet provider for the engine. See {@link CronetSource}
36      */
logCronetEngineCreation(int cronetEngineId, CronetEngineBuilderInfo engineBuilderInfo, CronetVersion version, CronetSource source)37     public abstract void logCronetEngineCreation(int cronetEngineId,
38             CronetEngineBuilderInfo engineBuilderInfo, CronetVersion version, CronetSource source);
39 
40     /**
41      * Logs a request/response action.
42      * @param cronetEngineId the id of the engine used for the request
43      * @param trafficInfo the associated traffic information. See {@link CronetTrafficInfo}
44      */
logCronetTrafficInfo(int cronetEngineId, CronetTrafficInfo trafficInfo)45     public abstract void logCronetTrafficInfo(int cronetEngineId, CronetTrafficInfo trafficInfo);
46 
47     /**
48      * Aggregates the information about a CronetEngine configuration.
49      */
50     public static class CronetEngineBuilderInfo {
51         private final boolean mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
52         private final String mUserAgent;
53         private final String mStoragePath;
54         private final boolean mQuicEnabled;
55         private final boolean mHttp2Enabled;
56         private final boolean mBrotiEnabled;
57         private final int mHttpCacheMode;
58         private final String mExperimentalOptions;
59         private final boolean mNetworkQualityEstimatorEnabled;
60         private final int mThreadPriority;
61 
CronetEngineBuilderInfo(CronetEngineBuilderImpl builder)62         public CronetEngineBuilderInfo(CronetEngineBuilderImpl builder) {
63             mPublicKeyPinningBypassForLocalTrustAnchorsEnabled =
64                     builder.publicKeyPinningBypassForLocalTrustAnchorsEnabled();
65             mUserAgent = builder.getUserAgent();
66             mStoragePath = builder.storagePath();
67             mQuicEnabled = builder.quicEnabled();
68             mHttp2Enabled = builder.http2Enabled();
69             mBrotiEnabled = builder.brotliEnabled();
70             mHttpCacheMode = builder.publicBuilderHttpCacheMode();
71             mExperimentalOptions = builder.experimentalOptions();
72             mNetworkQualityEstimatorEnabled = builder.networkQualityEstimatorEnabled();
73             mThreadPriority = builder.threadPriority(THREAD_PRIORITY_BACKGROUND);
74         }
75 
76         /**
77          * @return Whether public key pinning bypass for local trust anchors is enabled
78          */
isPublicKeyPinningBypassForLocalTrustAnchorsEnabled()79         public boolean isPublicKeyPinningBypassForLocalTrustAnchorsEnabled() {
80             return mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
81         }
82         /**
83          * @return User-Agent used for URLRequests created through this CronetEngine
84          */
getUserAgent()85         public String getUserAgent() {
86             return mUserAgent;
87         }
88         /**
89          * @return Path to the directory used for HTTP cache and Cookie storage
90          */
getStoragePath()91         public String getStoragePath() {
92             return mStoragePath;
93         }
94 
95         /**
96          * @return Whether QUIC protocol is enabled
97          */
isQuicEnabled()98         public boolean isQuicEnabled() {
99             return mQuicEnabled;
100         }
101 
102         /**
103          * @return Whether HTTP2 protocol is enabled
104          */
isHttp2Enabled()105         public boolean isHttp2Enabled() {
106             return mHttp2Enabled;
107         }
108 
109         /**
110          * @return Whether Brotli compression is enabled
111          */
isBrotliEnabled()112         public boolean isBrotliEnabled() {
113             return mBrotiEnabled;
114         }
115 
116         /**
117          * @return Whether caching of HTTP data and other information like QUIC server information
118          *         is enabled
119          */
getHttpCacheMode()120         public int getHttpCacheMode() {
121             return mHttpCacheMode;
122         }
123 
124         /**
125          * @return Experimental options configuration used by the CronetEngine
126          */
getExperimentalOptions()127         public String getExperimentalOptions() {
128             return mExperimentalOptions;
129         }
130 
131         /**
132          * @return Whether network quality estimator is enabled
133          */
isNetworkQualityEstimatorEnabled()134         public boolean isNetworkQualityEstimatorEnabled() {
135             return mNetworkQualityEstimatorEnabled;
136         }
137 
138         /**
139          * @return The thread priority of Cronet's internal thread
140          */
getThreadPriority()141         public int getThreadPriority() {
142             return mThreadPriority;
143         }
144     }
145 
146     /**
147      * Aggregates the information about request and response traffic for a
148      * particular CronetEngine.
149      */
150     public static class CronetTrafficInfo {
151         private final long mRequestHeaderSizeInBytes;
152         private final long mRequestBodySizeInBytes;
153         private final long mResponseHeaderSizeInBytes;
154         private final long mResponseBodySizeInBytes;
155         private final int mResponseStatusCode;
156         private final Duration mHeadersLatency;
157         private final Duration mTotalLatency;
158         private final String mNegotiatedProtocol;
159         private final boolean mWasConnectionMigrationAttempted;
160         private final boolean mDidConnectionMigrationSucceed;
161 
CronetTrafficInfo(long requestHeaderSizeInBytes, long requestBodySizeInBytes, long responseHeaderSizeInBytes, long responseBodySizeInBytes, int responseStatusCode, Duration headersLatency, Duration totalLatency, String negotiatedProtocol, boolean wasConnectionMigrationAttempted, boolean didConnectionMigrationSucceed)162         public CronetTrafficInfo(long requestHeaderSizeInBytes, long requestBodySizeInBytes,
163                 long responseHeaderSizeInBytes, long responseBodySizeInBytes,
164                 int responseStatusCode, Duration headersLatency, Duration totalLatency,
165                 String negotiatedProtocol, boolean wasConnectionMigrationAttempted,
166                 boolean didConnectionMigrationSucceed) {
167             mRequestHeaderSizeInBytes = requestHeaderSizeInBytes;
168             mRequestBodySizeInBytes = requestBodySizeInBytes;
169             mResponseHeaderSizeInBytes = responseHeaderSizeInBytes;
170             mResponseBodySizeInBytes = responseBodySizeInBytes;
171             mResponseStatusCode = responseStatusCode;
172             mHeadersLatency = headersLatency;
173             mTotalLatency = totalLatency;
174             mNegotiatedProtocol = negotiatedProtocol;
175             mWasConnectionMigrationAttempted = wasConnectionMigrationAttempted;
176             mDidConnectionMigrationSucceed = didConnectionMigrationSucceed;
177         }
178 
179         /**
180          * @return The total size of headers sent in bytes
181          */
getRequestHeaderSizeInBytes()182         public long getRequestHeaderSizeInBytes() {
183             return mRequestHeaderSizeInBytes;
184         }
185 
186         /**
187          * @return The total size of request body sent, if any, in bytes
188          */
getRequestBodySizeInBytes()189         public long getRequestBodySizeInBytes() {
190             return mRequestBodySizeInBytes;
191         }
192 
193         /**
194          * @return The total size of headers received in bytes
195          */
getResponseHeaderSizeInBytes()196         public long getResponseHeaderSizeInBytes() {
197             return mResponseHeaderSizeInBytes;
198         }
199 
200         /**
201          * @return The total size of response body, if any, received in bytes
202          */
getResponseBodySizeInBytes()203         public long getResponseBodySizeInBytes() {
204             return mResponseBodySizeInBytes;
205         }
206 
207         /**
208          * @return The response status code of the request
209          */
getResponseStatusCode()210         public int getResponseStatusCode() {
211             return mResponseStatusCode;
212         }
213 
214         /**
215          * The time it took from starting the request to receiving the full set of
216          * response headers.
217          *
218          * @return The time to get response headers
219          */
getHeadersLatency()220         public Duration getHeadersLatency() {
221             return mHeadersLatency;
222         }
223 
224         /**
225          * The time it took from starting the request to receiving the entire
226          * response.
227          *
228          * @return The time to get total response
229          */
getTotalLatency()230         public Duration getTotalLatency() {
231             return mTotalLatency;
232         }
233 
234         /**
235          * @return The negotiated protocol used for the traffic
236          */
getNegotiatedProtocol()237         public String getNegotiatedProtocol() {
238             return mNegotiatedProtocol;
239         }
240 
241         /**
242          * @return True if the connection migration was attempted, else False
243          */
wasConnectionMigrationAttempted()244         public boolean wasConnectionMigrationAttempted() {
245             return mWasConnectionMigrationAttempted;
246         }
247 
248         /**
249          * @return True if the connection migration was attempted and succeeded, else False
250          */
didConnectionMigrationSucceed()251         public boolean didConnectionMigrationSucceed() {
252             return mDidConnectionMigrationSucceed;
253         }
254     }
255 
256     /**
257      * Holds information about the cronet version used for a cronetEngine.
258      */
259     public static class CronetVersion {
260         private static final Pattern VERSION_PATTERN =
261                 Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)");
262 
263         private final int mMajorVersion;
264         private final int mMinorVersion;
265         private final int mBuildVersion;
266         private final int mPatchVersion;
267 
268         /**
269          * Pass the cronet version string here and
270          * it would be split. The string comes in the format
271          * MAJOR.MINOR.BUILD.PATCH
272          */
CronetVersion(String version)273         public CronetVersion(String version) {
274             Matcher m = VERSION_PATTERN.matcher(version);
275             if (!m.matches()) {
276                 throw new IllegalArgumentException(
277                         "Invalid version: expected a string matching " + VERSION_PATTERN
278                                 + ", got " + version);
279             }
280 
281             mMajorVersion = Integer.parseInt(m.group(1));
282             mMinorVersion = Integer.parseInt(m.group(2));
283             mBuildVersion = Integer.parseInt(m.group(3));
284             mPatchVersion = Integer.parseInt(m.group(4));
285         }
286 
287         /**
288          * @return the MAJOR version of cronet used for the traffic
289          */
getMajorVersion()290         public int getMajorVersion() {
291             return mMajorVersion;
292         }
293 
294         /**
295          * @return the MINOR version of cronet used for the traffic
296          */
getMinorVersion()297         public int getMinorVersion() {
298             return mMinorVersion;
299         }
300 
301         /**
302          * @return the BUILD version of cronet used for the traffic
303          */
getBuildVersion()304         public int getBuildVersion() {
305             return mBuildVersion;
306         }
307 
308         /**
309          * @return the PATCH version of cronet used for the traffic
310          */
getPatchVersion()311         public int getPatchVersion() {
312             return mPatchVersion;
313         }
314 
315         @Override
toString()316         public String toString() {
317             return "" + mMajorVersion + "." + mMinorVersion + "." + mBuildVersion + "."
318                     + mPatchVersion;
319         }
320     }
321 }
322