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

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