summaryrefslogtreecommitdiff
path: root/chromium/components/speech
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/speech
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-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.gn22
-rw-r--r--chromium/components/speech/DEPS4
-rw-r--r--chromium/components/speech/downstream_loader.cc48
-rw-r--r--chromium/components/speech/downstream_loader.h46
-rw-r--r--chromium/components/speech/downstream_loader_client.h40
-rw-r--r--chromium/components/speech/upstream_loader.cc129
-rw-r--r--chromium/components/speech/upstream_loader.h77
-rw-r--r--chromium/components/speech/upstream_loader_client.h34
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_