0

RendererSideContentDecoding: Refine mojo pipe creation logic.

This CL refines the mojo data pipe creation logic in
`ContentDecodingInterceptor::Intercept` for the
RendererSideContentDecoding feature. It adds UMA for the
`mojo::CreateDataPipe` result and makes the pipe size configurable via a
feature parameter.

This CL also introduces a check of the `CreateDataPipe` result, replacing the
previous `CHECK_EQ()` with proper error handling. If `CreateDataPipe` fails, the
loader client is notified with an `ERR_INSUFFICIENT_RESOURCES` error.

These changes improve error handling and provide better insights into data pipe
creation and performance.

Bug: 391950057
Change-Id: Ie879f4f89987ceadb5760b1182c099d98d47aee9
Fixed: 406053620
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6395875
Reviewed-by: Nidhi Jaju <nidhijaju@chromium.org>
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1437928}
This commit is contained in:
Tsuyoshi Horo
2025-03-25 21:18:10 -07:00
committed by Chromium LUCI CQ
parent 1d2b452df8
commit 7382fd765e
5 changed files with 56 additions and 5 deletions
services/network/public/cpp
tools/metrics/histograms/metadata/network

@ -4,6 +4,8 @@
#include "services/network/public/cpp/content_decoding_interceptor.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/types/pass_key.h"
@ -12,6 +14,7 @@
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/filter/filter_source_stream.h"
#include "services/network/public/cpp/data_pipe_to_source_stream.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/loading_params.h"
#include "services/network/public/cpp/source_stream_to_data_pipe.h"
#include "services/network/public/mojom/early_hints.mojom.h"
@ -21,6 +24,16 @@ namespace network {
namespace {
uint32_t GetRendererSideContentDecodingPipeSize() {
const int feature_param_value =
features::kRendererSideContentDecodingPipeSize.Get();
if (feature_param_value != 0) {
return base::checked_cast<uint32_t>(feature_param_value);
}
return network::GetDataPipeDefaultAllocationSize(
network::DataPipeAllocationSize::kLargerSizeIfPossible);
}
// Implements the URLLoaderClient and URLLoader interfaces to intercept a
// request after receiving a response and perform content decoding. This class
// acts as a middleman between the original URLLoader/URLLoaderClient pair and
@ -250,11 +263,12 @@ void ContentDecodingInterceptor::Intercept(
.struct_size = sizeof(MojoCreateDataPipeOptions),
.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE,
.element_num_bytes = 1,
.capacity_num_bytes = network::GetDataPipeDefaultAllocationSize(
network::DataPipeAllocationSize::kLargerSizeIfPossible)};
CHECK_EQ(mojo::CreateDataPipe(&options, pipe_producer_handle,
pipe_consumer_handle),
MOJO_RESULT_OK);
.capacity_num_bytes = GetRendererSideContentDecodingPipeSize()};
const auto mojo_result = mojo::CreateDataPipe(&options, pipe_producer_handle,
pipe_consumer_handle);
base::UmaHistogramExactLinear(
"Network.RendererSideContentDecoding.CreateDataPipe", mojo_result,
MOJO_RESULT_SHOULD_WAIT + 1);
// Create new endpoints for the intercepted URLLoader and URLLoaderClient.
mojo::PendingReceiver<network::mojom::URLLoader> url_loader_receiver;
@ -266,6 +280,14 @@ void ContentDecodingInterceptor::Intercept(
// side.
std::move(swap_callback).Run(endpoints, pipe_consumer_handle);
if (mojo_result != MOJO_RESULT_OK) {
mojo::Remote<network::mojom::URLLoaderClient> client(
std::move(url_loader_client));
client->OnComplete(
network::URLLoaderCompletionStatus(net::ERR_INSUFFICIENT_RESOURCES));
return;
}
// Post a task to create and start the `Interceptor` on the worker thread.
worker_task_runner->PostTask(
FROM_HERE,

@ -322,6 +322,13 @@ BASE_FEATURE(kReduceTransferSizeUpdatedIPC,
BASE_FEATURE(kRendererSideContentDecoding,
"RendererSideContentDecoding",
base::FEATURE_DISABLED_BY_DEFAULT);
// When non-zero, a Mojo data pipe of this size will be used between the
// decoding thread and the data receiving thread.
BASE_FEATURE_PARAM(int,
kRendererSideContentDecodingPipeSize,
&kRendererSideContentDecoding,
/*name=*/"RendererSideContentDecodingPipeSize",
/*default_value=*/0);
// This feature allows skipping TPCD mitigation checks when the cookie access
// is tagged as being used for advertising purposes. This means that cookies

@ -134,6 +134,8 @@ BASE_DECLARE_FEATURE(kReduceTransferSizeUpdatedIPC);
COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES)
BASE_DECLARE_FEATURE(kRendererSideContentDecoding);
COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES)
BASE_DECLARE_FEATURE_PARAM(int, kRendererSideContentDecodingPipeSize);
COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES)
BASE_DECLARE_FEATURE(kSkipTpcdMitigationsForAds);

@ -240,6 +240,13 @@ chromium-metrics-reviews@google.com.
<int value="2" label="Shill error"/>
</enum>
<enum name="CreateDataPipeMojoResult">
<int value="0" label="MOJO_RESULT_OK"/>
<int value="3" label="MOJO_RESULT_INVALID_ARGUMENT"/>
<int value="8" label="MOJO_RESULT_RESOURCE_EXHAUSTED"/>
<int value="12" label="MOJO_RESULT_UNIMPLEMENTED"/>
</enum>
<enum name="DnsProxy.DnsOverHttpsMode">
<int value="0" label="Unknown"/>
<int value="1" label="Off"/>

@ -2302,6 +2302,19 @@ chromium-metrics-reviews@google.com.
</summary>
</histogram>
<histogram name="Network.RendererSideContentDecoding.CreateDataPipe"
enum="CreateDataPipeMojoResult" expires_after="2025-06-18">
<owner>horo@chromium.org</owner>
<owner>blink-network-stack@google.com</owner>
<summary>
Result of creating the Mojo data pipe used between the decoding thread and
the data receiving thread in the renderer process for the
RendererSideContentDecoding feature. Recorded whenever the renderer process
receives a resource that needs to be decoded, and the
RendererSideContentDecoding feature is enabled.
</summary>
</histogram>
<histogram
name="Network.SharedDictionary.CreateBrotliSourceStreamWithDictionary"
units="microseconds" expires_after="2025-08-24">