Commit effe3e76 authored by jarhar's avatar jarhar Committed by Commit bot

Add Mojo JavaScript support for Chromecast

BUG=647036

Review-Url: https://codereview.chromium.org/2342563003
Cr-Commit-Position: refs/heads/master@{#419364}
parent 929a0aa4
......@@ -8,6 +8,8 @@ source_set("renderer") {
sources = [
"cast_content_renderer_client.cc",
"cast_content_renderer_client.h",
"cast_gin_runner.cc",
"cast_gin_runner.h",
"cast_media_load_deferrer.cc",
"cast_media_load_deferrer.h",
"key_systems_cast.cc",
......@@ -34,9 +36,11 @@ source_set("renderer") {
"//chromecast/media",
"//components/cdm/renderer",
"//components/network_hints/renderer",
"//content:resources_grit",
"//content/public/common",
"//content/public/renderer",
"//crypto",
"//gin:gin",
"//ipc",
"//media",
"//services/shell/public/cpp",
......
......@@ -4,12 +4,15 @@ include_rules = [
"+chromecast/media",
"+components/cdm/renderer",
"+components/network_hints/renderer",
"+content/grit",
"+content/public/common",
"+content/public/renderer",
"+gin",
"+media/base",
"+media/media_features.h",
"+media/renderers",
"+services/shell/public",
"+third_party/WebKit/public/platform",
"+third_party/WebKit/public/web",
"+ui/base/resource",
]
......@@ -5,28 +5,38 @@
#include "chromecast/renderer/cast_content_renderer_client.h"
#include <stdint.h>
#include <string>
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chromecast/base/chromecast_switches.h"
#include "chromecast/common/media/cast_media_client.h"
#include "chromecast/crash/cast_crash_keys.h"
#include "chromecast/renderer/cast_gin_runner.h"
#include "chromecast/renderer/cast_media_load_deferrer.h"
#include "chromecast/renderer/key_systems_cast.h"
#include "chromecast/renderer/media/media_caps_observer_impl.h"
#include "components/network_hints/renderer/prescient_networking_dispatcher.h"
#include "content/grit/content_resources.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "gin/modules/module_registry.h"
#include "gin/per_context_data.h"
#include "gin/public/context_holder.h"
#include "media/base/media.h"
#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebColor.h"
#include "third_party/WebKit/public/web/WebFrameWidget.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebSettings.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_ANDROID)
#include "media/base/android/media_codec_util.h"
......@@ -128,5 +138,44 @@ void CastContentRendererClient::DeferMediaLoad(
new CastMediaLoadDeferrer(render_frame, closure);
}
void CastContentRendererClient::RunScriptsAtDocumentStart(
content::RenderFrame* render_frame) {
// This method enables Mojo bindings in JavaScript for Chromecast.
v8::HandleScope handle_scope(blink::mainThreadIsolate());
v8::Local<v8::Context> context =
render_frame->GetWebFrame()->mainWorldScriptContext();
// CastGinRunner manages its own lifetime.
CastGinRunner* runner = new CastGinRunner(render_frame);
gin::Runner::Scope scoper(runner);
// Initialize AMD API for Mojo.
render_frame->EnsureMojoBuiltinsAreAvailable(context->GetIsolate(), context);
gin::ModuleRegistry::InstallGlobals(context->GetIsolate(), context->Global());
// Inject JavaScript files in the correct dependency order.
static const int mojo_resource_ids[] = {
IDR_MOJO_UNICODE_JS,
IDR_MOJO_BUFFER_JS,
IDR_MOJO_CODEC_JS,
IDR_MOJO_CONNECTOR_JS,
IDR_MOJO_VALIDATOR_JS,
IDR_MOJO_ROUTER_JS,
IDR_MOJO_BINDINGS_JS,
IDR_MOJO_CONNECTION_JS,
};
for (size_t i = 0; i < arraysize(mojo_resource_ids); i++) {
ExecuteJavaScript(render_frame, mojo_resource_ids[i]);
}
}
void ExecuteJavaScript(content::RenderFrame* render_frame, int resource_id) {
const std::string& js_string = ui::ResourceBundle::GetSharedInstance()
.GetRawDataResource(resource_id)
.as_string();
render_frame->ExecuteJavaScript(base::UTF8ToUTF16(js_string));
}
} // namespace shell
} // namespace chromecast
......@@ -25,6 +25,10 @@ class MediaCapsObserverImpl;
}
namespace shell {
class CastGinRunner;
class CastRenderThreadObserver;
void ExecuteJavaScript(content::RenderFrame* render_frame, int resourceId);
class CastContentRendererClient : public content::ContentRendererClient {
public:
......@@ -44,6 +48,7 @@ class CastContentRendererClient : public content::ContentRendererClient {
void DeferMediaLoad(content::RenderFrame* render_frame,
bool render_frame_has_played_media_before,
const base::Closure& closure) override;
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override;
protected:
CastContentRendererClient();
......
// Copyright 2016 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 "chromecast/renderer/cast_gin_runner.h"
#include "content/public/renderer/render_frame.h"
#include "gin/per_context_data.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
namespace chromecast {
namespace shell {
CastGinRunner::CastGinRunner(content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame),
frame_(render_frame->GetWebFrame()),
context_holder_(
gin::PerContextData::From(frame_->mainWorldScriptContext())
->context_holder()) {
DCHECK(frame_);
DCHECK(context_holder_);
gin::PerContextData* context_data =
gin::PerContextData::From(frame_->mainWorldScriptContext());
v8::Isolate::Scope isolate_scope(context_holder_->isolate());
v8::HandleScope handle_scope(context_holder_->isolate());
context_data->SetUserData(kCastContextData, this);
// Note: this installs the runner globally. If we need to support more than
// one runner at a time we'll have to revisit this.
context_data->set_runner(this);
}
CastGinRunner::~CastGinRunner() {
RemoveUserData(render_frame()->GetWebFrame()->mainWorldScriptContext());
}
void CastGinRunner::Run(const std::string& source,
const std::string& resource_name) {
frame_->executeScript(
blink::WebScriptSource(blink::WebString::fromUTF8(source)));
}
v8::Local<v8::Value> CastGinRunner::Call(v8::Local<v8::Function> function,
v8::Local<v8::Value> receiver,
int argc,
v8::Local<v8::Value> argv[]) {
return frame_->callFunctionEvenIfScriptDisabled(function, receiver, argc,
argv);
}
gin::ContextHolder* CastGinRunner::GetContextHolder() {
return context_holder_;
}
void CastGinRunner::WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) {
RemoveUserData(context);
}
void CastGinRunner::DidClearWindowObject() {
RemoveUserData(render_frame()->GetWebFrame()->mainWorldScriptContext());
}
void CastGinRunner::OnDestruct() {
RemoveUserData(render_frame()->GetWebFrame()->mainWorldScriptContext());
}
void CastGinRunner::RemoveUserData(v8::Local<v8::Context> context) {
gin::PerContextData* context_data = gin::PerContextData::From(context);
if (!context_data)
return;
context_data->RemoveUserData(kCastContextData);
}
} // namespace shell
} // namespace chromecast
// Copyright 2016 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 CHROMECAST_RENDERER_CAST_GIN_RUNNER_H_
#define CHROMECAST_RENDERER_CAST_GIN_RUNNER_H_
#include "base/macros.h"
#include "base/supports_user_data.h"
#include "content/public/renderer/render_frame_observer.h"
#include "gin/runner.h"
namespace {
const char kCastContextData[] = "CastContextData";
}
namespace blink {
class WebFrame;
}
namespace chromecast {
namespace shell {
// Implementation of gin::Runner that forwards Runner functions to WebFrame.
class CastGinRunner : public gin::Runner,
public base::SupportsUserData::Data,
public content::RenderFrameObserver {
public:
// Does not take ownership of ContextHolder.
CastGinRunner(content::RenderFrame* render_frame);
~CastGinRunner() override;
// gin:Runner implementation:
void Run(const std::string& source,
const std::string& resource_name) override;
v8::Local<v8::Value> Call(v8::Local<v8::Function> function,
v8::Local<v8::Value> receiver,
int argc,
v8::Local<v8::Value> argv[]) override;
gin::ContextHolder* GetContextHolder() override;
// content::RenderFrameObserver implementation:
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void DidClearWindowObject() override;
void OnDestruct() override;
private:
void RemoveUserData(v8::Local<v8::Context> context);
// Frame to execute script in.
blink::WebFrame* const frame_;
// Created by blink bindings to V8.
gin::ContextHolder* const context_holder_;
DISALLOW_COPY_AND_ASSIGN(CastGinRunner);
};
} // namespace shell
} // namespace chromecast
#endif // CHROMECAST_RENDERER_CAST_GIN_RUNNER_H_
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