| /* |
| * Copyright (C) 2023 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| syntax = "proto2"; |
| |
| package android.os.statsd.cronet; |
| |
| import "frameworks/proto_logging/stats/atoms.proto"; |
| import "frameworks/proto_logging/stats/atom_field_options.proto"; |
| |
| option java_package = "com.android.os.cronet"; |
| option java_multiple_files = true; |
| |
| extend Atom { |
| optional CronetEngineCreated cronet_engine_created = 703 |
| [(module) = "cronet"]; |
| optional CronetTrafficReported cronet_traffic_reported = 704 |
| [(module) = "cronet"]; |
| optional CronetEngineBuilderInitialized cronet_engine_builder_initialized = 762 [(module) = "cronet"]; |
| optional CronetHttpFlagsInitialized cronet_http_flags_initialized = 763 [(module) = "cronet"]; |
| optional CronetInitialized cronet_initialized = 764 [(module) = "cronet"]; |
| } |
| |
| // Logged every time CronetEngine.Builder#build() returns. |
| message CronetEngineCreated { |
| // A weak-ID-like reference to the instance of the Cronet engine being |
| // created. The field can be used to join subsequent request metrics with the |
| // engine details. |
| // |
| // The reference is NOT meant to be globally (or even on-device) unique, but |
| // on device collisions should be unlikely. |
| // Defaults to max positive int64 value which is equivalent to "not set". |
| optional int64 engine_instance_ref = 1 [default = 9223372036854775807]; |
| // Deprecated, moved to CronetEngineBuilderInitialized |
| optional int32 major_version = 2 [deprecated = true]; |
| // Deprecated, moved to CronetEngineBuilderInitialized |
| optional int32 minor_version = 3 [deprecated = true]; |
| // Deprecated, moved to CronetEngineBuilderInitialized |
| optional int32 build_version = 4 [deprecated = true]; |
| // Deprecated, moved to CronetEngineBuilderInitialized |
| optional int32 patch_version = 5 [deprecated = true]; |
| |
| // Deprecated, moved to CronetInitialized |
| optional CronetSource source = 6 [deprecated = true]; |
| // Options that can be set on the Cronet builder. Only fields which are |
| // actively set by the Cronet user are populated. When using the protos |
| // default values should be considered as "null" - default semnantics can |
| // change based on the Cronet version. |
| // |
| // Fields that can contain free text (even if just theoretically) should be |
| // curated and/or replaced with fields that provide useful signal while not |
| // being sensitive. For instance, instead of logging values of quic hint hosts |
| // verbatim, prefer to log if a request was affected by a hint. |
| // |
| // For field names, follow the nomenclature below: |
| // - fields set directly on the builder should have no prefix |
| // (e.g., enableBrotli() translates to enable_brotli) |
| // - fields which are set in a sub-object or sub-structure should be prefixed |
| // with the path leading to that field. For example, |
| // builder.setExperimentalOptions("quic: { foo: { bar: 2 } }"); |
| // translates to experimental_options_quic_foo_bar |
| // |
| // |
| // In both cases, keep the existing names that are used in Cronet if at all |
| // possible. |
| |
| // --- CronetEngine.Builder controls --- |
| optional bool enable_brotli = 7; |
| optional bool enable_http2 = 8; |
| optional CronetHttpCacheMode http_cache_mode = 9; |
| optional bool enable_public_key_pinning_bypass_for_local_trust_anchors = 10; |
| optional bool enable_quic = 11; |
| |
| // --- ExperimentalCronetEngine.Builder controls --- |
| optional bool enable_network_quality_estimator = 12; |
| optional int32 thread_priority = 13; |
| |
| // --- JSON experimental options --- |
| // The JSON config offers a lot of options but most of the atoms will have |
| // a majority of the fields below unset. We considered lumping the boolean |
| // flags into a single int32 field bud decided not to do so because |
| // a) having the standalone booleans makes the data set easier to understand |
| // and use |
| // b) we need to distinguish between three states (unset / true / false) |
| // which makes the compaction less efficient |
| // c) we expect the booleans to not be set in majority of the cases, |
| // in such a case, no space is saved. |
| |
| // QUIC |
| // Lexicographically sorted, comma separated, curated list of QUIC connection |
| // options. |
| optional string experimental_options_quic_connection_options = 14; |
| optional OptionalBoolean |
| experimental_options_quic_store_server_configs_in_properties = 15; |
| // Unset value is -1 |
| optional int32 |
| experimental_options_quic_max_server_configs_stored_in_properties = 16 |
| [default = -1]; |
| // Unset value is -1 |
| optional int32 experimental_options_quic_idle_connection_timeout_seconds = 17 |
| [default = -1]; |
| optional OptionalBoolean |
| experimental_options_quic_goaway_sessions_on_ip_change = 18; |
| optional OptionalBoolean |
| experimental_options_quic_close_sessions_on_ip_change = 19; |
| optional OptionalBoolean |
| experimental_options_quic_migrate_sessions_on_network_change_v2 = 20; |
| optional OptionalBoolean experimental_options_quic_migrate_sessions_early_v2 = |
| 21; |
| optional OptionalBoolean |
| experimental_options_quic_quic_disable_bidirectional_streams = 22; |
| // Unset value is -1 |
| optional int32 |
| experimental_options_quic_max_time_before_crypto_handshake_seconds = 23 |
| [default = -1]; |
| // Unset value is -1 |
| optional int32 |
| experimental_options_quic_max_idle_time_before_crypto_handshake_seconds = |
| 24 [default = -1]; |
| optional OptionalBoolean |
| experimental_options_quic_enable_socket_recv_optimization = 25; |
| |
| // DNS |
| optional OptionalBoolean experimental_options_asyncdns_enable = 26; |
| optional OptionalBoolean experimental_options_staledns_enable = 27; |
| // Unset value is -1 |
| optional int32 experimental_options_staledns_delay_ms = 28 [default = -1]; |
| // Unset value is -1 |
| optional int32 experimental_options_staledns_max_expired_time_ms = 29 |
| [default = -1]; |
| // Unset value is -1 |
| optional int32 experimental_options_staledns_max_stale_uses = 30 |
| [default = -1]; |
| optional OptionalBoolean experimental_options_staledns_allow_other_network = |
| 31; |
| optional OptionalBoolean experimental_options_staledns_persist_to_disk = 32; |
| // Unset value is -1 |
| optional int32 experimental_options_staledns_persist_delay_ms = 33 |
| [default = -1]; |
| optional OptionalBoolean |
| experimental_options_staledns_use_stale_on_name_not_resolved = 34; |
| // Host resolver rules omitted |
| optional OptionalBoolean experimental_options_disable_ipv6_on_wifi = 35; |
| |
| // Deprecated, moved to CronetEngineBuilderInitialized. |
| enum CronetSource { |
| option deprecated = true; |
| // Safe default, don't use explicitly. |
| CRONET_SOURCE_UNSPECIFIED = 0; |
| // The library is bundled with the application. |
| CRONET_SOURCE_STATICALLY_LINKED = 1; |
| // The library is loaded from GMS Core |
| CRONET_SOURCE_GMSCORE_DYNAMITE = 2; |
| // The application is using the fallback implementation |
| CRONET_SOURCE_FALLBACK = 3; |
| } |
| |
| // A pointer to CronetInitialized.cronet_initialization_ref for the Cronet initialization |
| // sequence that this engine relied on. |
| // Note that CronetInitialized may be logged after CronetEngineCreated because initialization |
| // continues in the background after the CronetEngine is instantiated. |
| // One consequence is that this reference can be broken if a |
| // crash occurs after the engine is created but before initialization is complete. |
| optional int64 cronet_initialization_ref = 36; |
| |
| // See |
| // https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html#constants |
| // for detailed semantics. |
| enum CronetHttpCacheMode { |
| // Safe default, don't use explicitly. |
| HTTP_CACHE_MODE_UNSPECIFIED = 0; |
| |
| HTTP_CACHE_DISABLED = 1; |
| HTTP_CACHE_DISK = 2; |
| HTTP_CACHE_DISK_NO_HTTP = 3; |
| HTTP_CACHE_IN_MEMORY = 4; |
| } |
| } |
| |
| // Logged when a request has reached terminal state after the final user callback has returned |
| // and before the requestFinishedListeners has fired. |
| message CronetTrafficReported { |
| // The Cronet engine that sent the trafic. See |
| // CronetEngineCreated.engine_instance_ref for more details. |
| // Defaults to max negative int64 value which is equivalent to "not set". |
| // The default value is deliberately different from |
| // CronetEngineCreated.engine_instance_ref to avoid unintentional joining. |
| optional int64 engine_instance_ref = 1 [default = -9223372036854775808]; |
| |
| // Bucketized sizes for request and response headers and body. |
| optional CronetRequestHeadersSizeBucket request_headers_size = 2; |
| optional CronetRequestBodySizeBucket request_body_size = 3; |
| optional CronetResponseHeadersSizeBucket response_headers_size = 4; |
| optional CronetResponseBodySizeBucket response_body_size = 5; |
| |
| // The status code of the response. |
| optional int32 http_status_code = 6; |
| // The Fingerprint2011 hash of the protocol that was negotiated for this |
| // request (as returned by UrlResponseInfo.getNegotiatedProtocol()). The |
| // possible values for the string are limited so the hash is sufficient |
| // to identify known values while preventing accidental presence of |
| // freeform text. |
| // See go/cronet-negotiated-protocols for possible values. |
| optional int64 negotiated_protocol_hash = 7; |
| |
| // The time it took from starting the request to receiving the full set of |
| // response headers, in milliseconds. |
| optional int32 headers_latency_millis = 8; |
| |
| // The time that elapsed from the point UrlRequest#start() was called to the point |
| // we are ready to call the final user callback (e.g. onSucceeded). |
| // Note: this includes time spent waiting for the user to issue an I/O request. |
| // In other words this includes the effect of the user |
| // throttling Cronet (a.k.a. flow control, a.k.a. backpressure). |
| // See also total_idle_time_millis |
| optional int32 overall_latency_millis = 9; |
| |
| // Whether a connection migration was attempted for this request. |
| optional bool connection_migration_attempted = 10; |
| // Whether a connection migration was attempted and successful for this |
| // request. |
| optional bool connection_migration_successful = 11; |
| |
| // Number of previous CronetTrafficReported records that were dropped due to rate limiting. |
| optional int32 samples_rate_limited = 12; |
| |
| // Terminal state of the reported request. |
| optional CronetRequestTerminalState terminal_state = 13; |
| |
| enum CronetRequestTerminalState { |
| STATE_UNKNOWN = 0; |
| STATE_SUCCEEDED = 1; |
| STATE_ERROR = 2; |
| STATE_CANCELLED = 3; |
| } |
| |
| // count of exceptions thrown during the execution of a user callback. |
| optional int32 user_callback_exception_count = 14; |
| |
| // Same as `overall_latency_millis`, but only including time spent with no |
| // outstanding I/O request from the user. For example, the time that elapses between Cronet |
| // becoming ready to call the onReadCompleted callback and the user making the |
| // next UrlRequest#read() call is idle time: during that time |
| // there is no outstanding read request. |
| // If this value is large relative to overall_latency_millis, it may mean the request was |
| // throttled by the user, i.e. they applied backpressure/flow control, intentionally or not. |
| // Note that in this context, "idle" should be interpreted from the |
| // perspective of the Cronet user. Internally, Cronet might not actually be "idle" |
| // as it may still attempt to keep its internal buffers filled. |
| // An example of Cronet idly waiting for the user would look like the following |
| /* |
| Cronet User |
| | |
| | |
| |----- OnResponseStarted ------| |
| | |
| Cronet | |
| Idle | |
| Time | |
| | |
| Cronet |------------------------------| User calls request.read() |
| Doing | |
| Work | |
| | |
| OnReadCompleted | |
| | |
| |----- onReadCompleted -------| |
| | Cronet Idle Time includes the time taken to call |
| | Executor#execute() on the user's executor. |
| | |
| Cronet | If the user is blocking the network |
| Idle | thread in Executor#execute(), then technically that |
| Time | counts as backpressure / flow control. |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |------------------------------| |
| */ |
| // This field contains the sum of Cronet Idle time waiting for user calls. |
| optional int64 total_idle_time_millis = 15; |
| |
| // The time it takes for the user's Executor#execute() method to return |
| // Note: contrary to most other metrics in this atom, this also includes |
| // the final user callback (e.g. onSucceeded). |
| // Note: in the case of the native implementation, Executor#execute() is called on |
| // the network thread, which is a shared resource. High values for this metric are |
| // usually a red flag because they mean the network thread is unable to service any |
| // other UrlRequests during this time (including those from other engines). |
| optional int64 total_user_executor_execute_latency_millis = 16; |
| |
| // The total amount of times `UrlRequest#read()` was called. |
| optional int32 read_count = 17; |
| |
| // The total amount of times `UploadDataProvider#read` has been fired. |
| optional int32 on_upload_read_count = 18; |
| |
| // Indicates if the request is a bidirectional stream or not. |
| optional OptionalBoolean is_bidi_stream = 19; |
| |
| |
| enum CronetRequestHeadersSizeBucket { |
| REQUEST_HEADERS_SIZE_BUCKET_UNSPECIFIED = 0; |
| // It's impossible to send requests without any headers in Cronet |
| REQUEST_HEADERS_SIZE_BUCKET_UNDER_ONE_KIB = 1; |
| REQUEST_HEADERS_SIZE_BUCKET_ONE_TO_TEN_KIB = 2; |
| REQUEST_HEADERS_SIZE_BUCKET_TEN_TO_TWENTY_FIVE_KIB = 3; |
| REQUEST_HEADERS_SIZE_BUCKET_TWENTY_FIVE_TO_FIFTY_KIB = 4; |
| REQUEST_HEADERS_SIZE_BUCKET_FIFTY_TO_HUNDRED_KIB = 5; |
| REQUEST_HEADERS_SIZE_BUCKET_OVER_HUNDRED_KIB = 6; |
| } |
| |
| enum CronetRequestBodySizeBucket { |
| REQUEST_BODY_SIZE_BUCKET_UNSPECIFIED = 0; |
| REQUEST_BODY_SIZE_BUCKET_ZERO = 1; |
| REQUEST_BODY_SIZE_BUCKET_UNDER_TEN_KIB = 2; |
| REQUEST_BODY_SIZE_BUCKET_TEN_TO_FIFTY_KIB = 3; |
| REQUEST_BODY_SIZE_BUCKET_FIFTY_TO_TWO_HUNDRED_KIB = 4; |
| REQUEST_BODY_SIZE_BUCKET_TWO_HUNDRED_TO_FIVE_HUNDRED_KIB = 5; |
| REQUEST_BODY_SIZE_BUCKET_FIVE_HUNDRED_KIB_TO_ONE_MIB = 6; |
| REQUEST_BODY_SIZE_BUCKET_ONE_TO_FIVE_MIB = 7; |
| REQUEST_BODY_SIZE_BUCKET_OVER_FIVE_MIB = 8; |
| } |
| |
| enum CronetResponseHeadersSizeBucket { |
| RESPONSE_HEADERS_SIZE_BUCKET_UNSPECIFIED = 0; |
| RESPONSE_HEADERS_SIZE_BUCKET_UNDER_ONE_KIB = 1; |
| RESPONSE_HEADERS_SIZE_BUCKET_ONE_TO_TEN_KIB = 2; |
| RESPONSE_HEADERS_SIZE_BUCKET_TEN_TO_TWENTY_FIVE_KIB = 3; |
| RESPONSE_HEADERS_SIZE_BUCKET_TWENTY_FIVE_TO_FIFTY_KIB = 4; |
| RESPONSE_HEADERS_SIZE_BUCKET_FIFTY_TO_HUNDRED_KIB = 5; |
| RESPONSE_HEADERS_SIZE_BUCKET_OVER_HUNDRED_KIB = 6; |
| } |
| |
| enum CronetResponseBodySizeBucket { |
| RESPONSE_BODY_SIZE_BUCKET_UNSPECIFIED = 0; |
| RESPONSE_BODY_SIZE_BUCKET_ZERO = 1; |
| RESPONSE_BODY_SIZE_BUCKET_UNDER_TEN_KIB = 2; |
| RESPONSE_BODY_SIZE_BUCKET_TEN_TO_FIFTY_KIB = 3; |
| RESPONSE_BODY_SIZE_BUCKET_FIFTY_TO_TWO_HUNDRED_KIB = 4; |
| RESPONSE_BODY_SIZE_BUCKET_TWO_HUNDRED_TO_FIVE_HUNDRED_KIB = 5; |
| RESPONSE_BODY_SIZE_BUCKET_FIVE_HUNDRED_KIB_TO_ONE_MIB = 6; |
| RESPONSE_BODY_SIZE_BUCKET_ONE_TO_FIVE_MIB = 7; |
| RESPONSE_BODY_SIZE_BUCKET_OVER_FIVE_MIB = 8; |
| } |
| } |
| |
| // Logged when the HTTP flags have been read. |
| message CronetHttpFlagsInitialized { |
| // A weak-ID-like reference to the http flags loading operation. |
| // The field can be used to join with CronetEngineBuilderInitialized atom. |
| optional int64 cronet_http_flags_ref = 1; |
| // how long it took to load (or attempt to load) http flags. |
| // This field is set to -1 if flag loading was not attempted |
| // (e.g. because the app opted out of Cronet flag support). |
| // Note: There is no support for unset values, hence -1 is used. |
| optional int32 http_flags_latency_millis = 2 [default = -1]; |
| // Determine whether flag loading was successful or not. |
| optional OptionalBoolean flags_successful = 3; |
| |
| // The first 8 bytes of the MD5 hashes, interpreted as signed little-endian integers, |
| // of the HTTP flag names that the Cronet instance logging the atoms is |
| // actually running with. |
| repeated int64 http_flags_names = 4 [packed = true]; |
| |
| // The effective values of the flags, in the same order as |
| // http_flags_names. |
| // For boolean flags, this is 0 or 1. |
| // For integer flags, this is the value of the flag itself. |
| // For float values, this is the floating point value multiplied by 1 billion, |
| // rounded, and clamped to the int64 range. (This should result in distinct |
| // values for most commonly used floating point inputs.) |
| // For string or bytes flags, this is a hash of the value |
| // calculated in the same way as http_flags_names above. |
| repeated int64 http_flags_values = 5 [packed = true]; |
| } |
| |
| /* |
| --------------------- ----------------- |
| | | createBuilder() | | ================⦀ |
| | Provider | -------------------------------> | Builder | ⦀ |
| | | | | ⦀ |
| |-------------------| engine_builder_created_lat |---------------- ⦀ |
| | ⦀ |
| Build() | engine_created_latency ⦀ |
| | ⦀ |
| V ⦀ |
| ------------------ ------------------- ⦀ |
| | | | | ⦀ |
| | REQ CAN START | <------------- | Engine | ⦀ |
| |WITHOUT BLOCKING| | | ⦀ |
| |----------------| |-----------------| ⦀ |
| ⦀ ⦀ |
| ==================================================================⦀ |
| engine_async_latency (This takes a variable amount of time depending on async jobs) |
| |
| engine_builder_created_latency: The wall time elapsed since createBuilder() has been called |
| until a builder has been returned. |
| |
| engine_created_latency: The wall time elapsed since Build() has been called until a CronetEngine |
| has been returned. |
| |
| engine_async_latency: The wall time elapsed since Build() |
| has been called until the returned CronetEngine |
| is usable (All Asynchronous setup calls have finished executing). |
| */ |
| |
| // Logged once for each CronetSource when createBuilder() has returned. |
| // This atom should normally be logged from Cronet API code (as opposed to impl code). |
| // If the app is bundling a Cronet API version that is too old to know about this atom, |
| // the impl takes responsibility for logging this atom and attempts to do so soon as |
| // the impl is loaded. Some fields may be missing in this case. |
| message CronetEngineBuilderInitialized { |
| // A weak-ID-like reference to the instance of the Cronet initialization. |
| // The field can be used to join subsequent engine creation and request |
| // metrics with the initialization details. |
| optional int64 cronet_initialization_ref = 1; |
| |
| // How long it took to produce the first `CronetEngine.Builder` instance for the source specified. |
| // This field can be set by Api layer or Impl Layer, If this field was set by the Impl layer then |
| // the value of the field will be equal to -1. |
| optional int32 engine_builder_created_latency_millis = 2 [default = -1]; |
| |
| // Source of the Cronet being loaded |
| optional Source source = 3; |
| |
| enum Source { |
| // Safe default, don't use explicitly. |
| CRONET_SOURCE_UNSPECIFIED = 0; |
| // Native-based Cronet implementation, bundled within the client app. |
| CRONET_SOURCE_EMBEDDED_NATIVE = 1; |
| // Java-based Cronet implementation, bundled within the client app. |
| CRONET_SOURCE_EMBEDDED_JAVA = 2; |
| // Native-based Cronet implementation, loaded from GMS Core (Google Play Services). |
| CRONET_SOURCE_GMSCORE_NATIVE = 3; |
| // Native-based Cronet implementation, loaded from the bootclasspath |
| // through the android.net.http.HttpEngine API. |
| CRONET_SOURCE_HTTPENGINE_NATIVE = 4; |
| } |
| |
| |
| // Whether the Provider successfully created a builder or not. |
| // This field can be set by Api layer or Impl Layer, If this field was set by the Impl layer then |
| // the value of the field will be equal to `UNSET`. |
| optional OptionalBoolean creation_successful = 4; |
| |
| // A weak-ID-like reference to the http flags loading operation. |
| // The field can be used to join with CronetHttpFlagsInitialized atoms. |
| // Note: at the time of writing, loading of flags happens after the builder creation |
| // has returned. This means the corresponding CronetHttpFlagsLoaded is logged |
| // after or might not be logged at all (if there was a crash or |
| // the resulting builder was never used). |
| optional int64 cronet_http_flags_ref = 5; |
| |
| // This field carries the value stored in the file below |
| // https://source.chromium.org/chromium/chromium/src/+/main:components/cronet/android/api/src/org/chromium/net/ApiVersion.template |
| optional int32 cronet_api_level = 6; |
| |
| // This field carries the value stored in the file below |
| // https://source.chromium.org/chromium/chromium/src/+/main:components/cronet/android/java/src/org/chromium/net/impl/ImplVersion.template |
| optional int32 cronet_impl_api_level = 7; |
| |
| // The following fields corresponds to the version of Chromium for which the implementation |
| // was compiled against as seen https://source.chromium.org/chromium/chromium/src/+/main:chrome/VERSION;l=1;bpv=0;bpt=0 |
| optional int32 major_version = 8; |
| optional int32 minor_version = 9; |
| optional int32 build_version = 10; |
| optional int32 patch_version = 11; |
| // The Android UID of the process that Cronet was initialized in. |
| optional int32 uid = 12 [(is_uid) = true]; |
| } |
| |
| // Logged once for each CronetSource when the first CronetEngine is ready to be used. |
| // Note that CronetInitialized may be logged after CronetEngineCreated because initialization |
| // may continue in the background after the CronetEngine is instantiated. |
| // One consequence is that cronet_initialization_ref can be broken if a |
| // crash occurs after the engine is created but before initialization is complete. |
| message CronetInitialized { |
| // A weak-ID-like reference to the instance of the Cronet initialization. |
| // The field can be used to join subsequent engine creation and request |
| // metrics with the native details. |
| optional int64 cronet_initialization_ref = 1; |
| |
| // The wall clock time spent in the execution of the first call to `CronetEngine.Builder#build` |
| optional int32 engine_creation_latency_millis = 2 [default = -1]; |
| |
| // How much wall clock time was spent from the moment the first `CronetEngine.Builder#build()` |
| // was made and the point where Cronet is ready to send requests. Notably, |
| // this includes the time it took for any asynchronous background initialization code to complete |
| optional int32 engine_async_latency_millis = 3 [default = -1]; |
| } |
| |
| // Distinguishes between three states (unset / true / false) |
| enum OptionalBoolean { |
| UNSET = 0; |
| TRUE = 1; |
| FALSE = 2; |
| } |