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

Side by Side Diff: extensions/renderer/resources/media_router_bindings.js

Issue 1162243002: Add Media Router JS Gin module. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Devlin's feedback. Created 5 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
« no previous file with comments | « extensions/renderer/resources/extensions_renderer_resources.grd ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 var mediaRouterObserver;
6
7 define('media_router_bindings', [
8 'mojo/public/js/bindings',
9 'mojo/public/js/core',
10 'content/public/renderer/service_provider',
11 'chrome/browser/media/router/media_router.mojom',
12 'extensions/common/mojo/keep_alive.mojom',
13 'mojo/public/js/connection',
14 'mojo/public/js/router',
15 ], function(bindings,
16 core,
17 serviceProvider,
18 mediaRouterMojom,
19 keepAliveMojom,
20 connector,
21 routerModule) {
22 'use strict';
23
24 /**
25 * Converts a sink object to a MediaSink Mojo object.
26 * @param {!Object} sink
Devlin 2015/06/08 19:51:42 Can we {!MediaSink} this?
Kevin M 2015/06/08 22:36:04 Done.
27 * @return {!mediaRouterMojom.MediaSink}
28 */
29 function sinkToMojo_(function(sink) {
Devlin 2015/06/08 19:51:42 This line appears broken - "function(sink)"
Kevin M 2015/06/08 22:36:03 Done.
30 return new mediaRouterMojom.MediaSink({
31 'name': sink.friendlyName,
32 'sink_id': sink.id,
33 });
34 }
35
36 /**
37 * Converts a route struct to its Mojo form.
38 * @param {!MediaRoute} route
39 * @param {!string=} opt_sinkName
40 * @return {!mojo.MediaRoute}
41 */
42 function routeToMojo_(route, opt_sinkName) {
43 return new mediaRouterMojom.MediaRoute({
44 'media_route_id': route.id,
45 'media_source': route.mediaSource,
46 'media_sink': new mediaRouterMojom.MediaSink({
47 'sink_id': route.sinkId,
48 'name': opt_sinkName,
49 }),
50 'description': route.description,
51 'icon_url': route.iconUrl,
52 'is_local': route.isLocal
53 });
54 }
55
56 /**
57 * @param {!MediaRouterService} service
58 * @constructor
59 */
60 function MediaRouterObserver(service) {
61 /**
62 * The Mojo service proxy. Allows extension code to call methods that reside
63 * in the browser.
64 * @type {!MediaRouterService}
65 */
66 this.service_ = service;
67
68 /**
69 * The MRPM service delegate. Its methods are called by the browser-resident
70 * Mojo service.
71 * @type {!MediaRouter}
72 */
73 this.mrpm_ = new MediaRouter(this);
74
75 /**
76 * The message pipe that connects the Media Router to mrpm_ across
77 * browser/renderer IPC boundaries.
78 * Object must remain in scope for the lifetime of the connection to
79 * prevent the connection from closing automatically.
80 * @type {!mojo.MessagePipe}
81 */
82 this.pipe_ = core.createMessagePipe();
83
84 /**
85 * Handle to a KeepAlive service object, which prevents the extension from
86 * being suspended as long as it remains in scope
87 * @type {boolean}
88 */
89 this.keepAlive_ = null;
90
91 /**
92 * Define the stub used to bind this.mrpm_ to the Mojo interface.
93 * Object must remain in scope for the lifetime of the connection to
94 * prevent the connection from closing automatically.
95 * @type {!mojom.MediaRouter}
96 */
97 this.mediaRouterStub_ = connector.bindHandleToStub(
98 this.pipe_.handle0, mediaRouterMojom.MediaRouter);
99
100 // Link the stub to impl code.
101 bindings.StubBindings(this.mediaRouterStub_).delegate = this.mrpm_;
102 }
103
104 /**
105 * Registers the Media Router Provider Manager with the Media Router.
106 * @return {!Promise<string>} A unique, string-based ID for this instance
107 * of the Media Router.
108 */
109 MediaRouterObserver.prototype.start = function() {
110 return this.service_.provideMediaRouter(this.pipe_.handle1).then(
111 function(result) {
112 return result.instance_id;
113 }.bind(this));
114 }
115
116 /**
117 * Sets the service delegate methods.
118 * @param {Object} handlers
119 */
120 MediaRouterObserver.prototype.setHandlers = function(handlers) {
121 this.mrpm_.setHandlers(handlers);
122 }
123
124 /**
125 * Gets the keep alive status.
126 * @return {boolean}
127 */
128 MediaRouterObserver.prototype.getKeepAlive = function() {
129 return this.keepAlive_ != null;
130 };
131
132 /**
133 * Called by the Provider Manager when a sink list for a given source is
134 * updated.
135 * @param {!string} sourceUrn
136 * @param {!Array<!Object>} sinks
Devlin 2015/06/08 19:51:42 here, too, MediaSink?
Kevin M 2015/06/08 22:36:03 Done.
137 */
138 MediaRouterObserver.prototype.onSinksReceived = function(sourceUrn, sinks) {
139 this.service_.onSinksReceived(sourceUrn,
140 sinks.map(sinkToMojo_));
141 };
142
143 /**
144 * Called by the Provider Manager to keep the extension from suspending
145 * if it enters a state where suspension is undesirable (e.g. there is an
146 * active MediaRoute.)
147 * If keepAlive is true, the extension is kept alive.
148 * If keepAlive is false, the extension is allowed to suspend.
149 * @param {boolean} keepAlive
150 */
151 MediaRouterObserver.prototype.setKeepAlive = function(keepAlive) {
152 if (keepAlive === false && this.keepAlive_) {
153 this.keepAlive_.close();
154 this.keepAlive_ = null;
155 } else if (keepAlive === true && !this.keepAlive_) {
156 this.keepAlive_ = new routerModule.Router(
157 serviceProvider.connectToService(
158 keepAliveMojom.KeepAlive.name));
159 }
160 };
161
162 /**
163 * Sends a message to an active media route.
164 * @param {!string} routeId
165 * @param {!Object|string} message A message that can be converted to a JSON
166 * string.
167 */
168 MediaRouterObserver.prototype.onMessage = function(routeId, message) {
169 this.service_.onMessage(routeId, JSON.stringify(message));
170 };
171
172 /**
173 * Reports an issue to the Media Router.
174 * @param {!Object} issue
175 */
176 MediaRouterObserver.prototype.onIssue = function(issue) {
177 function issueSeverityToMojo_(severity) {
178 switch (severity) {
179 case 'fatal':
180 return mediaRouterMojom.Issue.Severity.FATAL;
181 case 'warning':
182 return mediaRouterMojom.Issue.Severity.WARNING;
183 case 'notification':
184 return mediaRouterMojom.Issue.Severity.NOTIFICATION;
185 default:
186 console.error('Unknown issue severity: ' + severity);
187 return mediaRouterMojom.Issue.Severity.NOTIFICATION;
188 }
189 }
190
191 function issueActionToMojo_(action) {
192 switch (action) {
193 case 'ok':
194 return mediaRouterMojom.Issue.ActionType.OK;
195 case 'cancel':
196 return mediaRouterMojom.Issue.ActionType.CANCEL;
197 case 'dismiss':
198 return mediaRouterMojom.Issue.ActionType.DISMISS;
199 case 'learn_more':
200 return mediaRouterMojom.Issue.ActionType.LEARN_MORE;
201 default:
202 console.error('Unknown issue action type : ' + action);
203 return mediaRouterMojom.Issue.ActionType.OK;
204 }
205 }
206
207 var secondaryActions = (issue.secondaryActions || []).map(function(e) {
208 return issueActionToMojo_(e);
209 });
210 this.service_.onIssue(new mediaRouterMojom.Issue({
211 'route_id': issue.routeId,
212 'severity': issueSeverityToMojo_(issue.severity),
213 'title': issue.title,
214 'message': issue.message,
215 'default_action': issueActionToMojo_(issue.defaultAction),
216 'secondary_actions': secondaryActions,
217 'help_url': issue.helpUrl,
218 'is_blocking': issue.isBlocking
219 }));
220 };
221
222 /**
223 * Called by the Provider Manager when the list of active routes
224 * has changed.
225 * @param {!Array<MediaRoute>} routes
226 * @param {!Array<MediaSink>} sinks
227 */
228 MediaRouterObserver.prototype.onRoutesUpdated = function(routes, sinks) {
229 // Create an inverted index relating sink IDs to their names.
230 var sinkNameMap = {};
231 for (var i = 0; i < sinks.length; i++) {
232 sinkNameMap[sinks[i].id] = sinks[i].friendlyName;
233 }
234
235 // Convert MediaRoutes to Mojo objects and add their sink names
236 // via sinkNameMap.
237 var mojoRoutes = [];
238 for (var j = 0; j < routes.length; j++) {
239 mojoRoutes.push(routeToMojo_(routes[j], sinkNameMap[routes[j].sinkId]));
240 }
241
242 this.service_.onRoutesUpdated(
243 mojoRoutes,
244 sinks.map(MediaRouterObserver.sinkToMojo_));
245 };
246
247 /**
248 * Called by the Provider Manager when an error was encountered for a media
249 * route.
250 * @param {!string} requestId The ID of the route request which experienced an
251 * error.
252 * @param {!string} error
253 */
254 MediaRouterObserver.prototype.onRouteResponseError =
255 function(requestId, error) {
256 this.service_.onRouteResponseError(requestId, error);
257 };
258
259 MediaRouterObserver.prototype.onRouteResponseReceived =
260 function(requestId, routeId) {
261 this.service_.onRouteResponseReceived(requestId, routeId);
262 };
263
264 /**
265 * Object containing JS callbacks into Provider Manager code.
266 * @constructor
267 * @struct
268 */
269 function MediaRouterHandlers() {
270 /**
271 * @type {function(!string, !string, !string=, !string=, !number=}
272 */
273 this.createRoute = null;
274
275 /**
276 * @type {function(!string, !string, !string, !number)}
277 */
278 this.joinRoute = null;
279
280 /**
281 * @type {function(string)}
282 */
283 this.closeRoute = null;
284
285 /**
286 * @type {function(string)}
287 */
288 this.startObservingMediaSinks = null;
289
290 /**
291 * @type {function(string)}
292 */
293 this.stopObservingMediaSinks = null;
294
295 /**
296 * @type {function(string, string, string)}
297 */
298 this.postMessage = null;
299
300 /**
301 * @type {function()}
302 */
303 this.startObservingMediaRoutes = null;
304
305 /**
306 * @type {function()}
307 */
308 this.stopObservingMediaRoutes = null;
309 };
310
311 /**
312 * Routes calls from Media Router to the Provider Manager extension.
313 * Registered with the MediaRouter stub.
314 * @constructor
315 */
316 function MediaRouter(mediaRouterObserver) {
317 /**
318 * Object containing JS callbacks into Provider Manager code.
319 * @type {!MediaRouterHandlers}
320 */
321 this.handlers_ = new MediaRouterHandlers();
322
323 /**
324 * Proxy class to the browser's Media Router Mojo service.
325 * @type {!MediaRouterObserver}
326 */
327 this.mediaRouter_ = mediaRouterObserver;
328 }
329 MediaRouter.prototype = Object.create(
330 mediaRouterMojom.MediaRouter.stubClass.prototype);
331
332 /*
333 * Sets the callback handler used to invoke methods in the Provider Manager.
334 * @param {!MediaRouterHandlers} handlers
335 */
336 MediaRouter.prototype.setHandlers = function(handlers) {
337 this.handlers_ = handlers;
338 var requiredHandlers = [
339 'stopObservingMediaRoutes',
340 'startObservingMediaRoutes',
341 'postMessage',
342 'closeRoute',
343 'joinRoute',
344 'createRoute',
345 'stopObservingMediaSinks',
346 'startObservingMediaRoutes'
347 ];
348 var error = false;
349 requiredHandlers.forEach(function(nextHandler) {
350 if (!handlers.hasOwnProperty(nextHandler)) {
351 console.error(nextHandler + ' handler not registered.');
352 error = true;
353 }
354 });
355 if (error) {
Devlin 2015/06/08 19:51:42 why is this needed?
Kevin M 2015/06/08 22:36:04 To increase the LoC count. <_< Removed.
356 return;
357 }
358 }
359
360 /**
361 * Starts querying for sinks capable of displaying the media |sourceUrn|.
362 * Results are returned by calling OnSinksReceived.
363 * @param {!string} sourceUrn
364 */
365 MediaRouter.prototype.startObservingMediaSinks =
366 function(sourceUrn) {
367 this.handlers_.startObservingMediaSinks(sourceUrn);
368 };
369
370 /**
371 * Stops querying for sinks capable of displaying the media |sourceUrn|.
372 * @param {!string} sourceUrn
373 */
374 MediaRouter.prototype.stopObservingMediaSinks =
375 function(sourceUrn) {
376 this.handlers_.stopObservingMediaSinks(sourceUrn);
377 };
378
379 /**
380 * Requests that |sinkId| render the media referenced by |sourceUrn|.
381 * @param {!string} sourceUrn
382 * @param {!string} sinkId
383 * @param {!string=} opt_presentationId
384 * @param {!string=} opt_origin
385 * @param {!number=} opt_tabId
386 * @return {!Promise.<!Object>}
387 */
388 MediaRouter.prototype.createRoute =
389 function(sourceUrn, sinkId, opt_presentationId, opt_origin, opt_tabId) {
390 return this.handlers_.createRoute(
391 sourceUrn, sinkId, opt_presentationId, opt_origin, opt_tabId)
392 .then(function(route) {
393 // Sink name is not used, so it is omitted here.
394 return {route: routeToMojo_(route, "")};
395 }.bind(this))
396 .catch(function(err) {
397 return {error_text: err.message};
398 });
399 };
400
401 /**
402 * Join an existing route given by |presentationId| and render media
403 * referenced by |sourceUrn|. |origin| and |tabId| are used for checking
404 * origin/tab scope.
405 * @param {!string} sourceUrn
406 * @param {!string} presentationId
407 * @param {!string} origin
408 * @param {!number} tabId
409 * @return {!Promise.<!Object>} Resolved with the route on success,
410 * or with an error message on failure.
411 */
412 MediaRouter.prototype.joinRoute =
413 function(sourceUrn, presentationId, origin, tabId) {
414 return this.handlers_.joinRoute(sourceUrn, presentationId, origin, tabId)
415 .then(function(newRoute) {
416 return {route: routeToMojo_(newRoute)};
417 },
418 function(err) {
419 return {error_text: 'Error joining route: ' + err.message};
420 });
421 };
422
423 /**
424 * Closes route specified by |routeId|
425 * @param {!string} routeId
426 */
427 MediaRouter.prototype.closeRoute = function(routeId) {
428 this.handlers_.closeRoute(routeId);
429 };
430
431 /**
432 * Posts message to a sink connected by route with |routeId|.
433 * @param {!string} routeId
434 * @param {!string} message
435 * @param {string} extraInfoJson
436 */
437 MediaRouter.prototype.postMessage = function(
438 routeId, message, extraInfoJson) {
439 this.handlers_.postMessage(routeId, message, JSON.parse(extraInfoJson));
440 };
441
442 /**
443 * Requests that the Provider Manager start sending information about active
444 * media routes to the Media Router.
445 */
446 MediaRouter.prototype.startObservingMediaRoutes = function() {
447 this.handlers_.startObservingMediaRoutes();
448 };
449
450 /**
451 * Requests that the Provider Manager stop sending information about active
452 * media routes to the Media Router.
453 */
454 MediaRouter.prototype.stopObservingMediaRoutes = function() {
455 this.handlers_.stopObservingMediaRoutes();
456 };
457
458 mediaRouterObserver = new MediaRouterObserver(connector.bindHandleToProxy(
459 serviceProvider.connectToService(
460 mediaRouterMojom.MediaRouterObserver.name),
461 mediaRouterMojom.MediaRouterObserver));
462
463 return mediaRouterObserver;
464 });
465
OLDNEW
« no previous file with comments | « extensions/renderer/resources/extensions_renderer_resources.grd ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698