Commit 84566c47 authored by Oksana Zhuravlova's avatar Oksana Zhuravlova Committed by Commit Bot

[remoteobjects] Add blink module remote_objects

This CL adds the RemoteObjectGateway mojom interface and its
implementation in a new blink module. Follow-up CLs will add
communicating object deletion to the browser and handling method
invocation.

Bug: 794320
Change-Id: Icad078513d1b3d8449feab77e3ac0f2169307432
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1918187Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Oksana Zhuravlova <oksamyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723464}
parent 71da435d
......@@ -17,7 +17,9 @@ import "mojo/public/mojom/base/string16.mojom";
//
// Identifiers used by this object apply only within this RemoteObjectHost.
interface RemoteObjectHost {
GetObject(int32 object_id, RemoteObject& request);
// Binds |receiver| to an implementation of RemoteObject corresponding to
// |object_id|.
GetObject(int32 object_id, pending_receiver<RemoteObject> receiver);
// Ideally lifetime would be scoped to an associated RemoteObject pipe. This
// is complicated by the fact that the missing support for associated
......@@ -34,6 +36,23 @@ interface RemoteObject {
=> (RemoteInvocationResult result);
};
// Implemented in the renderer.
interface RemoteObjectGatewayFactory {
// Creates an implementation of RemoteObjectGateway associated with |host|
// and binds it to |gateway|.
CreateRemoteObjectGateway(pending_remote<RemoteObjectHost> host,
pending_receiver<RemoteObjectGateway> gateway);
};
// Implemented in the renderer.
interface RemoteObjectGateway {
// Exposes object with |name| and |id| to the frame.
AddNamedObject(string name, int32 object_id);
// Removes object with |name| from the frame context.
RemoveNamedObject(string name);
};
enum SingletonJavaScriptValue {
kNull,
kUndefined,
......
......@@ -129,6 +129,7 @@ jumbo_component("modules") {
"//third_party/blink/renderer/modules/push_messaging",
"//third_party/blink/renderer/modules/quota",
"//third_party/blink/renderer/modules/remoteplayback",
"//third_party/blink/renderer/modules/remote_objects",
"//third_party/blink/renderer/modules/scheduler",
"//third_party/blink/renderer/modules/screen_enumeration",
"//third_party/blink/renderer/modules/screen_orientation",
......
......@@ -68,6 +68,7 @@
#include "third_party/blink/renderer/modules/presentation/presentation_controller.h"
#include "third_party/blink/renderer/modules/presentation/presentation_receiver.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_client.h"
#include "third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h"
#include "third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h"
#include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h"
#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h"
......@@ -169,6 +170,8 @@ void ModulesInitializer::InitLocalFrame(LocalFrame& frame) const {
&AppBannerController::BindMojoRequest, WrapWeakPersistent(&frame)));
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
&TextSuggestionBackendImpl::Create, WrapWeakPersistent(&frame)));
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
&RemoteObjectGatewayFactoryImpl::Create, WrapWeakPersistent(&frame)));
}
void ModulesInitializer::InstallSupplements(LocalFrame& frame) const {
......@@ -249,6 +252,11 @@ void ModulesInitializer::OnClearWindowObjectInMainWorld(
// presentation can offer a connection to the presentation receiver.
PresentationReceiver::From(document);
}
LocalFrame* frame = document.GetFrame();
DCHECK(frame);
if (auto* gateway = RemoteObjectGatewayImpl::From(*frame))
gateway->OnClearWindowObjectInMainWorld();
}
std::unique_ptr<WebMediaPlayer> ModulesInitializer::CreateWebMediaPlayer(
......
# 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.
import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("remote_objects") {
sources = [
"remote_object.cc",
"remote_object.h",
"remote_object_gateway_impl.cc",
"remote_object_gateway_impl.h",
]
}
// 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 "third_party/blink/renderer/modules/remote_objects/remote_object.h"
namespace blink {
gin::WrapperInfo RemoteObject::kWrapperInfo = {gin::kEmbedderNativeGin};
RemoteObject::RemoteObject(v8::Isolate* isolate,
RemoteObjectGatewayImpl* gateway,
int32_t object_id)
: gin::NamedPropertyInterceptor(isolate, this),
gateway_(gateway),
object_id_(object_id) {}
gin::ObjectTemplateBuilder RemoteObject::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<RemoteObject>::GetObjectTemplateBuilder(isolate)
.AddNamedPropertyInterceptor();
}
v8::Local<v8::Value> RemoteObject::GetNamedProperty(
v8::Isolate* isolate,
const std::string& property) {
// TODO(crbug.com/794320): implement this.
ignore_result(object_id_);
return v8::Local<v8::Value>();
}
std::vector<std::string> RemoteObject::EnumerateNamedProperties(
v8::Isolate* isolate) {
// TODO(crbug.com/794320): implement this.
return std::vector<std::string>();
}
} // namespace blink
// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_H_
#include "gin/handle.h"
#include "gin/interceptor.h"
#include "gin/object_template_builder.h"
#include "gin/wrappable.h"
#include "third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
// Gin wrapper for representing objects that could be injected by the browser.
// Recreated every time the window object is cleared.
class RemoteObject : public gin::Wrappable<RemoteObject>,
public gin::NamedPropertyInterceptor {
public:
static gin::WrapperInfo kWrapperInfo;
RemoteObject(v8::Isolate*, RemoteObjectGatewayImpl*, int32_t);
// Not copyable or movable
RemoteObject(const RemoteObject&) = delete;
RemoteObject& operator=(const RemoteObject&) = delete;
~RemoteObject() override = default;
// gin::Wrappable.
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
// gin::NamedPropertyInterceptor
v8::Local<v8::Value> GetNamedProperty(v8::Isolate* isolate,
const std::string& property) override;
std::vector<std::string> EnumerateNamedProperties(
v8::Isolate* isolate) override;
private:
WeakPersistent<RemoteObjectGatewayImpl> gateway_{nullptr};
int32_t object_id_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_H_
// 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 "third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/modules/remote_objects/remote_object.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
namespace blink {
// static
const char RemoteObjectGatewayImpl::kSupplementName[] = "RemoteObjectGateway";
// static
RemoteObjectGatewayImpl* RemoteObjectGatewayImpl::From(LocalFrame& frame) {
return Supplement<LocalFrame>::From<RemoteObjectGatewayImpl>(frame);
}
void RemoteObjectGatewayImpl::InjectNamed(const WTF::String& object_name,
int32_t object_id) {
// TODO(crbug.com/794320): implement this.
ScriptState* script_state = ToScriptStateForMainWorld(GetSupplementable());
ScriptState::Scope scope(script_state);
v8::Isolate* isolate = script_state->GetIsolate();
v8::Local<v8::Context> context = script_state->GetContext();
if (context.IsEmpty())
return;
RemoteObject* object = new RemoteObject(isolate, this, object_id);
v8::Context::Scope context_scope(context);
v8::Local<v8::Object> global = context->Global();
gin::Handle<RemoteObject> controller = gin::CreateHandle(isolate, object);
// WrappableBase instance deletes itself in case of a wrapper
// creation failure, thus there is no need to delete |object|.
if (controller.IsEmpty())
return;
global->Set(context, V8AtomicString(isolate, object_name), controller.ToV8())
.Check();
}
// static
void RemoteObjectGatewayImpl::BindMojoReceiver(
LocalFrame* frame,
mojo::PendingRemote<mojom::blink::RemoteObjectHost> host,
mojo::PendingReceiver<mojom::blink::RemoteObjectGateway> receiver) {
if (!frame)
return;
DCHECK(!RemoteObjectGatewayImpl::From(*frame));
auto* self = MakeGarbageCollected<RemoteObjectGatewayImpl>(
util::PassKey<RemoteObjectGatewayImpl>(), *frame, std::move(receiver),
std::move(host));
Supplement<LocalFrame>::ProvideTo(*frame, self);
}
RemoteObjectGatewayImpl::RemoteObjectGatewayImpl(
util::PassKey<RemoteObjectGatewayImpl>,
LocalFrame& frame,
mojo::PendingReceiver<mojom::blink::RemoteObjectGateway>
object_gateway_receiver,
mojo::PendingRemote<mojom::blink::RemoteObjectHost> object_host_remote)
: Supplement<LocalFrame>(frame),
receiver_(this, std::move(object_gateway_receiver)),
object_host_(std::move(object_host_remote)) {}
void RemoteObjectGatewayImpl::OnClearWindowObjectInMainWorld() {
for (const auto& pair : named_objects_)
InjectNamed(pair.key, pair.value);
}
void RemoteObjectGatewayImpl::Dispose() {
receiver_.reset();
}
void RemoteObjectGatewayImpl::AddNamedObject(const WTF::String& name,
int32_t id) {
// Added objects only become available after page reload, so here they
// are only added into the internal map.
named_objects_.insert(name, id);
}
void RemoteObjectGatewayImpl::RemoveNamedObject(const WTF::String& name) {
// Removal becomes in effect on next reload. We simply remove the entry
// from the map here.
auto iter = named_objects_.find(name);
DCHECK(iter != named_objects_.end());
named_objects_.erase(iter);
}
// static
void RemoteObjectGatewayFactoryImpl::Create(
LocalFrame* frame,
mojo::PendingReceiver<mojom::blink::RemoteObjectGatewayFactory> receiver) {
mojo::MakeSelfOwnedReceiver(std::unique_ptr<RemoteObjectGatewayFactoryImpl>(
new RemoteObjectGatewayFactoryImpl(*frame)),
std::move(receiver));
}
RemoteObjectGatewayFactoryImpl::RemoteObjectGatewayFactoryImpl(
LocalFrame& frame)
: frame_(frame) {}
void RemoteObjectGatewayFactoryImpl::CreateRemoteObjectGateway(
mojo::PendingRemote<mojom::blink::RemoteObjectHost> host,
mojo::PendingReceiver<mojom::blink::RemoteObjectGateway> receiver) {
RemoteObjectGatewayImpl::BindMojoReceiver(frame_, std::move(host),
std::move(receiver));
}
} // namespace blink
// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_GATEWAY_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_GATEWAY_IMPL_H_
#include "base/util/type_safety/pass_key.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "third_party/blink/public/mojom/remote_objects/remote_objects.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
class MODULES_EXPORT RemoteObjectGatewayImpl
: public GarbageCollected<RemoteObjectGatewayImpl>,
public Supplement<LocalFrame>,
public mojom::blink::RemoteObjectGateway {
USING_GARBAGE_COLLECTED_MIXIN(RemoteObjectGatewayImpl);
USING_PRE_FINALIZER(RemoteObjectGatewayImpl, Dispose);
public:
static const char kSupplementName[];
RemoteObjectGatewayImpl(
util::PassKey<RemoteObjectGatewayImpl>,
LocalFrame&,
mojo::PendingReceiver<mojom::blink::RemoteObjectGateway>,
mojo::PendingRemote<mojom::blink::RemoteObjectHost>);
// Not copyable or movable
RemoteObjectGatewayImpl(const RemoteObjectGatewayImpl&) = delete;
RemoteObjectGatewayImpl& operator=(const RemoteObjectGatewayImpl&) = delete;
~RemoteObjectGatewayImpl() override = default;
void Dispose();
static void BindMojoReceiver(
LocalFrame*,
mojo::PendingRemote<mojom::blink::RemoteObjectHost>,
mojo::PendingReceiver<mojom::blink::RemoteObjectGateway>);
// This supplement is only installed if the RemoteObjectGateway mojom
// interface is requested to be bound (currently only for Android WebView).
static RemoteObjectGatewayImpl* From(LocalFrame&);
void OnClearWindowObjectInMainWorld();
void Trace(Visitor* visitor) override {
Supplement<LocalFrame>::Trace(visitor);
}
private:
// mojom::blink::RemoteObjectGateway
void AddNamedObject(const WTF::String& name, int32_t id) override;
void RemoveNamedObject(const WTF::String& name) override;
void InjectNamed(const WTF::String& object_name, int32_t object_id);
HashMap<String, int32_t> named_objects_;
mojo::Receiver<mojom::blink::RemoteObjectGateway> receiver_;
mojo::Remote<mojom::blink::RemoteObjectHost> object_host_;
};
class RemoteObjectGatewayFactoryImpl
: public mojom::blink::RemoteObjectGatewayFactory {
public:
static void Create(
LocalFrame* frame,
mojo::PendingReceiver<mojom::blink::RemoteObjectGatewayFactory> receiver);
private:
explicit RemoteObjectGatewayFactoryImpl(LocalFrame& frame);
// Not copyable or movable
RemoteObjectGatewayFactoryImpl(const RemoteObjectGatewayFactoryImpl&) =
delete;
RemoteObjectGatewayFactoryImpl& operator=(
const RemoteObjectGatewayFactoryImpl&) = delete;
// mojom::blink::RemoteObjectGatewayFactory
void CreateRemoteObjectGateway(
mojo::PendingRemote<mojom::blink::RemoteObjectHost> host,
mojo::PendingReceiver<mojom::blink::RemoteObjectGateway> receiver)
override;
WeakPersistent<LocalFrame> frame_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_GATEWAY_IMPL_H_
......@@ -751,6 +751,16 @@ _CONFIG = [
'indexed_db::.+',
],
},
{
'paths': [
'third_party/blink/renderer/modules/remote_objects/',
],
'allowed': [
'gin::.+',
# gin::NamedPropertyInterceptor uses std::vector.
'std::vector',
],
},
{
'paths': [
'third_party/blink/renderer/modules/webgpu/',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment