0

Make Data Decoder service available without Service Manager

This makes it possible to launch new instances of the Data Decoder
service without going through Service Manager APIs. The service is also
still accessible through Service Manager, as this allows the many
disparate clients across the tree to be ported incrementally.

Bug: 977637
Change-Id: I0d534ed1fb9a0ef7545533ad435b010789cccd9f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869383
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#708477}
This commit is contained in:
Ken Rockot
2019-10-23 03:04:18 +00:00
committed by Commit Bot
parent d2ff24ecbe
commit 2130dffdde
13 changed files with 198 additions and 42 deletions

@ -673,6 +673,7 @@ jumbo_source_set("browser") {
"cookie_store/cookie_store_host.h",
"cookie_store/cookie_store_manager.cc",
"cookie_store/cookie_store_manager.h",
"data_decoder/data_decoder_service.cc",
"data_url_loader_factory.cc",
"data_url_loader_factory.h",
"devtools/browser_devtools_agent_host.cc",

@ -0,0 +1 @@
file://services/data_decoder/OWNERS

@ -0,0 +1,19 @@
// Copyright 2019 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 "content/public/browser/data_decoder_service.h"
#include "content/public/browser/service_process_host.h"
namespace content {
mojo::Remote<data_decoder::mojom::DataDecoderService> LaunchDataDecoder() {
return ServiceProcessHost::Launch<data_decoder::mojom::DataDecoderService>(
ServiceProcessHost::Options()
.WithSandboxType(service_manager::SANDBOX_TYPE_UTILITY)
.WithDisplayName("Data Decoder Service")
.Pass());
}
} // namespace content

@ -0,0 +1,46 @@
// Copyright 2019 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 "content/public/browser/data_decoder_service.h"
#include "base/test/bind_test_util.h"
#include "base/values.h"
#include "content/public/test/content_browser_test.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/data_decoder/public/mojom/data_decoder_service.mojom.h"
#include "services/data_decoder/public/mojom/json_parser.mojom.h"
namespace content {
using DataDecoderBrowserTest = ContentBrowserTest;
IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, Launch) {
// Simple smoke test to verify that we can launch an instance of the Data
// Decoder service and communicate end-to-end.
mojo::Remote<data_decoder::mojom::DataDecoderService> service =
LaunchDataDecoder();
mojo::Remote<data_decoder::mojom::JsonParser> parser;
service->BindJsonParser(parser.BindNewPipeAndPassReceiver());
base::RunLoop loop;
parser->Parse(
R"({"a": 5, "b": 42})",
base::BindLambdaForTesting([&](base::Optional<base::Value> result,
const base::Optional<std::string>& error) {
EXPECT_FALSE(error);
ASSERT_TRUE(result);
EXPECT_EQ(base::Value::Type::DICTIONARY, result->type());
auto* a = result->FindKey("a");
EXPECT_TRUE(a);
EXPECT_EQ(5, a->GetInt());
auto* b = result->FindKey("b");
EXPECT_TRUE(b);
EXPECT_EQ(42, b->GetInt());
loop.Quit();
}));
loop.Run();
}
} // namespace content

