Skip to content

Commit

Permalink
Support exposing Mojo services between render frames, render threads,…
Browse files Browse the repository at this point in the history
… and their respective hosts.

This introduces ServiceRegistry as an abstraction around providing
services to and accessing services from a remote peer. In particular,
this adds peered service registries to RenderProcessHost and
RenderThread, and to RenderFrameHost and RenderFrame - the RenderFrame
setup is implemented using the RenderProcessHost/RenderThread
ServiceRegistry pair.

This replaces the existing WebUI handle setup by adding a webUI
controller service to the frame host registry and a corresponding
request for the webUI controller service to the frame registry.

BUG=386155

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=279557

Review URL: https://codereview.chromium.org/285333003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279623 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
sammc@chromium.org committed Jun 25, 2014
1 parent e07862b commit c52a141
Show file tree
Hide file tree
Showing 63 changed files with 485 additions and 303 deletions.
19 changes: 13 additions & 6 deletions chrome/browser/ui/webui/mojo_web_ui_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@

#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/mojo_web_ui_handler.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/service_registry.h"
#include "mojo/public/cpp/system/core.h"

MojoWebUIController::MojoWebUIController(content::WebUI* contents)
: WebUIController(contents),
mojo_data_source_(NULL) {
: WebUIController(contents), mojo_data_source_(NULL), weak_factory_(this) {
}

MojoWebUIController::~MojoWebUIController() {
Expand All @@ -22,10 +24,10 @@ MojoWebUIController::~MojoWebUIController() {
void MojoWebUIController::RenderViewCreated(
content::RenderViewHost* render_view_host) {
render_view_host->AllowBindings(content::BINDINGS_POLICY_WEB_UI);

mojo::MessagePipe pipe;
ui_handler_ = CreateUIHandler(pipe.handle0.Pass());
render_view_host->SetWebUIHandle(pipe.handle1.Pass());
render_view_host->GetMainFrame()->GetServiceRegistry()->AddService(
"webui_controller",
base::Bind(&MojoWebUIController::CreateAndStoreUIHandler,
weak_factory_.GetWeakPtr()));
}

void MojoWebUIController::AddMojoResourcePath(const std::string& path,
Expand All @@ -36,3 +38,8 @@ void MojoWebUIController::AddMojoResourcePath(const std::string& path,
}
mojo_data_source_->AddResourcePath(path, resource_id);
}

void MojoWebUIController::CreateAndStoreUIHandler(
mojo::ScopedMessagePipeHandle handle) {
ui_handler_ = CreateUIHandler(handle.Pass());
}
6 changes: 6 additions & 0 deletions chrome/browser/ui/webui/mojo_web_ui_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string>

#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_ui_controller.h"
#include "mojo/public/cpp/system/core.h"

Expand Down Expand Up @@ -42,11 +43,16 @@ class MojoWebUIController : public content::WebUIController {
mojo::ScopedMessagePipeHandle handle_to_page) = 0;

private:
// Invoked in response to a connection from the renderer.
void CreateAndStoreUIHandler(mojo::ScopedMessagePipeHandle handle);

// Bindings files are registered here.
content::WebUIDataSource* mojo_data_source_;

scoped_ptr<MojoWebUIHandler> ui_handler_;

base::WeakPtrFactory<MojoWebUIController> weak_factory_;

DISALLOW_COPY_AND_ASSIGN(MojoWebUIController);
};

Expand Down
2 changes: 2 additions & 0 deletions chrome/chrome_tests_unit.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@
'common',
'test_support_common',
'../base/base.gyp:base',
'../mojo/mojo.gyp:mojo_environment_chromium',
'../mojo/mojo.gyp:mojo_system_impl',
'../skia/skia.gyp:skia',
'../sync/sync.gyp:sync',
'../testing/gmock.gyp:gmock',
Expand Down
1 change: 1 addition & 0 deletions chrome/test/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ include_rules = [

"+grit", # For generated headers
"+media/base",
"+mojo/embedder",
"+sandbox/win/tests",
"+webkit/glue",
"+win8/test",
Expand Down
2 changes: 2 additions & 0 deletions chrome/test/base/run_all_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
#include "base/test/launcher/unit_test_launcher.h"
#include "chrome/test/base/chrome_unit_test_suite.h"
#include "content/public/test/unittest_test_suite.h"
#include "mojo/embedder/embedder.h"

int main(int argc, char **argv) {
content::UnitTestTestSuite test_suite(new ChromeUnitTestSuite(argc, argv));

mojo::embedder::Init();
return base::LaunchUnitTests(
argc, argv, base::Bind(&content::UnitTestTestSuite::Run,
base::Unretained(&test_suite)));
Expand Down
2 changes: 1 addition & 1 deletion content/app/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ source_set("app") {
} else {
deps += [
"//mojo/environment:chromium",
"//mojo/public/interfaces/service_provider:service_provider",
"//mojo/public/interfaces/interface_provider",
"//mojo/service_manager",
"//mojo/system",
]
Expand Down
2 changes: 1 addition & 1 deletion content/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ source_set("browser") {
"//cc",
"//cc:cc_surfaces",
"//mojo/public/cpp/bindings",
"//mojo/public/interfaces/service_provider:service_provider",
"//mojo/public/interfaces/interface_provider",
"//mojo/public/js/bindings",
"//net:http_server",
"//third_party/icu",
Expand Down
17 changes: 17 additions & 0 deletions content/browser/frame_host/render_frame_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/input/input_router.h"
#include "content/browser/renderer_host/input/timeout_monitor.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/transition_request_manager.h"
#include "content/common/desktop_notification_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/input_messages.h"
#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/render_frame_setup.mojom.h"
#include "content/common/swapped_out_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
Expand Down Expand Up @@ -162,6 +164,16 @@ RenderFrameHostImpl::RenderFrameHostImpl(
g_routing_id_frame_map.Get().insert(std::make_pair(
RenderFrameHostID(GetProcess()->GetID(), routing_id_),
this));

if (GetProcess()->GetServiceRegistry()) {
RenderFrameSetupPtr setup;
GetProcess()->GetServiceRegistry()->GetRemoteInterface(&setup);
mojo::IInterfaceProviderPtr service_provider;
setup->GetServiceProviderForFrame(routing_id_,
mojo::Get(&service_provider));
service_registry_.BindRemoteServiceProvider(
service_provider.PassMessagePipe());
}
}

RenderFrameHostImpl::~RenderFrameHostImpl() {
Expand Down Expand Up @@ -242,6 +254,11 @@ RenderViewHost* RenderFrameHostImpl::GetRenderViewHost() {
return render_view_host_;
}

ServiceRegistry* RenderFrameHostImpl::GetServiceRegistry() {
static_cast<RenderProcessHostImpl*>(GetProcess())->EnsureMojoActivated();
return &service_registry_;
}

bool RenderFrameHostImpl::Send(IPC::Message* message) {
if (IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart) {
return render_view_host_->input_router()->SendInput(
Expand Down
4 changes: 4 additions & 0 deletions content/browser/frame_host/render_frame_host_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/common/mojo/service_registry_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/javascript_message_type.h"
#include "content/public/common/page_transition_types.h"
Expand Down Expand Up @@ -66,6 +67,7 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost {
const base::string16& javascript,
const JavaScriptResultCallback& callback) OVERRIDE;
virtual RenderViewHost* GetRenderViewHost() OVERRIDE;
virtual ServiceRegistry* GetServiceRegistry() OVERRIDE;

// IPC::Sender
virtual bool Send(IPC::Message* msg) OVERRIDE;
Expand Down Expand Up @@ -302,6 +304,8 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost {
// When the last BeforeUnload message was sent.
base::TimeTicks send_before_unload_start_time_;

ServiceRegistryImpl service_registry_;

base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;

DISALLOW_COPY_AND_ASSIGN(RenderFrameHostImpl);
Expand Down
13 changes: 2 additions & 11 deletions content/browser/mojo/mojo_application_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ MojoApplicationHost::~MojoApplicationHost() {
}

bool MojoApplicationHost::Init() {
DCHECK(!child_service_provider_.get()) << "Already initialized!";
DCHECK(!client_handle_.is_valid()) << "Already initialized!";

mojo::embedder::PlatformChannelPair channel_pair;

Expand All @@ -43,8 +43,7 @@ bool MojoApplicationHost::Init() {
// Forward this to the client once we know its process handle.
client_handle_ = channel_pair.PassClientHandle();

child_service_provider_.reset(
BindToPipe(new ServiceProviderImpl(), message_pipe.Pass()));
service_registry_.BindRemoteServiceProvider(message_pipe.Pass());
return true;
}

Expand All @@ -60,12 +59,4 @@ bool MojoApplicationHost::Activate(IPC::Sender* sender,
return did_activate_;
}

void MojoApplicationHost::ServiceProviderImpl::ConnectToService(
const mojo::String& service_url,
const mojo::String& service_name,
mojo::ScopedMessagePipeHandle handle,
const mojo::String& requestor_url) {
// TODO(darin): Provide something meaningful here.
}

} // namespace content
32 changes: 7 additions & 25 deletions content/browser/mojo/mojo_application_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#define CONTENT_BROWSER_MOJO_MOJO_APPLICATION_HOST_H_

#include "base/process/process_handle.h"
#include "content/common/mojo/service_registry_impl.h"
#include "mojo/embedder/channel_init.h"
#include "mojo/embedder/scoped_platform_handle.h"
#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"

namespace IPC {
class Sender;
Expand All @@ -19,49 +19,31 @@ namespace content {
// MojoApplicationHost represents the code needed on the browser side to setup
// a child process as a Mojo application via Chrome IPC. The child process
// should use MojoApplication to handle messages generated by an instance of
// MojoApplicationHost. MojoApplicationHost makes the mojo::ShellClient
// interface available so that child-provided services can be invoked.
// MojoApplicationHost. MojoApplicationHost makes the ServiceRegistry interface
// available so that child-provided services can be invoked.
class MojoApplicationHost {
public:
MojoApplicationHost();
virtual ~MojoApplicationHost();

// Two-phase initialization:
// 1- Init makes the shell_client() available synchronously.
// 1- Init makes service_registry() available synchronously.
// 2- Activate establishes the actual connection to the peer process.
bool Init();
bool Activate(IPC::Sender* sender, base::ProcessHandle process_handle);

bool did_activate() const { return did_activate_; }

mojo::ServiceProvider* service_provider() {
DCHECK(child_service_provider_.get());
return child_service_provider_->client();
}
ServiceRegistry* service_registry() { return &service_registry_; }

private:
class ServiceProviderImpl
: public mojo::InterfaceImpl<mojo::ServiceProvider> {
public:
virtual void OnConnectionError() OVERRIDE {
// TODO(darin): How should we handle this error?
}

// mojo::ServiceProvider methods:
virtual void ConnectToService(
const mojo::String& service_url,
const mojo::String& service_name,
mojo::ScopedMessagePipeHandle handle,
const mojo::String& requestor_url) OVERRIDE;
};

mojo::embedder::ChannelInit channel_init_;
mojo::embedder::ScopedPlatformHandle client_handle_;

scoped_ptr<ServiceProviderImpl> child_service_provider_;

bool did_activate_;

ServiceRegistryImpl service_registry_;

DISALLOW_COPY_AND_ASSIGN(MojoApplicationHost);
};

Expand Down
23 changes: 10 additions & 13 deletions content/browser/renderer_host/render_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
#include "content/browser/media/midi_host.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/mime_registry_message_filter.h"
#include "content/browser/mojo/mojo_application_host.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/profiler_message_filter.h"
#include "content/browser/push_messaging_message_filter.h"
Expand Down Expand Up @@ -141,7 +140,6 @@
#include "ipc/ipc_logging.h"
#include "ipc/ipc_switches.h"
#include "media/base/media_switches.h"
#include "mojo/common/common_type_converters.h"
#include "net/url_request/url_request_context_getter.h"
#include "ppapi/shared_impl/ppapi_switches.h"
#include "third_party/skia/include/core/SkBitmap.h"
Expand Down Expand Up @@ -448,6 +446,7 @@ RenderProcessHostImpl::RenderProcessHostImpl(
is_self_deleted_(false),
#endif
pending_views_(0),
mojo_application_host_(new MojoApplicationHost),
mojo_activation_required_(false),
visible_widgets_(0),
backgrounded_(true),
Expand Down Expand Up @@ -597,7 +596,6 @@ bool RenderProcessHostImpl::Init() {
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get());

// Setup the Mojo channel.
mojo_application_host_.reset(new MojoApplicationHost());
mojo_application_host_->Init();

// Call the embedder first so that their IPC filters have priority.
Expand Down Expand Up @@ -908,6 +906,12 @@ void RenderProcessHostImpl::NotifyTimezoneChange() {
Send(new ViewMsg_TimezoneChange());
}

ServiceRegistry* RenderProcessHostImpl::GetServiceRegistry() {
if (!mojo_application_host_)
return NULL;
return mojo_application_host_->service_registry();
}

void RenderProcessHostImpl::AddRoute(
int32 routing_id,
IPC::Listener* listener) {
Expand Down Expand Up @@ -1933,7 +1937,8 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead) {
iter.Advance();
}

mojo_application_host_.reset();
mojo_application_host_.reset(new MojoApplicationHost);
mojo_activation_required_ = false;

// It's possible that one of the calls out to the observers might have caused
// this object to be no longer needed.
Expand Down Expand Up @@ -2253,17 +2258,9 @@ void RenderProcessHostImpl::DecrementWorkerRefCount() {
Cleanup();
}

void RenderProcessHostImpl::ConnectTo(
const base::StringPiece& service_name,
mojo::ScopedMessagePipeHandle handle) {
void RenderProcessHostImpl::EnsureMojoActivated() {
mojo_activation_required_ = true;
MaybeActivateMojo();

mojo_application_host_->service_provider()->ConnectToService(
mojo::String::From(service_name),
std::string(),
handle.Pass(),
mojo::String());
}

void RenderProcessHostImpl::OnAllocateGpuMemoryBuffer(uint32 width,
Expand Down
Loading

0 comments on commit c52a141

Please sign in to comment.