blob: 697e36cf1f42b99521ad6aa23f8f47b7f04717e1 [file] [log] [blame]
// 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 "base/macros.h"
#include "content/public/browser/service_process_host.h"
#include "content/public/test/content_browser_test.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/data_decoder/public/cpp/data_decoder.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;
class ServiceProcessObserver : public ServiceProcessHost::Observer {
public:
ServiceProcessObserver() { ServiceProcessHost::AddObserver(this); }
~ServiceProcessObserver() override {
ServiceProcessHost::RemoveObserver(this);
}
int instances_started() const { return instances_started_; }
void WaitForNextLaunch() {
launch_wait_loop_.emplace();
launch_wait_loop_->Run();
}
void OnServiceProcessLaunched(const ServiceProcessInfo& info) override {
if (info.IsService<data_decoder::mojom::DataDecoderService>()) {
++instances_started_;
if (launch_wait_loop_)
launch_wait_loop_->Quit();
}
}
private:
base::Optional<base::RunLoop> launch_wait_loop_;
int instances_started_ = 0;
DISALLOW_COPY_AND_ASSIGN(ServiceProcessObserver);
};
IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, Launch) {
ServiceProcessObserver observer;
// Verifies that the DataDecoder client object launches a service process as
// needed.
data_decoder::DataDecoder decoder;
// |GetService()| must always ensure a connection to the service on all
// platforms, so we use it instead of a more specific API whose behavior may
// vary across platforms.
decoder.GetService();
observer.WaitForNextLaunch();
EXPECT_EQ(1, observer.instances_started());
}
IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, LaunchIsolated) {
ServiceProcessObserver observer;
// Verifies that separate DataDecoder client objects will launch separate
// service processes. We also bind a JsonParser interface to ensure that the
// instances don't go idle.
data_decoder::DataDecoder decoder1;
mojo::Remote<data_decoder::mojom::JsonParser> parser1;
decoder1.GetService()->BindJsonParser(parser1.BindNewPipeAndPassReceiver());
observer.WaitForNextLaunch();
EXPECT_EQ(1, observer.instances_started());
data_decoder::DataDecoder decoder2;
mojo::Remote<data_decoder::mojom::JsonParser> parser2;
decoder2.GetService()->BindJsonParser(parser2.BindNewPipeAndPassReceiver());
observer.WaitForNextLaunch();
EXPECT_EQ(2, observer.instances_started());
// Both interfaces should be connected end-to-end.
parser1.FlushForTesting();
parser2.FlushForTesting();
EXPECT_TRUE(parser1.is_connected());
EXPECT_TRUE(parser2.is_connected());
}
} // namespace content