@ -129,6 +129,7 @@ jumbo_source_set("browser_sources") {
"cors_exempt_headers.h",
"cors_origin_pattern_setter.cc",
"cors_origin_pattern_setter.h",
"data_decoder_service.h",
"desktop_capture.cc",
"desktop_capture.h",
"desktop_media_id.cc",
@ -414,6 +415,7 @@ jumbo_source_set("browser_sources") {
"//media/mojo/mojom:remoting",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
"//services/data_decoder/public/mojom",
"//services/device/public/mojom:usb",
"//services/media_session/public/cpp",
"//services/media_session/public/mojom",

@ -5,6 +5,7 @@ include_rules = [
"+components/viz/common",
"+components/viz/host",
"+device/fido",
"+services/data_decoder/public",
"+services/device/public",
"+services/media_session/public",
"+services/metrics/public/cpp",

@ -0,0 +1,24 @@
// Copyright 2019 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 CONTENT_PUBLIC_BROWSER_DATA_DECODER_SERVICE_H_
#define CONTENT_PUBLIC_BROWSER_DATA_DECODER_SERVICE_H_
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/data_decoder/public/mojom/data_decoder_service.mojom.h"
namespace content {
// Launches a new isolated instance of the Data Decoder service. This instance
// will live as long as the returned Remote is kept alive and bound. Instances
// can be used to batch multiple decoding operations, but callers should be wary
// of sending data from multiple untrusted sources to the same instance.
CONTENT_EXPORT mojo::Remote<data_decoder::mojom::DataDecoderService>
LaunchDataDecoder();
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_DATA_DECODER_SERVICE_H_

@ -897,6 +897,7 @@ test("content_browsertests") {
"../browser/content_index/content_index_browsertest.cc",
"../browser/content_service_browsertest.cc",
"../browser/cross_site_transfer_browsertest.cc",
"../browser/data_decoder/data_decoder_service_browsertest.cc",
"../browser/database_browsertest.cc",
"../browser/device_sensors/device_sensor_browsertest.cc",
"../browser/devtools/devtools_video_consumer_browsertest.cc",

@ -9,8 +9,10 @@
#include "base/no_destructor.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/utility/content_utility_client.h"
#include "content/public/utility/utility_thread.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/bindings/service_factory.h"
#include "services/data_decoder/data_decoder_service.h"
#include "services/network/network_service.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/video_capture/public/mojom/video_capture_service.mojom.h"
@ -29,6 +31,13 @@ auto RunNetworkService(
/*delay_initialization_until_set_client=*/true);
}
auto RunDataDecoder(
mojo::PendingReceiver<data_decoder::mojom::DataDecoderService> receiver) {
UtilityThread::Get()->EnsureBlinkInitialized();
return std::make_unique<data_decoder::DataDecoderService>(
std::move(receiver));
}
auto RunVideoCapture(
mojo::PendingReceiver<video_capture::mojom::VideoCaptureService> receiver) {
return std::make_unique<video_capture::VideoCaptureServiceImpl>(
@ -44,6 +53,7 @@ mojo::ServiceFactory& GetIOThreadServiceFactory() {
mojo::ServiceFactory& GetMainThreadServiceFactory() {
static base::NoDestructor<mojo::ServiceFactory> factory{
RunDataDecoder,
RunVideoCapture,
};
return *factory;

@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/data_decoder/bundled_exchanges_parser_factory.h"
#include "services/data_decoder/image_decoder_impl.h"
@ -30,52 +31,47 @@ constexpr auto kMaxServiceIdleTime = base::TimeDelta::FromSeconds(5);
} // namespace
DataDecoderService::DataDecoderService()
: keepalive_(&binding_, kMaxServiceIdleTime) {
registry_.AddInterface(base::BindRepeating(
&DataDecoderService::BindImageDecoder, base::Unretained(this)));
registry_.AddInterface(base::BindRepeating(
&DataDecoderService::BindJsonParser, base::Unretained(this)));
registry_.AddInterface(base::BindRepeating(&DataDecoderService::BindXmlParser,
base::Unretained(this)));
registry_.AddInterface(base::BindRepeating(
&DataDecoderService::BindBundledExchangesParserFactory,
base::Unretained(this)));
: keepalive_(&binding_, kMaxServiceIdleTime) {}
#ifdef OS_CHROMEOS
registry_.AddInterface(base::BindRepeating(
&DataDecoderService::BindBleScanParser, base::Unretained(this)));
#endif // OS_CHROMEOS
DataDecoderService::DataDecoderService(
mojo::PendingReceiver<service_manager::mojom::Service> receiver)
: DataDecoderService() {
binding_.Bind(std::move(receiver));
}
DataDecoderService::DataDecoderService(
service_manager::mojom::ServiceRequest request)
mojo::PendingReceiver<mojom::DataDecoderService> receiver)
: DataDecoderService() {
BindRequest(std::move(request));
receiver_.Bind(std::move(receiver));
}
DataDecoderService::~DataDecoderService() = default;
void DataDecoderService::BindRequest(
service_manager::mojom::ServiceRequest request) {
binding_.Bind(std::move(request));
void DataDecoderService::BindReceiver(
mojo::PendingReceiver<mojom::DataDecoderService> receiver) {
receiver_.Bind(std::move(receiver));
}
void DataDecoderService::OnBindInterface(
const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
registry_.BindInterface(interface_name, std::move(interface_pipe));
mojo::GenericPendingReceiver receiver(interface_name,
std::move(interface_pipe));
if (auto r = receiver.As<mojom::ImageDecoder>())
BindImageDecoder(std::move(r));
else if (auto r = receiver.As<mojom::JsonParser>())
BindJsonParser(std::move(r));
else if (auto r = receiver.As<mojom::XmlParser>())
BindXmlParser(std::move(r));
else if (auto r = receiver.As<mojom::BundledExchangesParserFactory>())
BindBundledExchangesParserFactory(std::move(r));
#if defined(OS_CHROMEOS)
else if (auto r = receiver.As<mojom::BleScanParser>())
BindBleScanParser(std::move(r));
#endif
}
#ifdef OS_CHROMEOS
void DataDecoderService::BindBleScanParser(
mojo::PendingReceiver<mojom::BleScanParser> receiver) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<BleScanParserImpl>(keepalive_.CreateRef()),
std::move(receiver));
}
#endif // OS_CHROMEOS
void DataDecoderService::BindImageDecoder(
mojo::PendingReceiver<mojom::ImageDecoder> receiver) {
mojo::MakeSelfOwnedReceiver(
@ -103,4 +99,13 @@ void DataDecoderService::BindBundledExchangesParserFactory(
std::move(receiver));
}
#ifdef OS_CHROMEOS
void DataDecoderService::BindBleScanParser(
mojo::PendingReceiver<mojom::BleScanParser> receiver) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<BleScanParserImpl>(keepalive_.CreateRef()),
std::move(receiver));
}
#endif // OS_CHROMEOS
} // namespace data_decoder

@ -9,11 +9,12 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "services/data_decoder/public/mojom/bundled_exchanges_parser.mojom.h"
#include "services/data_decoder/public/mojom/data_decoder_service.mojom.h"
#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
#include "services/data_decoder/public/mojom/json_parser.mojom.h"
#include "services/data_decoder/public/mojom/xml_parser.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_binding.h"
#include "services/service_manager/public/cpp/service_keepalive.h"
@ -25,35 +26,45 @@
namespace data_decoder {
class DataDecoderService : public service_manager::Service {
class DataDecoderService : public service_manager::Service,
public mojom::DataDecoderService {
public:
DataDecoderService();
explicit DataDecoderService(service_manager::mojom::ServiceRequest request);
explicit DataDecoderService(
mojo::PendingReceiver<service_manager::mojom::Service> receiver);
explicit DataDecoderService(
mojo::PendingReceiver<mojom::DataDecoderService> receiver);
~DataDecoderService() override;
// May be used to establish a latent Service binding for this instance. May
// only be called once, and only if this instance was default-constructed.
void BindRequest(service_manager::mojom::ServiceRequest request);
// May be used to establish a latent DataDecoderService binding for this
// instance. May only be called once, and only if this instance was default-
// constructed.
void BindReceiver(mojo::PendingReceiver<mojom::DataDecoderService> receiver);
// service_manager::Service:
// service_manager::Service implementation:
void OnBindInterface(const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
private:
// mojom::DataDecoderService implementation:
void BindImageDecoder(
mojo::PendingReceiver<mojom::ImageDecoder> receiver) override;
void BindJsonParser(
mojo::PendingReceiver<mojom::JsonParser> receiver) override;
void BindXmlParser(mojo::PendingReceiver<mojom::XmlParser> receiver) override;
void BindBundledExchangesParserFactory(
mojo::PendingReceiver<mojom::BundledExchangesParserFactory> receiver);
void BindImageDecoder(mojo::PendingReceiver<mojom::ImageDecoder> receiver);
void BindJsonParser(mojo::PendingReceiver<mojom::JsonParser> receiver);
void BindXmlParser(mojo::PendingReceiver<mojom::XmlParser> receiver);
mojo::PendingReceiver<mojom::BundledExchangesParserFactory> receiver)
override;
#ifdef OS_CHROMEOS
void BindBleScanParser(mojo::PendingReceiver<mojom::BleScanParser> receiver);
void BindBleScanParser(
mojo::PendingReceiver<mojom::BleScanParser> receiver) override;
#endif // OS_CHROMEOS
service_manager::ServiceBinding binding_{this};
service_manager::ServiceKeepalive keepalive_;
service_manager::BinderRegistry registry_;
mojo::Receiver<mojom::DataDecoderService> receiver_{this};
DISALLOW_COPY_AND_ASSIGN(DataDecoderService);
};

@ -7,6 +7,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
sources = [
"bundled_exchanges_parser.mojom",
"data_decoder_service.mojom",
"image_decoder.mojom",
"json_parser.mojom",
"xml_parser.mojom",

@ -0,0 +1,34 @@
// Copyright 2019 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.
module data_decoder.mojom;
import "services/data_decoder/public/mojom/bundled_exchanges_parser.mojom";
import "services/data_decoder/public/mojom/image_decoder.mojom";
import "services/data_decoder/public/mojom/json_parser.mojom";
import "services/data_decoder/public/mojom/xml_parser.mojom";
[EnableIf=is_chromeos]
import "services/data_decoder/public/mojom/ble_scan_parser.mojom";
// The main interface to the Data Decoder service.
interface DataDecoderService {
// Binds an interface which can be used to decode compressed image data.
BindImageDecoder(pending_receiver<ImageDecoder> receiver);
// Binds an interface which can be used to parse JSON data.
BindJsonParser(pending_receiver<JsonParser> receiver);
// Binds an interface which can be used to parse XML data.
BindXmlParser(pending_receiver<XmlParser> reciever);
// Binds an interface which can be used to parse bundled HTTP exchanges.
BindBundledExchangesParserFactory(
pending_receiver<BundledExchangesParserFactory> receiver);
// Binds an interface which can be used to parse raw BLE advertising packet
// data.
[EnableIf=is_chromeos]
BindBleScanParser(pending_receiver<BleScanParser> receiver);
};