Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: headless/lib/renderer/headless_content_renderer_client.cc

Issue 2049363003: Adds support for headless chrome embedder mojo services (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added a TODO Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "headless/lib/renderer/headless_content_renderer_client.h" 5 #include "headless/lib/renderer/headless_content_renderer_client.h"
6 6
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/public/renderer/render_frame.h"
9
7 namespace headless { 10 namespace headless {
8 11
9 HeadlessContentRendererClient::HeadlessContentRendererClient() {} 12 HeadlessContentRendererClient::HeadlessContentRendererClient() {}
10 13
11 HeadlessContentRendererClient::~HeadlessContentRendererClient() {} 14 HeadlessContentRendererClient::~HeadlessContentRendererClient() {}
12 15
16 void HeadlessContentRendererClient::RunScriptsAtDocumentStart(
17 content::RenderFrame* render_frame) {
18 render_frame->ExecuteJavaScript(base::UTF8ToUTF16(R"(
dcheng 2016/06/21 14:52:10 Raw string literals are still banned AFAIK.
alex clarke (OOO till 29th) 2016/06/21 16:15:17 Ah so they are :/ I got confused because they are
19 // Shim to let code use define() instead of mojo.define()
20 window.define = (function() {
21 let moduleCache = new Map();
22 return function(name, deps, factory) {
23 let promise = moduleCache.get(name);
24 if (promise === undefined) {
25 // This promise must be cached as mojo.define will only call the
26 // factory function the first time the module is defined.
27 promise = new Promise(resolve => {
28 mojo.define(name, deps, (...modules) => {
29 let result = factory(...modules);
30 return result;
31 });
32 });
33 moduleCache.set(name, promise);
34 }
35 return promise;
36 }
37 })();
38
39 // This code is run before the browser has sent us the mojo bindings so
40 // we need to get fancy and use nested proxy classes to define a promise
41 // to an arbitary window.mojo.services.myModule.myInterface.
42 if (window.hasOwnProperty("mojo")) {
43 let mojoBindings = new Map();
44 let resolvePending = true;
45
46 // Factory for returning the second level dynamic property which
47 // resolves to a promise to the corresponding mojo interface...
48 let interfaceProxyFactory = function(serviceName) {
49 return new Proxy({}, {
50 get: function(target, interfaceName) {
51 let name = serviceName + "::" + interfaceName;
52 let binding = mojoBindings.get(name);
53 if (binding === undefined) {
54 binding = {};
55 binding.promise = new Promise(function(resolve, reject) {
56 binding.resolve = resolve;
57 binding.reject = reject;
58 if (!resolvePending)
59 reject();
60 });
61 mojoBindings.set(name, binding);
62 }
63 return binding.promise;
64 },
65 set: function(target, name, value) {
66 throw new Error(
67 'Assignment to the mojo services proxy is not allowed');
68 }
69 });
70 };
71
72 // Top level dynamic property.
73 window.mojo.services = new Proxy({}, {
74 get: function(target, serviceName) {
75 if (!(serviceName in target)) {
76 let interfaceProxy = interfaceProxyFactory(serviceName);
77 target[serviceName] = interfaceProxy;
78 return interfaceProxy;
79 }
80 return target[serviceName];
81 },
82 set: function(target, name, value) {
83 throw new Error(
84 'Assignment to the mojo services proxy is not allowed');
85 }
86 });
87
88 // Resolve promises for the listed |serviceNames|.
89 window.mojo.resolvePromisesForServices_ = function(serviceNames) {
90 let numServices = serviceNames.length;
91 for (let i = 0; i < numServices; ++i) {
92 let serviceName = serviceNames[i];
93 // Use mojo to obtain the module binding.
94 define([
95 serviceName,
96 "mojo/public/js/core",
97 "mojo/public/js/router",
98 "content/public/renderer/frame_service_registry",
99 ], function(serviceMojom, mojoCore, routerModule,
100 serviceProvider) {
101 // A mojom binding may contain bindings for a number of
102 // interfaces. Iterate through all of them and resolve any
103 // promises.
104 for (let m in serviceMojom) {
105 if (typeof serviceMojom[m] == "object") {
106 let service = serviceMojom[m];
107 let binding = mojoBindings.get(service.name);
108 let interface = new service.proxyClass(
109 new routerModule.Router(
110 serviceProvider.connectToService(service.name)));
111 if (binding === undefined) {
112 // Store resolved promise in case binding is requested.
113 mojoBindings.set(
114 service.name, {"promise": Promise.resolve(interface)});
115 } else {
116 binding.resolve(interface);
117 // Since this promise has been resolved we don't want to try
118 // and reject it below!
119 delete binding.reject;
120 }
121 }
122 }
123 });
124 }
125 // Reject any remaining promises that didn't get resolved.
126 for (let [key, value] of mojoBindings) {
127 if ("reject" in value) {
128 value.reject();
129 }
130 }
131 // Reject any subsequent unknown properties.
132 resolvePending = false;
133 };
134 } )"));
135 }
136
13 } // namespace headless 137 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698