diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/speech | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/speech')
-rw-r--r-- | chromium/components/speech/BUILD.gn | 22 | ||||
-rw-r--r-- | chromium/components/speech/DEPS | 4 | ||||
-rw-r--r-- | chromium/components/speech/downstream_loader.cc | 48 | ||||
-rw-r--r-- | chromium/components/speech/downstream_loader.h | 46 | ||||
-rw-r--r-- | chromium/components/speech/downstream_loader_client.h | 40 | ||||
-rw-r--r-- | chromium/components/speech/upstream_loader.cc | 129 | ||||
-rw-r--r-- | chromium/components/speech/upstream_loader.h | 77 | ||||
-rw-r--r-- | chromium/components/speech/upstream_loader_client.h | 34 |
8 files changed, 400 insertions, 0 deletions
diff --git a/chromium/components/speech/BUILD.gn b/chromium/components/speech/BUILD.gn new file mode 100644 index 00000000000..30148e5ce03 --- /dev/null +++ b/chromium/components/speech/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("speech") { + sources = [ + "downstream_loader.cc", + "downstream_loader.h", + "downstream_loader_client.h", + "upstream_loader.cc", + "upstream_loader.h", + "upstream_loader_client.h", + ] + + deps = [ + "//mojo/public/cpp/bindings", + "//mojo/public/cpp/platform", + "//mojo/public/cpp/system", + "//services/network/public/cpp", + "//services/network/public/mojom", + ] +} diff --git a/chromium/components/speech/DEPS b/chromium/components/speech/DEPS new file mode 100644 index 00000000000..38ed60b94e2 --- /dev/null +++ b/chromium/components/speech/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+mojo/public/cpp", + "+services/network/public", +] diff --git a/chromium/components/speech/downstream_loader.cc b/chromium/components/speech/downstream_loader.cc new file mode 100644 index 00000000000..14ca74922de --- /dev/null +++ b/chromium/components/speech/downstream_loader.cc @@ -0,0 +1,48 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/speech/downstream_loader.h" + +#include "base/callback.h" +#include "components/speech/downstream_loader_client.h" + +namespace speech { + +DownstreamLoader::DownstreamLoader( + std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + DownstreamLoaderClient* downstream_loader_client) + : downstream_loader_client_(downstream_loader_client) { + DCHECK(downstream_loader_client_); + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), upstream_traffic_annotation); + simple_url_loader_->DownloadAsStream(url_loader_factory, this); +} + +DownstreamLoader::~DownstreamLoader() = default; + +void DownstreamLoader::OnDataReceived(base::StringPiece string_piece, + base::OnceClosure resume) { + downstream_loader_client_->OnDownstreamDataReceived(string_piece); + std::move(resume).Run(); +} + +void DownstreamLoader::OnComplete(bool success) { + int response_code = -1; + if (simple_url_loader_->ResponseInfo() && + simple_url_loader_->ResponseInfo()->headers) { + response_code = + simple_url_loader_->ResponseInfo()->headers->response_code(); + } + + downstream_loader_client_->OnDownstreamDataComplete(success, response_code); +} + +void DownstreamLoader::OnRetry(base::OnceClosure start_retry) { + // Retries are not enabled for these requests. + NOTREACHED(); +} + +} // namespace speech diff --git a/chromium/components/speech/downstream_loader.h b/chromium/components/speech/downstream_loader.h new file mode 100644 index 00000000000..f6682a7f8be --- /dev/null +++ b/chromium/components/speech/downstream_loader.h @@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_DOWNSTREAM_LOADER_H_ +#define COMPONENTS_SPEECH_DOWNSTREAM_LOADER_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/strings/string_piece.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/cpp/simple_url_loader_stream_consumer.h" + +namespace speech { + +class DownstreamLoaderClient; + +// Streams response data from the server to the DownstreamLoaderClient. +class DownstreamLoader : public network::SimpleURLLoaderStreamConsumer { + public: + DownstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + DownstreamLoaderClient* downstream_loader_client); + DownstreamLoader(const DownstreamLoader&) = delete; + DownstreamLoader& operator=(const DownstreamLoader&) = delete; + ~DownstreamLoader() override; + + // SimpleURLLoaderStreamConsumer implementation: + void OnDataReceived(base::StringPiece string_piece, + base::OnceClosure resume) override; + void OnComplete(bool success) override; + void OnRetry(base::OnceClosure start_retry) override; + + private: + // The DownstreamLoaderClient must outlive the DownstreamLoader. + DownstreamLoaderClient* const downstream_loader_client_; + + std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_DOWNSTREAM_LOADER_H_ diff --git a/chromium/components/speech/downstream_loader_client.h b/chromium/components/speech/downstream_loader_client.h new file mode 100644 index 00000000000..3b0e07889b5 --- /dev/null +++ b/chromium/components/speech/downstream_loader_client.h @@ -0,0 +1,40 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_DOWNSTREAM_LOADER_CLIENT_H_ +#define COMPONENTS_SPEECH_DOWNSTREAM_LOADER_CLIENT_H_ + +#include "base/strings/string_piece.h" + +namespace speech { + +// An interface containing the callback functions required by consumers +// of the DownstreamLoader. The class that implements this client +// interface must outlive the DownstreamLoader. +class DownstreamLoaderClient { + public: + DownstreamLoaderClient(const DownstreamLoaderClient&) = delete; + DownstreamLoaderClient& operator=(const DownstreamLoaderClient&) = delete; + + protected: + DownstreamLoaderClient() = default; + virtual ~DownstreamLoaderClient() = default; + + private: + friend class DownstreamLoader; + + // Executed when downstream data is received. + virtual void OnDownstreamDataReceived( + base::StringPiece new_response_data) = 0; + + // Executed when downstream data is completed. + // success: True on 2xx responses where the entire body was successfully + // received. response_code: The HTTP response code if available, or -1 on + // network errors. + virtual void OnDownstreamDataComplete(bool success, int response_code) = 0; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_DOWNSTREAM_LOADER_CLIENT_H_ diff --git a/chromium/components/speech/upstream_loader.cc b/chromium/components/speech/upstream_loader.cc new file mode 100644 index 00000000000..9a88c14b6ff --- /dev/null +++ b/chromium/components/speech/upstream_loader.cc @@ -0,0 +1,129 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/speech/upstream_loader.h" + +#include "base/callback_forward.h" +#include "components/speech/upstream_loader_client.h" + +namespace speech { + +UpstreamLoader::UpstreamLoader( + std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + UpstreamLoaderClient* upstream_loader_client) + : upstream_loader_client_(upstream_loader_client) { + DCHECK(upstream_loader_client_); + // Attach a chunked upload body. + mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter> data_remote; + receiver_set_.Add(this, data_remote.InitWithNewPipeAndPassReceiver()); + resource_request->request_body = new network::ResourceRequestBody(); + resource_request->request_body->SetToChunkedDataPipe(std::move(data_remote)); + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), upstream_traffic_annotation); + simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory, + base::BindOnce(&UpstreamLoader::OnComplete, base::Unretained(this))); +} + +UpstreamLoader::~UpstreamLoader() = default; + +// Attempts to send more of the upload body, if more data is available, and +// |upload_pipe_| is valid. +void UpstreamLoader::SendData() { + DCHECK_LE(upload_position_, upload_body_.size()); + + if (!upload_pipe_.is_valid()) + return; + + // Nothing more to write yet, or done writing everything. + if (upload_position_ == upload_body_.size()) + return; + + // Since kMaxUploadWrite is a uint32_t, no overflow occurs in this downcast. + uint32_t write_bytes = std::min(upload_body_.length() - upload_position_, + static_cast<size_t>(kMaxUploadWrite)); + MojoResult result = + upload_pipe_->WriteData(upload_body_.data() + upload_position_, + &write_bytes, MOJO_WRITE_DATA_FLAG_NONE); + + // Wait for the pipe to have more capacity available, if needed. + if (result == MOJO_RESULT_SHOULD_WAIT) { + upload_pipe_watcher_->ArmOrNotify(); + return; + } + + // Do nothing on pipe closure - depend on the SimpleURLLoader to notice the + // other pipes being closed on error. Can reach this point if there's a + // retry, for instance, so cannot draw any conclusions here. + if (result != MOJO_RESULT_OK) + return; + + upload_position_ += write_bytes; + // If more data is available, arm the watcher again. Don't write again in a + // loop, even if WriteData would allow it, to avoid blocking the current + // thread. + if (upload_position_ < upload_body_.size()) + upload_pipe_watcher_->ArmOrNotify(); +} + +void UpstreamLoader::AppendChunkToUpload(const std::string& data, + bool is_last_chunk) { + DCHECK(!has_last_chunk_); + + upload_body_ += data; + if (is_last_chunk) { + // Send size before the rest of the body. While it doesn't matter much, if + // the other side receives the size before the last chunk, which Mojo does + // not guarantee, some protocols can merge the data and the last chunk + // itself into a single frame. + has_last_chunk_ = is_last_chunk; + if (get_size_callback_) + std::move(get_size_callback_).Run(net::OK, upload_body_.size()); + } + + SendData(); +} + +void UpstreamLoader::OnUploadPipeWriteable(MojoResult unused) { + SendData(); +} + +void UpstreamLoader::OnComplete(std::unique_ptr<std::string> response_body) { + int response_code = -1; + if (simple_url_loader_->ResponseInfo() && + simple_url_loader_->ResponseInfo()->headers) { + response_code = + simple_url_loader_->ResponseInfo()->headers->response_code(); + } + upstream_loader_client_->OnUpstreamDataComplete(response_body != nullptr, + response_code); +} + +void UpstreamLoader::GetSize(GetSizeCallback get_size_callback) { + if (has_last_chunk_) { + std::move(get_size_callback).Run(net::OK, upload_body_.size()); + } else { + get_size_callback_ = std::move(get_size_callback); + } +} + +void UpstreamLoader::StartReading(mojo::ScopedDataPipeProducerHandle pipe) { + // Delete any existing pipe, if any. + upload_pipe_watcher_.reset(); + upload_pipe_ = std::move(pipe); + upload_pipe_watcher_ = std::make_unique<mojo::SimpleWatcher>( + FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL); + upload_pipe_watcher_->Watch( + upload_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + base::BindRepeating(&UpstreamLoader::OnUploadPipeWriteable, + base::Unretained(this))); + upload_position_ = 0; + + // Will attempt to start sending the request body, if any data is available. + SendData(); +} + +} // namespace speech diff --git a/chromium/components/speech/upstream_loader.h b/chromium/components/speech/upstream_loader.h new file mode 100644 index 00000000000..7f80e04cda4 --- /dev/null +++ b/chromium/components/speech/upstream_loader.h @@ -0,0 +1,77 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_UPSTREAM_LOADER_H_ +#define COMPONENTS_SPEECH_UPSTREAM_LOADER_H_ + +#include <memory> +#include <string> + +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/chunked_data_pipe_getter.mojom.h" + +namespace speech { + +class UpstreamLoaderClient; + +// Maximum amount of data written per Mojo write. +const uint32_t kMaxUploadWrite = 128 * 1024; + +// Streams sound data up to the server. Buffers entire request body into memory, +// so it can be replayed in the case of redirects or retries. +class UpstreamLoader : public network::mojom::ChunkedDataPipeGetter { + public: + UpstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request, + net::NetworkTrafficAnnotationTag upstream_traffic_annotation, + network::mojom::URLLoaderFactory* url_loader_factory, + UpstreamLoaderClient* upstream_loader_client); + UpstreamLoader(const UpstreamLoader&) = delete; + UpstreamLoader& operator=(const UpstreamLoader&) = delete; + ~UpstreamLoader() override; + + void SendData(); + + void AppendChunkToUpload(const std::string& data, bool is_last_chunk); + + private: + void OnUploadPipeWriteable(MojoResult unused); + void OnComplete(std::unique_ptr<std::string> response_body); + + // mojom::ChunkedDataPipeGetter implementation: + void GetSize(GetSizeCallback get_size_callback) override; + void StartReading(mojo::ScopedDataPipeProducerHandle pipe) override; + + // Partial upload body. Have to cache the entire thing in memory, in case have + // to replay it. + std::string upload_body_; + + // Current position in |upload_body_|. All bytes before this point have been + // written to |upload_pipe_|. + size_t upload_position_ = 0; + + // Whether |upload_body_| is complete. + bool has_last_chunk_ = false; + + // Current pipe being used to send the |upload_body_| to the URLLoader. + mojo::ScopedDataPipeProducerHandle upload_pipe_; + + // Watches |upload_pipe_| for writeability. + std::unique_ptr<mojo::SimpleWatcher> upload_pipe_watcher_; + + // If non-null, invoked once the size of the upload is known. + network::mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback_; + + // The UpstreamLoaderClient must outlive the UpstreamLoader. + UpstreamLoaderClient* const upstream_loader_client_; + + std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; + mojo::ReceiverSet<network::mojom::ChunkedDataPipeGetter> receiver_set_; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_UPSTREAM_LOADER_H_ diff --git a/chromium/components/speech/upstream_loader_client.h b/chromium/components/speech/upstream_loader_client.h new file mode 100644 index 00000000000..dcc51f7358d --- /dev/null +++ b/chromium/components/speech/upstream_loader_client.h @@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SPEECH_UPSTREAM_LOADER_CLIENT_H_ +#define COMPONENTS_SPEECH_UPSTREAM_LOADER_CLIENT_H_ + +namespace speech { + +// An interface containing the callback functions required by consumers +// of the UpstreamLoader. The class that implements this client +// interface must outlive the UpstreamLoader. +class UpstreamLoaderClient { + public: + UpstreamLoaderClient(const UpstreamLoaderClient&) = delete; + UpstreamLoaderClient& operator=(const UpstreamLoaderClient&) = delete; + + protected: + UpstreamLoaderClient() = default; + virtual ~UpstreamLoaderClient() = default; + + private: + friend class UpstreamLoader; + + // Executed when upstream data is completed. + // success: True on 2xx responses. + // response_code: The HTTP response code if available, or -1 on + // network errors. + virtual void OnUpstreamDataComplete(bool success, int response_code) = 0; +}; + +} // namespace speech + +#endif // COMPONENTS_SPEECH_UPSTREAM_LOADER_CLIENT_H_ |