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