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

Unified 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, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/resources/extensions_renderer_resources.grd ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/resources/media_router_bindings.js
diff --git a/extensions/renderer/resources/media_router_bindings.js b/extensions/renderer/resources/media_router_bindings.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6f19163d633fc536433b20737dc15f96b8bb5f4
--- /dev/null
+++ b/extensions/renderer/resources/media_router_bindings.js
@@ -0,0 +1,503 @@
+// Copyright 2015 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.
+
+var mediaRouterObserver;
+
+define('media_router_bindings', [
+ 'mojo/public/js/bindings',
+ 'mojo/public/js/core',
+ 'content/public/renderer/service_provider',
+ 'chrome/browser/media/router/media_router.mojom',
+ 'extensions/common/mojo/keep_alive.mojom',
+ 'mojo/public/js/connection',
+ 'mojo/public/js/router',
+], function(bindings,
+ core,
+ serviceProvider,
+ mediaRouterMojom,
+ keepAliveMojom,
+ connector,
+ routerModule) {
+ 'use strict';
+
+
+ /**
+ * Converts a sink object to a MediaSink Mojo object.
+ * @param {Object} sink
haibinlu 2015/06/02 17:54:15 !Object
Kevin M 2015/06/02 18:29:38 Done.
+ * @return {mediaRouterMojom.MediaSink}
haibinlu 2015/06/02 17:54:15 !mediaRouterMojom.MediaSink
Kevin M 2015/06/02 18:29:38 Done.
+ */
+ function sinkToMojo_(function(sink) {
+ return new mediaRouterMojom.MediaSink({
+ 'name': sink.friendlyName,
+ 'sink_id': sink.id,
+ });
+ }
+
+
+ /**
+ * Converts a route struct to its Mojo form.
+ *
+ * @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.
+ * @param {string} opt_sinkName
+ * @return {mojo.MediaRoute}
+ */
+ function routeToMojo_(route, opt_sinkName) {
+ return new mediaRouterMojom.MediaRoute({
+ 'media_route_id': route.id,
+ 'media_source': route.mediaSource,
+ '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
+ 'sink_id': route.sinkId,
+ 'name': opt_sinkName,
+ }),
+ 'description': route.description,
+ 'icon_url': route.iconUrl,
+ 'is_local': route.isLocal
+ });
+ }
+
+ /**
+ * @param {MediaRouterService} service
+ * @constructor
+ */
+ function MediaRouterObserver(service) {
+ /**
+ * The Mojo service proxy. Allows extension code to call methods that reside
+ * in the browser.
+ * @type {MediaRouterService}
+ */
+ this.observer_ = service;
+
+ /**
+ * The MRPM service delegate. Its methods are called by the browser-resident
+ * Mojo service.
+ * @type {MediaRouter}
+ */
+ this.mrpm_ = new MediaRouter(this);
+
+ /**
+ * The message pipe that connects the Media Router to mrpm_ across
+ * browser/renderer IPC boundaries.
+ * Object must remain in scope for the lifetime of the connection to
+ * prevent the connection from closing automatically.
+ * @type {mojo.MessagePipe}
+ */
+ this.pipe_ = core.createMessagePipe();
+
+ /**
+ * Handle to a KeepAlive service object, which prevents the extension from
+ * being suspended as long as it remains in scope
+ * @type {boolean}
+ */
+ this.keepAlive_ = null;
+
+ // Define the stub used to bind this.mrpm_ to the Mojo interface.
+ // Object must remain in scope for the lifetime of the connection to
+ // prevent the connection from closing automatically.
+ // @type {mojom.MediaRouter}
+ this.mediaRouterStub_ = connector.bindHandleToStub(
+ this.pipe_.handle0, mediaRouterMojom.MediaRouter);
+
+ // Link the stub to impl code.
+ bindings.StubBindings(this.mediaRouterStub_).delegate = this.mrpm_;
+ }
+
+
+ /**
+ * Register the Media Router Provider Manager with the Media Router.
+ * @return {!Promise<string>} A unique, string-based ID for this instance
+ * of the Media Router.
+ */
+ MediaRouterObserver.prototype.start = function() {
+ return this.observer_.provideMediaRouter(this.pipe_.handle1).then(
+ function(result) {
+ return result.instance_id;
+ }.bind(this));
+ }
+
+
+ /**
+ * Sets the service delegate methods.
+ * @param {Object}
+ */
+ MediaRouterObserver.prototype.setHandlers = function(handlers) {
+ this.mrpm_.setHandlers(handlers);
+ }
+
+
+ /**
+ * Gets the keep alive status.
+ * @return {boolean}
+ */
+ MediaRouterObserver.prototype.getKeepAlive = function() {
+ return this.keepAlive_ != null;
+ };
+
+
+ /**
+ * Called by the Provider Manager when a sink list for a given source is
+ * updated.
+ * @param {!string} sourceUrn
+ * @param {!Array<!Object>} sinks
+ */
+ MediaRouterObserver.prototype.onSinksReceived = function(sourceUrn, sinks) {
+ this.observer_.onSinksReceived(sourceUrn,
+ sinks.map(sinkToMojo_));
+ };
+
+
+ /**
+ * Called by the Provider Manager to keep the extension from suspending
+ * if it enters a state where suspension is undesirable (e.g. there is an
+ * active MediaRoute.)
+ * If keepAlive is true, the extension is kept alive.
+ * If keepAlive is false, the extension is allowed to suspend.
+ *
+ * @param {boolean} keepAlive
+ */
+ MediaRouterObserver.prototype.setKeepAlive = function(keepAlive) {
+ if (keepAlive === false && this.keepAlive_) {
+ this.keepAlive_.close();
+ this.keepAlive_ = null;
+ } else if (keepAlive === true && !this.keepAlive_) {
+ this.keepAlive_ = new routerModule.Router(
+ serviceProvider.connectToService(
+ keepAliveMojom.KeepAlive.name));
+ }
+ };
+
+
+ /**
+ * Sends a message to an active media route.
+ *
+ * @param {!string} routeId
+ * @param {!Object|string} message A message that can be converted to a JSON
+ * string.
+ */
+ MediaRouterObserver.prototype.onMessage = function(routeId, message) {
+ this.observer_.onMessage(routeId, JSON.stringify(message));
+ };
+
+
+ /**
+ * Reports an issue to the Media Router.
+ *
+ * @param {!Object} issue
+ */
+ MediaRouterObserver.prototype.onIssue = function(issue) {
+ function issueSeverityToMojo_(severity) {
+ switch (severity) {
+ case 'fatal':
+ return mediaRouterMojom.Issue.Severity.FATAL;
+ case 'warning':
+ return mediaRouterMojom.Issue.Severity.WARNING;
+ case 'notification':
+ return mediaRouterMojom.Issue.Severity.NOTIFICATION;
+ default:
+ console.error('Unknown issue severity: ' + severity);
+ return mediaRouterMojom.Issue.Severity.NOTIFICATION;
+ }
+ }
+
+ function issueActionToMojo_(action) {
+ switch (action) {
+ case 'ok':
+ return mediaRouterMojom.Issue.ActionType.OK;
+ case 'cancel':
+ return mediaRouterMojom.Issue.ActionType.CANCEL;
+ case 'dismiss':
+ return mediaRouterMojom.Issue.ActionType.DISMISS;
+ case 'learn_more':
+ return mediaRouterMojom.Issue.ActionType.LEARN_MORE;
+ default:
+ console.error('Unknown issue action type : ' + action);
+ return mediaRouterMojom.Issue.ActionType.OK;
+ }
+ }
+
+ var secondaryActions = (issue.secondaryActions || []).map(function(e) {
+ return issueActionToMojo_(e);
+ });
+ this.observer_.onIssue(new mediaRouterMojom.Issue({
+ 'route_id': issue.routeId,
+ 'severity': issueSeverityToMojo_(issue.severity),
+ 'title': issue.title,
+ 'message': issue.message,
+ 'default_action': issueActionToMojo_(issue.defaultAction),
+ 'secondary_actions': secondaryActions,
+ 'help_url': issue.helpUrl,
+ 'is_blocking': issue.isBlocking
+ }));
+ };
+
+
+ /**
+ * Called by the Provider Manager when the list of active routes
+ * has changed.
+ * @param {!Array<MediaRoute>} routes
+ * @param {!Array<MediaSink>} routes
+ */
+ MediaRouterObserver.prototype.onRoutesUpdated = function(routes, sinks) {
+ // Create an inverted index relating sink IDs to their names.
+ var sinkNameMap = {};
+ for (var i = 0; i < sinks.length; i++) {
+ sinkNameMap[sinks[i].id] = sinks[i].friendlyName;
+ }
+
+ // Convert MediaRoutes to Mojo objects and add their sink names
+ // via sinkNameMap.
+ var mojoRoutes = [];
+ for (var j = 0; j < routes.length; j++) {
+ mojoRoutes.push(routeToMojo_(routes[j], sinkNameMap[routes[j].sinkId]));
+ }
+
+ this.observer_.onRoutesUpdated(
+ mojoRoutes,
+ sinks.map(MediaRouterObserver.sinkToMojo_));
+ };
+
+
+ /**
+ * Called by the Provider Manager when an error was encountered for a media
+ * route.
+ *
+ * @param {!string} requestId The ID of the route request which experienced an
+ * error.
+ * @param {!string} error
+ */
+ MediaRouterObserver.prototype.onRouteResponseError =
+ function(requestId, error) {
+ this.observer_.onRouteResponseError(requestId, error);
+ };
+
+
+ MediaRouterObserver.prototype.onRouteResponseReceived =
+ function(requestId, routeId) {
+ this.observer_.onRouteResponseReceived(requestId, routeId);
+ };
+
+
+ /**
+ * Object containing JS callbacks into Provider Manager code.
+ * @constructor
+ * @struct
+ */
+ function MediaRouterHandlers() {
+ /**
+ * @type {function(!string, !string, !string=, !string=, !number=}
+ */
+ this.createRoute = null;
+
+ /**
+ * @type {function(!string, !string, !string, !number)}
+ */
+ this.joinRoute = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.closeRoute = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.startObservingMediaSinks = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.stopObservingMediaSinks = null;
+
+ /**
+ * @type {function(string, string, string)}
+ */
+ this.postMessage = null;
+
+ /**
+ * @type {function()}
+ */
+ this.startObservingMediaRoutes = null;
+
+ /**
+ * @type {function()}
+ */
+ this.stopObservingMediaRoutes = null;
+ };
+
+
+ /**
+ * Routes calls from Media Router to the Provider Manager extension.
+ * Registered with the MediaRouter stub.
+ *
+ * @constructor
+ */
+ function MediaRouter(mediaRouterObserver) {
+ /**
+ * Object containing JS callbacks into Provider Manager code.
+ * @type {!MediaRouterHandlers}
+ */
+ this.handlers_ = new MediaRouterHandlers();
+
+ /**
+ * Proxy class to the browser's Media Router Mojo service.
+ * @type {!MediaRouterObserver}
+ */
+ this.mediaRouter_ = mediaRouterObserver;
+ }
+ MediaRouter.prototype = Object.create(
+ mediaRouterMojom.MediaRouter.stubClass.prototype);
+
+
+ /*
+ * Sets the callback handler used to invoke methods in the Provider Manager.
+ * @param {!MediaRouterHandlers} handlers
+ */
+ MediaRouter.prototype.setHandlers = function(handlers) {
+ this.handlers_ = handlers;
+ if (!this.handlers_.stopObservingMediaRoutes) {
+ console.error('stopObservingMediaRoutes handler not registered.');
+ return;
+ }
+ if (!this.handlers_.startObservingMediaRoutes) {
+ console.error('startObservingMediaRoutes handler not registered.');
+ return;
+ }
+ if (!this.handlers_.postMessage) {
+ console.error('postMessage handler not registered.');
+ return;
+ }
+ if (!this.handlers_.closeRoute) {
+ console.error('closeRoute handler not registered.');
+ return;
+ }
+ if (!this.handlers_.joinRoute) {
+ 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.
+ }
+ if (!this.handlers_.createRoute) {
+ return Promise.resolve({
+ error_text: 'createRoute handler not registered.'
+ });
+ }
+ if (!this.handlers_.stopObservingMediaSinks) {
+ console.error('stopObservingMediaSinks handler not registered.');
+ return;
+ }
+ if ( !this.handlers_.startObservingMediaSinks) {
+ console.error('startObservingMediaSinks handler not registered.');
+ return;
+ }
+ }
+
+
+ /**
+ * Starts querying for sinks capable of displaying the media |sourceUrn|.
+ * Results are returned by calling OnSinksReceived.
+ * @param {!string} sourceUrn
+ */
+ MediaRouter.prototype.startObservingMediaSinks =
+ function(sourceUrn) {
+ this.handlers_.startObservingMediaSinks(sourceUrn);
+ };
+
+
+ /**
+ * Stops querying for sinks capable of displaying the media |sourceUrn|.
+ * @param {!string} sourceUrn
+ */
+ MediaRouter.prototype.stopObservingMediaSinks =
+ function(sourceUrn) {
+ this.handlers_.stopObservingMediaSinks(sourceUrn);
+ };
+
+
+ /**
+ * Requests that |sinkId| render the media referenced by |sourceUrn|.
+ * @param {!string} sourceUrn
+ * @param {!string} sinkId
+ * @param {!string=} opt_presentationId
+ * @param {!string=} opt_origin
+ * @param {!number=} opt_tabId
+ * @return {!Promise.<!Object>}
+ */
+ MediaRouter.prototype.createRoute =
+ function(sourceUrn, sinkId, opt_presentationId, opt_origin, opt_tabId) {
+ return this.handlers_.createRoute(
+ sourceUrn, sinkId, opt_presentationId, opt_origin, opt_tabId)
+ .then(function(route) {
+ // Sink name is not used, so it is omitted here.
+ return {route: routeToMojo_(route, "")};
+ }.bind(this))
+ .catch(function(err) {
+ return {error_text: err.message};
+ });
+ };
+
+ /**
+ * Join an existing route given by |presentationId| and render media
+ * referenced by |sourceUrn|. |origin| and |tabId| are used for checking
+ * origin/tab scope.
+ * @param {!string} sourceUrn
+ * @param {!string} presentationId
+ * @param {!string} origin
+ * @param {!number} tabId
+ * @return {!Promise.<!Object>} Resolved with the route on success,
+ * or with an error message on failure.
+ */
+ MediaRouter.prototype.joinRoute =
+ function(sourceUrn, presentationId, origin, tabId) {
+ return this.handlers_.joinRoute(sourceUrn, presentationId, origin, tabId)
+ .then(function(newRoute) {
+ return {route: routeToMojo_(newRoute)};
+ },
+ function(err) {
+ return {error_text: 'Error joining route: ' + err.message};
+ });
+ };
+
+
+ /**
+ * Closes route specified by |routeId|
+ * @param {!string} routeId
+ */
+ MediaRouter.prototype.closeRoute = function(routeId) {
+ this.handlers_.closeRoute(routeId);
+ };
+
+
+ /**
+ * Posts message to a sink connected by route with |routeId|.
+ * @param {!string} routeId
+ * @param {!string} message
+ * @param {string} extraInfoJson
+ */
+ MediaRouter.prototype.postMessage = function(
+ routeId, message, extraInfoJson) {
+ this.handlers_.postMessage(routeId, message, JSON.parse(extraInfoJson));
+ };
+
+
+ /**
+ * Requests that the Provider Manager start sending information about active
+ * media routes to the Media Router.
+ */
+ MediaRouter.prototype.startObservingMediaRoutes = function() {
+ this.handlers_.startObservingMediaRoutes();
+ };
+
+
+ /**
+ * Requests that the Provider Manager stop sending information about active
+ * media routes to the Media Router.
+ */
+ MediaRouter.prototype.stopObservingMediaRoutes = function() {
+ this.handlers_.stopObservingMediaRoutes();
+ };
+
+ mediaRouterObserver = new MediaRouterObserver(connector.bindHandleToProxy(
+ serviceProvider.connectToService(
+ mediaRouterMojom.MediaRouterObserver.name),
+ mediaRouterMojom.MediaRouterObserver));
+
+ return mediaRouterObserver;
+});
+
« 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