Extensions: convert media_router_bindings.js to use new Mojo JS bindings.
This CL also changes the mojoPrivate API to be simply an async wrapper around
require().
Bug: 699569, 718047
Change-Id: I271887d1cc1eb49fd2faefff47467c47be23a3be
Reviewed-on: https://chromium-review.googlesource.com/783645
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: Derek Cheng <imcheng@chromium.org>
Reviewed-by: Ken Rockot <rockot@chromium.org>
Commit-Queue: Yuzhu Shen <yzshen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521129}
diff --git a/chrome/common/media_router/mojo/BUILD.gn b/chrome/common/media_router/mojo/BUILD.gn
index 0dfaec4..63f946b 100644
--- a/chrome/common/media_router/mojo/BUILD.gn
+++ b/chrome/common/media_router/mojo/BUILD.gn
@@ -13,9 +13,6 @@
public_deps = [
"//mojo/common:common_custom_types",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- use_new_js_bindings = false
}
mojom("media_router") {
@@ -31,9 +28,6 @@
"//url/mojo:url_mojom_gurl",
"//url/mojo:url_mojom_origin",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- use_new_js_bindings = false
}
mojom("media_router_test_interfaces") {
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js
index 9251258..4ce4750 100644
--- a/chrome/renderer/resources/extensions/media_router_bindings.js
+++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -2,935 +2,1391 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var mediaRouter;
+'use strict';
-define('media_router_bindings', [
- 'chrome/common/media_router/mojo/media_controller.mojom',
- 'chrome/common/media_router/mojo/media_router.mojom',
- 'chrome/common/media_router/mojo/media_status.mojom',
- 'content/public/renderer/frame_interfaces',
- 'extensions/common/mojo/keep_alive.mojom',
- 'media/mojo/interfaces/mirror_service_remoting.mojom',
- 'media/mojo/interfaces/remoting_common.mojom',
- 'mojo/common/time.mojom',
- 'mojo/public/js/bindings',
- 'net/interfaces/ip_address.mojom',
- 'net/interfaces/ip_endpoint.mojom',
- 'url/mojo/origin.mojom',
- 'url/mojo/url.mojom',
-], function(mediaControllerMojom,
- mediaRouterMojom,
- mediaStatusMojom,
- frameInterfaces,
- keepAliveMojom,
- remotingMojom,
- remotingCommonMojom,
- timeMojom,
- bindings,
- ipAddressMojom,
- ipEndpointMojom,
- originMojom,
- urlMojom) {
- 'use strict';
+if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) {
+ loadScript('mojo_bindings');
+}
+mojo.config.autoLoadMojomDeps = false;
- /**
- * Converts a media sink to a MediaSink Mojo object.
- * @param {!MediaSink} sink A media sink.
- * @return {!mediaRouterMojom.MediaSink} A Mojo MediaSink object.
- */
- function sinkToMojo_(sink) {
- return new mediaRouterMojom.MediaSink({
- 'name': sink.friendlyName,
- 'description': sink.description,
- 'domain': sink.domain,
- 'sink_id': sink.id,
- 'icon_type': sinkIconTypeToMojo(sink.iconType),
- });
+loadScript('chrome/common/media_router/mojo/media_controller.mojom');
+loadScript('chrome/common/media_router/mojo/media_router.mojom');
+loadScript('chrome/common/media_router/mojo/media_status.mojom');
+loadScript('extensions/common/mojo/keep_alive.mojom');
+loadScript('media/mojo/interfaces/mirror_service_remoting.mojom');
+loadScript('media/mojo/interfaces/remoting_common.mojom');
+loadScript('mojo/common/time.mojom');
+loadScript('net/interfaces/ip_address.mojom');
+loadScript('net/interfaces/ip_endpoint.mojom');
+loadScript('url/mojo/origin.mojom');
+loadScript('url/mojo/url.mojom');
+
+// The following adapter classes preserve backward compatibility for the media
+// router component extension.
+// TODO(crbug.com/787128): Remove these adapters.
+
+function assignFields(object, fields) {
+ for(var field in fields) {
+ if (object.hasOwnProperty(field))
+ object[field] = fields[field];
+ }
+}
+
+/**
+ * Adapter for mediaRouter.mojom.DialMediaSink.
+ * @constructor
+ */
+function DialMediaSinkAdapter(fields) {
+ this.ip_address = null;
+ this.model_name = null;
+ this.app_url = null;
+
+ assignFields(this, fields);
+}
+
+DialMediaSinkAdapter.fromNewVersion = function(other) {
+ return new DialMediaSinkAdapter({
+ 'ip_address': IPAddressAdapter.fromNewVersion(other.ipAddress),
+ 'model_name': other.modelName,
+ 'app_url': other.appUrl,
+ });
+};
+
+DialMediaSinkAdapter.prototype.toNewVersion = function() {
+ return new mediaRouter.mojom.DialMediaSink({
+ 'ipAddress' : this.ip_address.toNewVersion(),
+ 'modelName' : this.model_name,
+ 'appUrl' : this.app_url,
+ });
+};
+
+/**
+ * Adapter for mediaRouter.mojom.CastMediaSink.
+ * @constructor
+ */
+function CastMediaSinkAdapter(fields) {
+ this.ip_endpoint = null;
+ this.model_name = null;
+ this.capabilities = 0;
+ this.cast_channel_id = 0;
+
+ assignFields(this, fields);
+}
+
+CastMediaSinkAdapter.fromNewVersion = function(other) {
+ return new CastMediaSinkAdapter({
+ 'ip_endpoint': IPEndpointAdapter.fromNewVersion(other.ipEndpoint),
+ 'model_name': other.modelName,
+ 'capabilities': other.capabilities,
+ 'cast_channel_id': other.castChannelId,
+ });
+};
+
+CastMediaSinkAdapter.prototype.toNewVersion = function() {
+ return new mediaRouter.mojom.CastMediaSink({
+ 'ipEndpoint': this.ip_endpoint.toNewVersion(),
+ 'modelName': this.model_name,
+ 'capabilities': this.capabilities,
+ 'castChannelId': this.cast_channel_id,
+ });
+};
+
+/**
+ * Adapter for mediaRouter.mojom.HangoutsMediaStatusExtraData.
+ * @constructor
+ */
+function HangoutsMediaStatusExtraDataAdapter(fields) {
+ this.local_present = false;
+
+ assignFields(this, fields);
+}
+
+HangoutsMediaStatusExtraDataAdapter.prototype.toNewVersion = function() {
+ return new mediaRouter.mojom.HangoutsMediaStatusExtraData({
+ 'localPresent': this.local_present,
+ });
+};
+
+/**
+ * Adapter for net.interfaces.IPAddress.
+ * @constructor
+ */
+function IPAddressAdapter(fields) {
+ this.address_bytes = null;
+
+ assignFields(this, fields);
+}
+
+IPAddressAdapter.fromNewVersion = function(other) {
+ return new IPAddressAdapter({
+ 'address_bytes': other.addressBytes,
+ });
+};
+
+IPAddressAdapter.prototype.toNewVersion = function() {
+ return new net.interfaces.IPAddress({
+ 'addressBytes': this.address_bytes,
+ });
+};
+
+/**
+ * Adapter for net.interfaces.IPEndpoint.
+ * @constructor
+ */
+function IPEndpointAdapter(fields) {
+ this.address = null;
+ this.port = 0;
+
+ assignFields(this, fields);
+}
+
+IPEndpointAdapter.fromNewVersion = function(other) {
+ return new IPEndpointAdapter({
+ 'address': IPAddressAdapter.fromNewVersion(other.address),
+ 'port': other.port,
+ });
+};
+
+IPEndpointAdapter.prototype.toNewVersion = function() {
+ return new net.interfaces.IPEndpoint({
+ 'address': this.address.toNewVersion(),
+ 'port': this.port,
+ });
+};
+
+/**
+ * Adapter for mediaRouter.mojom.MediaStatus.
+ * @constructor
+ */
+function MediaStatusAdapter(fields) {
+ this.title = null;
+ this.description = null;
+ this.can_play_pause = false;
+ this.can_mute = false;
+ this.can_set_volume = false;
+ this.can_seek = false;
+ this.is_muted = false;
+ this.play_state = 0;
+ this.volume = 0;
+ this.duration = null;
+ this.current_time = null;
+ this.hangouts_extra_data = null;
+
+ assignFields(this, fields);
+}
+
+MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState;
+
+MediaStatusAdapter.prototype.toNewVersion = function() {
+ return new mediaRouter.mojom.MediaStatus({
+ 'title': this.title,
+ 'description': this.description,
+ 'canPlayPause': this.can_play_pause,
+ 'canMute': this.can_mute,
+ 'canSetVolume': this.can_set_volume,
+ 'canSeek': this.can_seek,
+ 'isMuted': this.is_muted,
+ 'playState': this.play_state,
+ 'volume': this.volume,
+ 'duration': this.duration,
+ 'currentTime': this.current_time,
+ 'hangoutsExtraData':
+ this.hangouts_extra_data && this.hangouts_extra_data.toNewVersion(),
+ });
+};
+
+/**
+ * Adapter for media.mojom.RemotingSinkMetadata.
+ * @constructor
+ */
+function RemotingSinkMetadataAdapter(fields) {
+ this.features = null;
+ this.audio_capabilities = null;
+ this.video_capabilities = null;
+ this.friendly_name = null;
+
+ assignFields(this, fields);
+}
+
+RemotingSinkMetadataAdapter.fromNewVersion = function(other) {
+ return new RemotingSinkMetadataAdapter({
+ 'features': other.features,
+ 'audio_capabilities': other.audioCapabilities,
+ 'video_capabilities': other.videoCapabilities,
+ 'friendly_name': other.friendlyName,
+ });
+};
+
+RemotingSinkMetadataAdapter.prototype.toNewVersion = function() {
+ return new media.mojom.RemotingSinkMetadata({
+ 'features': this.features,
+ 'audioCapabilities': this.audio_capabilities,
+ 'videoCapabilities': this.video_capabilities,
+ 'friendlyName': this.friendly_name,
+ });
+};
+
+/**
+ * Adapter for mediaRouter.mojom.MediaSink.
+ * @constructor
+ */
+function MediaSinkAdapter(fields) {
+ this.sink_id = null;
+ this.name = null;
+ this.description = null;
+ this.domain = null;
+ this.icon_type = 0;
+ this.extra_data = null;
+
+ assignFields(this, fields);
+}
+
+MediaSinkAdapter.fromNewVersion = function(other) {
+ return new MediaSinkAdapter({
+ 'sink_id': other.sinkId,
+ 'name': other.name,
+ 'description': other.description,
+ 'domain': other.domain,
+ 'icon_type': other.iconType,
+ 'extra_data': other.extraData &&
+ MediaSinkExtraDataAdapter.fromNewVersion(other.extraData),
+ });
+};
+
+MediaSinkAdapter.prototype.toNewVersion = function() {
+ return new mediaRouter.mojom.MediaSink({
+ 'sinkId': this.sink_id,
+ 'name': this.name,
+ 'description': this.description,
+ 'domain': this.domain,
+ 'iconType': this.icon_type,
+ 'extraData': this.extra_data && this.extra_data.toNewVersion(),
+ });
+};
+
+/**
+ * Adapter for mediaRouter.mojom.MediaSinkExtraData.
+ * @constructor
+ */
+function MediaSinkExtraDataAdapter(value) {
+ this.$data = null;
+ this.$tag = undefined;
+
+ if (value == undefined) {
+ return;
}
- /**
- * Converts a media sink's icon type to a MediaSink.IconType Mojo object.
- * @param {!MediaSink.IconType} type A media sink's icon type.
- * @return {!mediaRouterMojom.MediaSink.IconType} A Mojo MediaSink.IconType
- * object.
- */
- function sinkIconTypeToMojo(type) {
- switch (type) {
- case 'cast':
- return mediaRouterMojom.SinkIconType.CAST;
- case 'cast_audio_group':
- return mediaRouterMojom.SinkIconType.CAST_AUDIO_GROUP;
- case 'cast_audio':
- return mediaRouterMojom.SinkIconType.CAST_AUDIO;
- case 'meeting':
- return mediaRouterMojom.SinkIconType.MEETING;
- case 'hangout':
- return mediaRouterMojom.SinkIconType.HANGOUT;
- case 'education':
- return mediaRouterMojom.SinkIconType.EDUCATION;
- case 'generic':
- return mediaRouterMojom.SinkIconType.GENERIC;
- default:
- console.error('Unknown sink icon type : ' + type);
- return mediaRouterMojom.SinkIconType.GENERIC;
+ var keys = Object.keys(value);
+ if (keys.length == 0) {
+ return;
+ }
+
+ if (keys.length > 1) {
+ throw new TypeError('You may set only one member on a union.');
+ }
+
+ var fields = [
+ 'dial_media_sink',
+ 'cast_media_sink',
+ ];
+
+ if (fields.indexOf(keys[0]) < 0) {
+ throw new ReferenceError(keys[0] +
+ ' is not a MediaSinkExtraDataAdapter member.');
+ }
+
+ this[keys[0]] = value[keys[0]];
+}
+
+MediaSinkExtraDataAdapter.Tags = {
+ dial_media_sink: 0,
+ cast_media_sink: 1,
+};
+
+Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'dial_media_sink', {
+ get: function() {
+ if (this.$tag != MediaSinkExtraDataAdapter.Tags.dial_media_sink) {
+ throw new ReferenceError(
+ 'MediaSinkExtraDataAdapter.dial_media_sink is not currently set.');
}
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = MediaSinkExtraDataAdapter.Tags.dial_media_sink;
+ this.$data = value;
}
-
- /**
- * Returns a Mojo MediaRoute object given a MediaRoute and a
- * media sink name.
- * @param {!MediaRoute} route
- * @return {!mojo.MediaRoute}
- */
- function routeToMojo_(route) {
- return new mediaRouterMojom.MediaRoute({
- 'media_route_id': route.id,
- 'media_source': route.mediaSource,
- 'media_sink_id': route.sinkId,
- 'description': route.description,
- 'icon_url': route.iconUrl,
- 'is_local': route.isLocal,
- 'custom_controller_path': route.customControllerPath || '',
- 'for_display': route.forDisplay,
- 'is_incognito': route.offTheRecord,
- 'is_local_presentation': route.isOffscreenPresentation,
- 'supports_media_route_controller': route.supportsMediaRouteController,
- 'controller_type': route.controllerType,
- // Begin newly added properties, followed by the milestone they were
- // added. The guard should be safe to remove N+2 milestones later.
- 'presentation_id': route.presentationId || '' // M64
- });
- }
-
- /**
- * Converts a route message to a RouteMessage Mojo object.
- * @param {!RouteMessage} message
- * @return {!mediaRouterMojom.RouteMessage} A Mojo RouteMessage object.
- */
- function messageToMojo_(message) {
- if ("string" == typeof message.message) {
- return new mediaRouterMojom.RouteMessage({
- 'type': mediaRouterMojom.RouteMessage.Type.TEXT,
- 'message': message.message,
- });
- } else {
- return new mediaRouterMojom.RouteMessage({
- 'type': mediaRouterMojom.RouteMessage.Type.BINARY,
- 'data': message.message,
- });
- }
- }
-
- /**
- * Converts presentation connection state to Mojo enum value.
- * @param {!string} state
- * @return {!mediaRouterMojom.MediaRouter.PresentationConnectionState}
- */
- function presentationConnectionStateToMojo_(state) {
- var PresentationConnectionState =
- mediaRouterMojom.MediaRouter.PresentationConnectionState;
- switch (state) {
- case 'connecting':
- return PresentationConnectionState.CONNECTING;
- case 'connected':
- return PresentationConnectionState.CONNECTED;
- case 'closed':
- return PresentationConnectionState.CLOSED;
- case 'terminated':
- return PresentationConnectionState.TERMINATED;
- default:
- console.error('Unknown presentation connection state: ' + state);
- return PresentationConnectionState.TERMINATED;
- }
- }
-
- /**
- * Converts presentation connection close reason to Mojo enum value.
- * @param {!string} reason
- * @return {!mediaRouterMojom.MediaRouter.PresentationConnectionCloseReason}
- */
- function presentationConnectionCloseReasonToMojo_(reason) {
- var PresentationConnectionCloseReason =
- mediaRouterMojom.MediaRouter.PresentationConnectionCloseReason;
- switch (reason) {
- case 'error':
- return PresentationConnectionCloseReason.CONNECTION_ERROR;
- case 'closed':
- return PresentationConnectionCloseReason.CLOSED;
- case 'went_away':
- return PresentationConnectionCloseReason.WENT_AWAY;
- default:
- console.error('Unknown presentation connection close reason : ' +
- reason);
- return PresentationConnectionCloseReason.CONNECTION_ERROR;
- }
- }
-
- /**
- * Parses the given route request Error object and converts it to the
- * corresponding result code.
- * @param {!Error} error
- * @return {!mediaRouterMojom.RouteRequestResultCode}
- */
- function getRouteRequestResultCode_(error) {
- return error.errorCode ? error.errorCode :
- mediaRouterMojom.RouteRequestResultCode.UNKNOWN_ERROR;
- }
-
- /**
- * Creates and returns a successful route response from given route.
- * @param {!MediaRoute} route
- * @return {!Object}
- */
- function toSuccessRouteResponse_(route) {
- return {
- route: routeToMojo_(route),
- result_code: mediaRouterMojom.RouteRequestResultCode.OK
- };
- }
-
- /**
- * Creates and returns a error route response from given Error object.
- * @param {!Error} error
- * @return {!Object}
- */
- function toErrorRouteResponse_(error) {
- return {
- error_text: error.message,
- result_code: getRouteRequestResultCode_(error)
- };
- }
-
- /**
- * Creates a new MediaRouter.
- * Converts a route struct to its Mojo form.
- * @param {!mediaRouterMojom.MediaRouterPtr} service
- * @constructor
- */
- function MediaRouter(service) {
- /**
- * The Mojo service proxy. Allows extension code to call methods that reside
- * in the browser.
- * @type {!mediaRouterMojom.MediaRouterPtr}
- */
- this.service_ = service;
-
- /**
- * The provider manager service delegate. Its methods are called by the
- * browser-resident Mojo service.
- * @type {!MediaRouter}
- */
- this.mrpm_ = new MediaRouteProvider(this);
-
- /**
- * 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;
-
- /**
- * The bindings to bind the service delegate to the Mojo interface.
- * Object must remain in scope for the lifetime of the connection to
- * prevent the connection from closing automatically.
- * @type {!bindings.Binding}
- */
- this.mediaRouteProviderBinding_ = new bindings.Binding(
- mediaRouterMojom.MediaRouteProvider, this.mrpm_);
- }
-
- /**
- * Returns definitions of Mojo core and generated Mojom classes that can be
- * used directly by the component.
- * @return {!Object}
- * TODO(imcheng): We should export these along with MediaRouter. This requires
- * us to modify the component to handle multiple exports. When that logic is
- * baked in for a couple of milestones, we should be able to remove this
- * method.
- */
- MediaRouter.prototype.getMojoExports = function() {
- return {
- Binding: bindings.Binding,
- DialMediaSink: mediaRouterMojom.DialMediaSink,
- CastMediaSink: mediaRouterMojom.CastMediaSink,
- HangoutsMediaRouteController:
- mediaControllerMojom.HangoutsMediaRouteController,
- HangoutsMediaStatusExtraData:
- mediaStatusMojom.HangoutsMediaStatusExtraData,
- IPAddress: ipAddressMojom.IPAddress,
- IPEndpoint: ipEndpointMojom.IPEndpoint,
- InterfacePtrController: bindings.InterfacePtrController,
- InterfaceRequest: bindings.InterfaceRequest,
- MediaController: mediaControllerMojom.MediaController,
- MediaStatus: mediaStatusMojom.MediaStatus,
- MediaStatusObserverPtr: mediaStatusMojom.MediaStatusObserverPtr,
- MirrorServiceRemoter: remotingMojom.MirrorServiceRemoter,
- MirrorServiceRemoterPtr: remotingMojom.MirrorServiceRemoterPtr,
- MirrorServiceRemotingSourcePtr:
- remotingMojom.MirrorServiceRemotingSourcePtr,
- RemotingStopReason: remotingCommonMojom.RemotingStopReason,
- RemotingStartFailReason: remotingCommonMojom.RemotingStartFailReason,
- RemotingSinkFeature: remotingCommonMojom.RemotingSinkFeature,
- RemotingSinkAudioCapability:
- remotingCommonMojom.RemotingSinkAudioCapability,
- RemotingSinkVideoCapability:
- remotingCommonMojom.RemotingSinkVideoCapability,
- RemotingSinkMetadata: remotingCommonMojom.RemotingSinkMetadata,
- RouteControllerType: mediaRouterMojom.RouteControllerType,
- Origin: originMojom.Origin,
- Sink: mediaRouterMojom.MediaSink,
- SinkExtraData: mediaRouterMojom.MediaSinkExtraData,
- TimeDelta: timeMojom.TimeDelta,
- Url: urlMojom.Url,
- makeRequest: bindings.makeRequest,
- };
- };
-
- /**
- * Registers the Media Router Provider Manager with the Media Router.
- * @return {!Promise<Object>} Instance ID and config for the Media Router.
- */
- MediaRouter.prototype.start = function() {
- return this.service_.registerMediaRouteProvider(
- mediaRouterMojom.MediaRouteProvider.Id.EXTENSION,
- this.mediaRouteProviderBinding_.createInterfacePtrAndBind());
- }
-
- /**
- * Sets the service delegate methods.
- * @param {Object} handlers
- */
- MediaRouter.prototype.setHandlers = function(handlers) {
- this.mrpm_.setHandlers(handlers);
- }
-
- /**
- * The keep alive status.
- * @return {boolean}
- */
- MediaRouter.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<!MediaSink>} sinks
- * @param {!Array<!originMojom.Origin>} origins
- */
- MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) {
- this.service_.onSinksReceived(
- mediaRouterMojom.MediaRouteProvider.Id.EXTENSION, sourceUrn,
- sinks.map(sinkToMojo_), origins);
- };
-
- /**
- * Called by the provider manager when a sink is found to notify the MR of the
- * sink's ID. The actual sink will be returned through the normal sink list
- * update process, so this helps the MR identify the search result in the
- * list.
- * @param {string} pseudoSinkId ID of the pseudo sink that started the
- * search.
- * @param {string} sinkId ID of the newly-found sink.
- */
- MediaRouter.prototype.onSearchSinkIdReceived = function(
- pseudoSinkId, sinkId) {
- this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId);
- };
-
- /**
- * 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
- */
- MediaRouter.prototype.setKeepAlive = function(keepAlive) {
- if (keepAlive === false && this.keepAlive_) {
- this.keepAlive_.ptr.reset();
- this.keepAlive_ = null;
- } else if (keepAlive === true && !this.keepAlive_) {
- this.keepAlive_ = new keepAliveMojom.KeepAlivePtr(
- frameInterfaces.getInterface(keepAliveMojom.KeepAlive.name));
- }
- };
-
- /**
- * Called by the provider manager to send an issue from a media route
- * provider to the Media Router, to show the user.
- * @param {!Object} issue The issue object.
- */
- MediaRouter.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 '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.service_.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_page_id': issue.helpPageId,
- 'is_blocking': issue.isBlocking
- }));
- };
-
- /**
- * Called by the provider manager when the set of active routes
- * has been updated.
- * @param {!Array<MediaRoute>} routes The active set of media routes.
- * @param {string=} sourceUrn The sourceUrn associated with this route
- * query.
- * @param {Array<string>=} joinableRouteIds The active set of joinable
- * media routes.
- */
- MediaRouter.prototype.onRoutesUpdated = function(
- routes, sourceUrn = '', joinableRouteIds = []) {
- this.service_.onRoutesUpdated(
- mediaRouterMojom.MediaRouteProvider.Id.EXTENSION,
- routes.map(routeToMojo_), sourceUrn, joinableRouteIds);
- };
-
- /**
- * Called by the provider manager when sink availability has been updated.
- * @param {!mediaRouterMojom.MediaRouter.SinkAvailability} availability
- * The new sink availability.
- */
- MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) {
- this.service_.onSinkAvailabilityUpdated(
- mediaRouterMojom.MediaRouteProvider.Id.EXTENSION, availability);
- };
-
- /**
- * Called by the provider manager when the state of a presentation connected
- * to a route has changed.
- * @param {string} routeId
- * @param {string} state
- */
- MediaRouter.prototype.onPresentationConnectionStateChanged =
- function(routeId, state) {
- this.service_.onPresentationConnectionStateChanged(
- routeId, presentationConnectionStateToMojo_(state));
- };
-
- /**
- * Called by the provider manager when the state of a presentation connected
- * to a route has closed.
- * @param {string} routeId
- * @param {string} reason
- * @param {string} message
- */
- MediaRouter.prototype.onPresentationConnectionClosed =
- function(routeId, reason, message) {
- this.service_.onPresentationConnectionClosed(
- routeId, presentationConnectionCloseReasonToMojo_(reason), message);
- };
-
- /**
- * @param {string} routeId
- * @param {!Array<!RouteMessage>} mesages
- */
- MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) {
- this.service_.onRouteMessagesReceived(
- routeId, messages.map(messageToMojo_));
- };
-
- /**
- * @param {number} tabId
- * @param {!remotingMojom.MirrorServiceRemoterPtr} remoter
- * @param {!remotingMojom.MirrorServiceRemotingSourcePtr} remotingSource
- */
- MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter,
- remotingSource) {
- this.service_.onMediaRemoterCreated(tabId, remoter, remotingSource);
- }
-
- /**
- * Object containing callbacks set by the provider manager.
- *
- * @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): Promise}
- */
- this.terminateRoute = null;
-
- /**
- * @type {function(string)}
- */
- this.startObservingMediaSinks = null;
-
- /**
- * @type {function(string)}
- */
- this.stopObservingMediaSinks = null;
-
- /**
- * @type {function(string, string): Promise}
- */
- this.sendRouteMessage = null;
-
- /**
- * @type {function(string, Uint8Array): Promise}
- */
- this.sendRouteBinaryMessage = null;
-
- /**
- * @type {function(string)}
- */
- this.startListeningForRouteMessages = null;
-
- /**
- * @type {function(string)}
- */
- this.stopListeningForRouteMessages = null;
-
- /**
- * @type {function(string)}
- */
- this.detachRoute = null;
-
- /**
- * @type {function()}
- */
- this.startObservingMediaRoutes = null;
-
- /**
- * @type {function()}
- */
- this.stopObservingMediaRoutes = null;
-
- /**
- * @type {function()}
- */
- this.connectRouteByRouteId = null;
-
- /**
- * @type {function()}
- */
- this.enableMdnsDiscovery = null;
-
- /**
- * @type {function()}
- */
- this.updateMediaSinks = null;
-
- /**
- * @type {function(string, string, !SinkSearchCriteria): string}
- */
- this.searchSinks = null;
-
- /**
- * @type {function()}
- */
- this.provideSinks = null;
-
- /**
- * @type {function(string, !bindings.InterfaceRequest,
- * !mediaStatusMojom.MediaStatusObserverPtr): !Promise<void>}
- */
- this.createMediaRouteController = null;
- };
-
- /**
- * Routes calls from Media Router to the provider manager extension.
- * Registered with the MediaRouter stub.
- * @param {!MediaRouter} MediaRouter proxy to call into the
- * Media Router mojo interface.
- * @constructor
- */
- function MediaRouteProvider(mediaRouter) {
- /**
- * 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 {!MediaRouter}
- */
- this.mediaRouter_ = mediaRouter;
- }
-
- /*
- * Sets the callback handler used to invoke methods in the provider manager.
- *
- * @param {!MediaRouterHandlers} handlers
- */
- MediaRouteProvider.prototype.setHandlers = function(handlers) {
- this.handlers_ = handlers;
- var requiredHandlers = [
- 'stopObservingMediaRoutes',
- 'startObservingMediaRoutes',
- 'sendRouteMessage',
- 'sendRouteBinaryMessage',
- 'startListeningForRouteMessages',
- 'stopListeningForRouteMessages',
- 'detachRoute',
- 'terminateRoute',
- 'joinRoute',
- 'createRoute',
- 'stopObservingMediaSinks',
- 'startObservingMediaRoutes',
- 'connectRouteByRouteId',
- 'enableMdnsDiscovery',
- 'updateMediaSinks',
- 'searchSinks',
- 'provideSinks',
- 'createMediaRouteController',
- 'onBeforeInvokeHandler'
- ];
- requiredHandlers.forEach(function(nextHandler) {
- if (handlers[nextHandler] === undefined) {
- console.error(nextHandler + ' handler not registered.');
- }
- });
- }
-
- /**
- * Starts querying for sinks capable of displaying the media source
- * designated by |sourceUrn|. Results are returned by calling
- * OnSinksReceived.
- * @param {!string} sourceUrn
- */
- MediaRouteProvider.prototype.startObservingMediaSinks =
- function(sourceUrn) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.startObservingMediaSinks(sourceUrn);
- };
-
- /**
- * Stops querying for sinks capable of displaying |sourceUrn|.
- * @param {!string} sourceUrn
- */
- MediaRouteProvider.prototype.stopObservingMediaSinks =
- function(sourceUrn) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.stopObservingMediaSinks(sourceUrn);
- };
-
- /**
- * Requests that |sinkId| render the media referenced by |sourceUrn|. If the
- * request is from the Presentation API, then origin and tabId will
- * be populated.
- * @param {!string} sourceUrn Media source to render.
- * @param {!string} sinkId Media sink ID.
- * @param {!string} presentationId Presentation ID from the site
- * requesting presentation. TODO(mfoltz): Remove.
- * @param {!originMojom.Origin} origin Origin of site requesting presentation.
- * @param {!number} tabId ID of tab requesting presentation.
- * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for
- * the request. Otherwise, the default duration will be used.
- * @param {!boolean} incognito If true, the route is being requested by
- * an incognito profile.
- * @return {!Promise.<!Object>} A Promise resolving to an object describing
- * the newly created media route, or rejecting with an error message on
- * failure.
- */
- MediaRouteProvider.prototype.createRoute =
- function(sourceUrn, sinkId, presentationId, origin, tabId,
- timeout, incognito) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_.createRoute(
- sourceUrn, sinkId, presentationId, origin, tabId,
- Math.floor(timeout.microseconds / 1000), incognito)
- .then(function(route) {
- return toSuccessRouteResponse_(route);
- },
- function(err) {
- return toErrorRouteResponse_(err);
- });
- };
-
- /**
- * Handles a request via the Presentation API to join an existing route given
- * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for
- * validating same-origin/tab scope.
- * @param {!string} sourceUrn Media source to render.
- * @param {!string} presentationId Presentation ID to join.
- * @param {!originMojom.Origin} origin Origin of site requesting join.
- * @param {!number} tabId ID of tab requesting join.
- * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for
- * the request. Otherwise, the default duration will be used.
- * @param {!boolean} incognito If true, the route is being requested by
- * an incognito profile.
- * @return {!Promise.<!Object>} A Promise resolving to an object describing
- * the newly created media route, or rejecting with an error message on
- * failure.
- */
- MediaRouteProvider.prototype.joinRoute =
- function(sourceUrn, presentationId, origin, tabId, timeout,
- incognito) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_.joinRoute(
- sourceUrn, presentationId, origin, tabId,
- Math.floor(timeout.microseconds / 1000), incognito)
- .then(function(route) {
- return toSuccessRouteResponse_(route);
- },
- function(err) {
- return toErrorRouteResponse_(err);
- });
- };
-
- /**
- * Handles a request via the Presentation API to join an existing route given
- * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for
- * validating same-origin/tab scope.
- * @param {!string} sourceUrn Media source to render.
- * @param {!string} routeId Route ID to join.
- * @param {!string} presentationId Presentation ID to join.
- * @param {!originMojom.Origin} origin Origin of site requesting join.
- * @param {!number} tabId ID of tab requesting join.
- * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for
- * the request. Otherwise, the default duration will be used.
- * @param {!boolean} incognito If true, the route is being requested by
- * an incognito profile.
- * @return {!Promise.<!Object>} A Promise resolving to an object describing
- * the newly created media route, or rejecting with an error message on
- * failure.
- */
- MediaRouteProvider.prototype.connectRouteByRouteId =
- function(sourceUrn, routeId, presentationId, origin, tabId,
- timeout, incognito) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_.connectRouteByRouteId(
- sourceUrn, routeId, presentationId, origin, tabId,
- Math.floor(timeout.microseconds / 1000), incognito)
- .then(function(route) {
- return toSuccessRouteResponse_(route);
- },
- function(err) {
- return toErrorRouteResponse_(err);
- });
- };
-
- /**
- * Terminates the route specified by |routeId|.
- * @param {!string} routeId
- * @return {!Promise<!Object>} A Promise resolving to an object describing
- * the result of the terminate operation, or rejecting with an error
- * message and code if the operation failed.
- */
- MediaRouteProvider.prototype.terminateRoute = function(routeId) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_.terminateRoute(routeId).then(
- () => ({result_code: mediaRouterMojom.RouteRequestResultCode.OK}),
- (err) => toErrorRouteResponse_(err));
- };
-
- /**
- * Posts a message to the route designated by |routeId|.
- * @param {!string} routeId
- * @param {!string} message
- * @return {!Promise.<boolean>} Resolved with true if the message was sent,
- * or false on failure.
- */
- MediaRouteProvider.prototype.sendRouteMessage = function(
- routeId, message) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_.sendRouteMessage(routeId, message)
- .then(function() {
- return {'sent': true};
- }, function() {
- return {'sent': false};
- });
- };
-
- /**
- * Sends a binary message to the route designated by |routeId|.
- * @param {!string} routeId
- * @param {!Array<number>} data
- * @return {!Promise.<boolean>} Resolved with true if the data was sent,
- * or false on failure.
- */
- MediaRouteProvider.prototype.sendRouteBinaryMessage = function(
- routeId, data) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data))
- .then(function() {
- return {'sent': true};
- }, function() {
- return {'sent': false};
- });
- };
-
- /**
- * Listen for messages from a route.
- * @param {!string} routeId
- */
- MediaRouteProvider.prototype.startListeningForRouteMessages = function(
- routeId) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.startListeningForRouteMessages(routeId);
- };
-
- /**
- * @param {!string} routeId
- */
- MediaRouteProvider.prototype.stopListeningForRouteMessages = function(
- routeId) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.stopListeningForRouteMessages(routeId);
- };
-
- /**
- * Indicates that the presentation connection that was connected to |routeId|
- * is no longer connected to it.
- * @param {!string} routeId
- */
- MediaRouteProvider.prototype.detachRoute = function(
- routeId) {
- this.handlers_.detachRoute(routeId);
- };
-
- /**
- * Requests that the provider manager start sending information about active
- * media routes to the Media Router.
- * @param {!string} sourceUrn
- */
- MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.startObservingMediaRoutes(sourceUrn);
- };
-
- /**
- * Requests that the provider manager stop sending information about active
- * media routes to the Media Router.
- * @param {!string} sourceUrn
- */
- MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.stopObservingMediaRoutes(sourceUrn);
- };
-
- /**
- * Enables mDNS device discovery.
- */
- MediaRouteProvider.prototype.enableMdnsDiscovery = function() {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.enableMdnsDiscovery();
- };
-
- /**
- * Requests that the provider manager update media sinks.
- * @param {!string} sourceUrn
- */
- MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.updateMediaSinks(sourceUrn);
- };
-
- /**
- * Requests that the provider manager search its providers for a sink matching
- * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found
- * that can be used immediately for route creation, its ID is returned.
- * Otherwise the empty string is returned.
- *
- * @param {string} sinkId Sink ID of the pseudo sink generating the request.
- * @param {string} sourceUrn Media source to be used with the sink.
- * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route
- * providers.
- * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the
- * sink ID of the sink found by the search that can be used for route
- * creation, or the empty string if no route can be immediately created.
- */
- MediaRouteProvider.prototype.searchSinks = function(
- sinkId, sourceUrn, searchCriteria) {
- this.handlers_.onBeforeInvokeHandler();
- const searchSinksResponse =
- this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria);
-
- if ('string' == typeof searchSinksResponse) {
- // TODO (zijiang): Remove this check when M59 is stable and the
- // extension is always returning a promise.
- return Promise.resolve({
- 'sink_id': sink_id
- });
- }
- return searchSinksResponse.then(
- sink_id => {
- return { 'sink_id': sink_id };
- },
- () => {
- return { 'sink_id': '' };
- });
- };
-
- /**
- * Notifies the provider manager that MediaRouter has discovered a list of
- * sinks.
- * @param {string} providerName
- * @param {!Array<!mediaRouterMojom.MediaSink>} sinks
- */
- MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) {
- this.handlers_.onBeforeInvokeHandler();
- this.handlers_.provideSinks(providerName, sinks);
- };
-
- /**
- * Creates a controller for the given route and binds the given
- * InterfaceRequest to it, and registers an observer for media status updates
- * for the route.
- * @param {string} routeId
- * @param {!bindings.InterfaceRequest} controllerRequest
- * @param {!mediaStatusMojom.MediaStatusObserverPtr} observer
- * @return {!Promise<!{success: boolean}>} Resolves to true if a controller
- * is created. Resolves to false if a controller cannot be created, or if
- * the controller is already bound.
- */
- MediaRouteProvider.prototype.createMediaRouteController = function(
- routeId, controllerRequest, observer) {
- this.handlers_.onBeforeInvokeHandler();
- return this.handlers_
- .createMediaRouteController(routeId, controllerRequest, observer)
- .then(() => ({success: true}), e => ({success: false}));
- };
-
- mediaRouter = new MediaRouter(new mediaRouterMojom.MediaRouterPtr(
- frameInterfaces.getInterface(mediaRouterMojom.MediaRouter.name)));
-
- return mediaRouter;
});
+
+Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'cast_media_sink', {
+ get: function() {
+ if (this.$tag != MediaSinkExtraDataAdapter.Tags.cast_media_sink) {
+ throw new ReferenceError(
+ 'MediaSinkExtraDataAdapter.cast_media_sink is not currently set.');
+ }
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = MediaSinkExtraDataAdapter.Tags.cast_media_sink;
+ this.$data = value;
+ }
+});
+
+MediaSinkExtraDataAdapter.fromNewVersion = function(other) {
+ if (other.$tag == mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) {
+ return new MediaSinkExtraDataAdapter({
+ 'dial_media_sink':
+ DialMediaSinkAdapter.fromNewVersion(other.dialMediaSink),
+ });
+ } else {
+ return new MediaSinkExtraDataAdapter({
+ 'cast_media_sink':
+ CastMediaSinkAdapter.fromNewVersion(other.castMediaSink),
+ });
+ }
+};
+
+MediaSinkExtraDataAdapter.prototype.toNewVersion = function() {
+ if (this.$tag == MediaSinkExtraDataAdapter.Tags.dial_media_sink) {
+ return new mediaRouter.mojom.MediaSinkExtraData({
+ 'dialMediaSink': this.dial_media_sink.toNewVersion(),
+ });
+ } else {
+ return new mediaRouter.mojom.MediaSinkExtraData({
+ 'castMediaSink': this.cast_media_sink.toNewVersion(),
+ });
+ }
+};
+
+/**
+ * Adapter for media.mojom.MirrorServiceRemoterPtr.
+ * @constructor
+ */
+function MirrorServiceRemoterPtrAdapter(handleOrPtrInfo) {
+ this.ptr = new mojo.InterfacePtrController(MirrorServiceRemoterAdapter,
+ handleOrPtrInfo);
+}
+
+MirrorServiceRemoterPtrAdapter.prototype =
+ Object.create(media.mojom.MirrorServiceRemoterPtr.prototype);
+MirrorServiceRemoterPtrAdapter.prototype.constructor =
+ MirrorServiceRemoterPtrAdapter;
+
+MirrorServiceRemoterPtrAdapter.prototype.startDataStreams = function() {
+ return MirrorServiceRemoterProxy.prototype.startDataStreams
+ .apply(this.ptr.getProxy(), arguments).then(function(response) {
+ return Promise.resolve({
+ 'audio_stream_id': response.audioStreamId,
+ 'video_stream_id': response.videoStreamId,
+ });
+ });
+};
+
+/**
+ * Adapter for media.mojom.MirrorServiceRemoter.stubclass.
+ * @constructor
+ */
+function MirrorServiceRemoterStubAdapter(delegate) {
+ this.delegate_ = delegate;
+}
+
+MirrorServiceRemoterStubAdapter.prototype = Object.create(
+ media.mojom.MirrorServiceRemoter.stubClass.prototype);
+MirrorServiceRemoterStubAdapter.prototype.constructor =
+ MirrorServiceRemoterStubAdapter;
+
+MirrorServiceRemoterStubAdapter.prototype.startDataStreams =
+ function(hasAudio, hasVideo) {
+ return this.delegate_ && this.delegate_.startDataStreams &&
+ this.delegate_.startDataStreams(hasAudio, hasVideo).then(
+ function(response) {
+ return {
+ 'audioStreamId': response.audio_stream_id,
+ 'videoStreamId': response.video_stream_id,
+ };
+ });
+};
+
+/**
+ * Adapter for media.mojom.MirrorServiceRemoter.
+ */
+var MirrorServiceRemoterAdapter = {
+ name: 'media::mojom::MirrorServiceRemoter',
+ kVersion: 0,
+ ptrClass: MirrorServiceRemoterPtrAdapter,
+ proxyClass: media.mojom.MirrorServiceRemoter.proxyClass,
+ stubClass: MirrorServiceRemoterStubAdapter,
+ validateRequest: media.mojom.MirrorServiceRemoter.validateRequest,
+ validateResponse: media.mojom.MirrorServiceRemoter.validateResponse,
+};
+
+/**
+ * Adapter for media.mojom.MirrorServiceRemotingSourcePtr.
+ * @constructor
+ */
+function MirrorServiceRemotingSourcePtrAdapter(handleOrPtrInfo) {
+ this.ptr = new mojo.InterfacePtrController(MirrorServiceRemotingSourceAdapter,
+ handleOrPtrInfo);
+}
+
+MirrorServiceRemotingSourcePtrAdapter.prototype =
+ Object.create(media.mojom.MirrorServiceRemotingSourcePtr.prototype);
+MirrorServiceRemotingSourcePtrAdapter.prototype.constructor =
+ MirrorServiceRemotingSourcePtrAdapter;
+
+MirrorServiceRemotingSourcePtrAdapter.prototype.onSinkAvailable =
+ function(metadata) {
+ return this.ptr.getProxy().onSinkAvailable(metadata.toNewVersion());
+};
+
+/**
+ * Adapter for media.mojom.MirrorServiceRemotingSource.
+ */
+var MirrorServiceRemotingSourceAdapter = {
+ name: 'media::mojom::MirrorServiceRemotingSource',
+ kVersion: 0,
+ ptrClass: MirrorServiceRemotingSourcePtrAdapter,
+ proxyClass: media.mojom.MirrorServiceRemotingSource.proxyClass,
+ stubClass: null,
+ validateRequest: media.mojom.MirrorServiceRemotingSource.validateRequest,
+ validateResponse: null,
+};
+
+/**
+ * Adapter for mediaRouter.mojom.MediaStatusObserver.
+ * @constructor
+ */
+function MediaStatusObserverPtrAdapter(handleOrPtrInfo) {
+ this.ptr = new mojo.InterfacePtrController(MediaStatusObserverAdapter,
+ handleOrPtrInfo);
+}
+
+MediaStatusObserverPtrAdapter.prototype =
+ Object.create(mediaRouter.mojom.MediaStatusObserverPtr.prototype);
+MediaStatusObserverPtrAdapter.prototype.constructor =
+ MediaStatusObserverPtrAdapter;
+
+MediaStatusObserverPtrAdapter.prototype.onMediaStatusUpdated =
+ function(status) {
+ return this.ptr.getProxy().onMediaStatusUpdated(status.toNewVersion());
+};
+
+/**
+ * Adapter for mediaRouter.mojom.MediaStatusObserver.
+ */
+var MediaStatusObserverAdapter = {
+ name: 'mediaRouter::mojom::MediaStatusObserver',
+ kVersion: 0,
+ ptrClass: MediaStatusObserverPtrAdapter,
+ proxyClass: mediaRouter.mojom.MediaStatusObserver.proxyClass,
+ stubClass: null,
+ validateRequest: mediaRouter.mojom.MediaStatusObserver.validateRequest,
+ validateResponse: null,
+};
+
+/**
+ * Converts a media sink to a MediaSink Mojo object.
+ * @param {!MediaSink} sink A media sink.
+ * @return {!mediaRouter.mojom.MediaSink} A Mojo MediaSink object.
+ */
+function sinkToMojo_(sink) {
+ return new mediaRouter.mojom.MediaSink({
+ 'name': sink.friendlyName,
+ 'description': sink.description,
+ 'domain': sink.domain,
+ 'sinkId': sink.id,
+ 'iconType': sinkIconTypeToMojo(sink.iconType),
+ });
+}
+
+/**
+ * Converts a media sink's icon type to a MediaSink.IconType Mojo object.
+ * @param {!MediaSink.IconType} type A media sink's icon type.
+ * @return {!mediaRouter.mojom.MediaSink.IconType} A Mojo MediaSink.IconType
+ * object.
+ */
+function sinkIconTypeToMojo(type) {
+ switch (type) {
+ case 'cast':
+ return mediaRouter.mojom.SinkIconType.CAST;
+ case 'cast_audio_group':
+ return mediaRouter.mojom.SinkIconType.CAST_AUDIO_GROUP;
+ case 'cast_audio':
+ return mediaRouter.mojom.SinkIconType.CAST_AUDIO;
+ case 'meeting':
+ return mediaRouter.mojom.SinkIconType.MEETING;
+ case 'hangout':
+ return mediaRouter.mojom.SinkIconType.HANGOUT;
+ case 'education':
+ return mediaRouter.mojom.SinkIconType.EDUCATION;
+ case 'generic':
+ return mediaRouter.mojom.SinkIconType.GENERIC;
+ default:
+ console.error('Unknown sink icon type : ' + type);
+ return mediaRouter.mojom.SinkIconType.GENERIC;
+ }
+}
+
+/**
+ * Returns a Mojo MediaRoute object given a MediaRoute and a
+ * media sink name.
+ * @param {!MediaRoute} route
+ * @return {!mediaRouter.mojom.MediaRoute}
+ */
+function routeToMojo_(route) {
+ return new mediaRouter.mojom.MediaRoute({
+ 'mediaRouteId': route.id,
+ 'mediaSource': route.mediaSource,
+ 'mediaSinkId': route.sinkId,
+ 'description': route.description,
+ 'iconUrl': route.iconUrl,
+ 'isLocal': route.isLocal,
+ 'customControllerPath': route.customControllerPath || '',
+ 'forDisplay': route.forDisplay,
+ 'isIncognito': route.offTheRecord,
+ 'isLocalPresentation': route.isOffscreenPresentation,
+ 'supportsMediaRouteController': route.supportsMediaRouteController,
+ 'controllerType': route.controllerType,
+ // Begin newly added properties, followed by the milestone they were
+ // added. The guard should be safe to remove N+2 milestones later.
+ 'presentationId': route.presentationId || '' // M64
+ });
+}
+
+/**
+ * Converts a route message to a RouteMessage Mojo object.
+ * @param {!RouteMessage} message
+ * @return {!mediaRouter.mojom.RouteMessage} A Mojo RouteMessage object.
+ */
+function messageToMojo_(message) {
+ if ("string" == typeof message.message) {
+ return new mediaRouter.mojom.RouteMessage({
+ 'type': mediaRouter.mojom.RouteMessage.Type.TEXT,
+ 'message': message.message,
+ });
+ } else {
+ return new mediaRouter.mojom.RouteMessage({
+ 'type': mediaRouter.mojom.RouteMessage.Type.BINARY,
+ 'data': message.message,
+ });
+ }
+}
+
+/**
+ * Converts presentation connection state to Mojo enum value.
+ * @param {!string} state
+ * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionState}
+ */
+function presentationConnectionStateToMojo_(state) {
+ var PresentationConnectionState =
+ mediaRouter.mojom.MediaRouter.PresentationConnectionState;
+ switch (state) {
+ case 'connecting':
+ return PresentationConnectionState.CONNECTING;
+ case 'connected':
+ return PresentationConnectionState.CONNECTED;
+ case 'closed':
+ return PresentationConnectionState.CLOSED;
+ case 'terminated':
+ return PresentationConnectionState.TERMINATED;
+ default:
+ console.error('Unknown presentation connection state: ' + state);
+ return PresentationConnectionState.TERMINATED;
+ }
+}
+
+/**
+ * Converts presentation connection close reason to Mojo enum value.
+ * @param {!string} reason
+ * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason}
+ */
+function presentationConnectionCloseReasonToMojo_(reason) {
+ var PresentationConnectionCloseReason =
+ mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason;
+ switch (reason) {
+ case 'error':
+ return PresentationConnectionCloseReason.CONNECTION_ERROR;
+ case 'closed':
+ return PresentationConnectionCloseReason.CLOSED;
+ case 'went_away':
+ return PresentationConnectionCloseReason.WENT_AWAY;
+ default:
+ console.error('Unknown presentation connection close reason : ' +
+ reason);
+ return PresentationConnectionCloseReason.CONNECTION_ERROR;
+ }
+}
+
+/**
+ * Parses the given route request Error object and converts it to the
+ * corresponding result code.
+ * @param {!Error} error
+ * @return {!mediaRouter.mojom.RouteRequestResultCode}
+ */
+function getRouteRequestResultCode_(error) {
+ return error.errorCode ? error.errorCode :
+ mediaRouter.mojom.RouteRequestResultCode.UNKNOWN_ERROR;
+}
+
+/**
+ * Creates and returns a successful route response from given route.
+ * @param {!MediaRoute} route
+ * @return {!Object}
+ */
+function toSuccessRouteResponse_(route) {
+ return {
+ route: routeToMojo_(route),
+ resultCode: mediaRouter.mojom.RouteRequestResultCode.OK
+ };
+}
+
+/**
+ * Creates and returns a error route response from given Error object.
+ * @param {!Error} error
+ * @return {!Object}
+ */
+function toErrorRouteResponse_(error) {
+ return {
+ errorText: error.message,
+ resultCode: getRouteRequestResultCode_(error)
+ };
+}
+
+/**
+ * Creates a new MediaRouter.
+ * Converts a route struct to its Mojo form.
+ * @param {!mediaRouter.mojom.MediaRouterPtr} service
+ * @constructor
+ */
+function MediaRouter(service) {
+ /**
+ * The Mojo service proxy. Allows extension code to call methods that reside
+ * in the browser.
+ * @type {!mediaRouter.mojom.MediaRouterPtr}
+ */
+ this.service_ = service;
+
+ /**
+ * The provider manager service delegate. Its methods are called by the
+ * browser-resident Mojo service.
+ * @type {!MediaRouter}
+ */
+ this.mrpm_ = new MediaRouteProvider(this);
+
+ /**
+ * 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;
+
+ /**
+ * The bindings to bind the service delegate to the Mojo interface.
+ * Object must remain in scope for the lifetime of the connection to
+ * prevent the connection from closing automatically.
+ * @type {!mojo.Binding}
+ */
+ this.mediaRouteProviderBinding_ = new mojo.Binding(
+ mediaRouter.mojom.MediaRouteProvider, this.mrpm_);
+}
+
+/**
+ * Returns definitions of Mojo core and generated Mojom classes that can be
+ * used directly by the component.
+ * @return {!Object}
+ * TODO(imcheng): We should export these along with MediaRouter. This requires
+ * us to modify the component to handle multiple exports. When that logic is
+ * baked in for a couple of milestones, we should be able to remove this
+ * method.
+ * TODO(imcheng): We should stop exporting mojo bindings classes that the
+ * Media Router extension doesn't directly use, such as
+ * mojo.AssociatedInterfacePtrInfo, mojo.InterfacePtrController and
+ * mojo.interfaceControl2.
+ */
+MediaRouter.prototype.getMojoExports = function() {
+ return {
+ AssociatedInterfacePtrInfo: mojo.AssociatedInterfacePtrInfo,
+ Binding: mojo.Binding,
+ DialMediaSink: DialMediaSinkAdapter,
+ CastMediaSink: CastMediaSinkAdapter,
+ HangoutsMediaRouteController:
+ mediaRouter.mojom.HangoutsMediaRouteController,
+ HangoutsMediaStatusExtraData: HangoutsMediaStatusExtraDataAdapter,
+ IPAddress: IPAddressAdapter,
+ IPEndpoint: IPEndpointAdapter,
+ InterfacePtrController: mojo.InterfacePtrController,
+ InterfacePtrInfo: mojo.InterfacePtrInfo,
+ InterfaceRequest: mojo.InterfaceRequest,
+ MediaController: mediaRouter.mojom.MediaController,
+ MediaStatus: MediaStatusAdapter,
+ MediaStatusObserverPtr: mediaRouter.mojom.MediaStatusObserverPtr,
+ MirrorServiceRemoter: MirrorServiceRemoterAdapter,
+ MirrorServiceRemoterPtr: MirrorServiceRemoterPtrAdapter,
+ MirrorServiceRemotingSourcePtr: MirrorServiceRemotingSourcePtrAdapter,
+ RemotingStopReason: media.mojom.RemotingStopReason,
+ RemotingStartFailReason: media.mojom.RemotingStartFailReason,
+ RemotingSinkFeature: media.mojom.RemotingSinkFeature,
+ RemotingSinkAudioCapability:
+ media.mojom.RemotingSinkAudioCapability,
+ RemotingSinkVideoCapability:
+ media.mojom.RemotingSinkVideoCapability,
+ RemotingSinkMetadata: RemotingSinkMetadataAdapter,
+ RouteControllerType: mediaRouter.mojom.RouteControllerType,
+ Origin: url.mojom.Origin,
+ Sink: MediaSinkAdapter,
+ SinkExtraData: MediaSinkExtraDataAdapter,
+ TimeDelta: mojo.common.mojom.TimeDelta,
+ Url: url.mojom.Url,
+ interfaceControl2: mojo.interfaceControl2,
+ makeRequest: mojo.makeRequest,
+ };
+};
+
+/**
+ * Registers the Media Router Provider Manager with the Media Router.
+ * @return {!Promise<Object>} Instance ID and config for the Media Router.
+ */
+MediaRouter.prototype.start = function() {
+ return this.service_.registerMediaRouteProvider(
+ mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
+ this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then(
+ function(response) {
+ return {
+ 'enable_dial_discovery': response.enableDialDiscovery,
+ 'enable_cast_discovery': response.enableCastDiscovery,
+ };
+ });
+}
+
+/**
+ * Sets the service delegate methods.
+ * @param {Object} handlers
+ */
+MediaRouter.prototype.setHandlers = function(handlers) {
+ this.mrpm_.setHandlers(handlers);
+}
+
+/**
+ * The keep alive status.
+ * @return {boolean}
+ */
+MediaRouter.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<!MediaSink>} sinks
+ * @param {!Array<!url.mojom.Origin>} origins
+ */
+MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) {
+ this.service_.onSinksReceived(
+ mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, sourceUrn,
+ sinks.map(sinkToMojo_), origins);
+};
+
+/**
+ * Called by the provider manager when a sink is found to notify the MR of the
+ * sink's ID. The actual sink will be returned through the normal sink list
+ * update process, so this helps the MR identify the search result in the
+ * list.
+ * @param {string} pseudoSinkId ID of the pseudo sink that started the
+ * search.
+ * @param {string} sinkId ID of the newly-found sink.
+ */
+MediaRouter.prototype.onSearchSinkIdReceived = function(
+ pseudoSinkId, sinkId) {
+ this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId);
+};
+
+/**
+ * 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
+ */
+MediaRouter.prototype.setKeepAlive = function(keepAlive) {
+ if (keepAlive === false && this.keepAlive_) {
+ this.keepAlive_.ptr.reset();
+ this.keepAlive_ = null;
+ } else if (keepAlive === true && !this.keepAlive_) {
+ this.keepAlive_ = new extensions.KeepAlivePtr;
+ Mojo.bindInterface(extensions.KeepAlive.name,
+ mojo.makeRequest(this.keepAlive_).handle);
+ }
+};
+
+/**
+ * Called by the provider manager to send an issue from a media route
+ * provider to the Media Router, to show the user.
+ * @param {!Object} issue The issue object.
+ */
+MediaRouter.prototype.onIssue = function(issue) {
+ function issueSeverityToMojo_(severity) {
+ switch (severity) {
+ case 'fatal':
+ return mediaRouter.mojom.Issue.Severity.FATAL;
+ case 'warning':
+ return mediaRouter.mojom.Issue.Severity.WARNING;
+ case 'notification':
+ return mediaRouter.mojom.Issue.Severity.NOTIFICATION;
+ default:
+ console.error('Unknown issue severity: ' + severity);
+ return mediaRouter.mojom.Issue.Severity.NOTIFICATION;
+ }
+ }
+
+ function issueActionToMojo_(action) {
+ switch (action) {
+ case 'dismiss':
+ return mediaRouter.mojom.Issue.ActionType.DISMISS;
+ case 'learn_more':
+ return mediaRouter.mojom.Issue.ActionType.LEARN_MORE;
+ default:
+ console.error('Unknown issue action type : ' + action);
+ return mediaRouter.mojom.Issue.ActionType.OK;
+ }
+ }
+
+ var secondaryActions = (issue.secondaryActions || []).map(issueActionToMojo_);
+ this.service_.onIssue(new mediaRouter.mojom.Issue({
+ 'routeId': issue.routeId || '',
+ 'severity': issueSeverityToMojo_(issue.severity),
+ 'title': issue.title,
+ 'message': issue.message || '',
+ 'defaultAction': issueActionToMojo_(issue.defaultAction),
+ 'secondaryActions': secondaryActions,
+ 'helpPageId': issue.helpPageId,
+ 'isBlocking': issue.isBlocking
+ }));
+};
+
+/**
+ * Called by the provider manager when the set of active routes
+ * has been updated.
+ * @param {!Array<MediaRoute>} routes The active set of media routes.
+ * @param {string=} sourceUrn The sourceUrn associated with this route
+ * query.
+ * @param {Array<string>=} joinableRouteIds The active set of joinable
+ * media routes.
+ */
+MediaRouter.prototype.onRoutesUpdated = function(
+ routes, sourceUrn = '', joinableRouteIds = []) {
+ this.service_.onRoutesUpdated(
+ mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
+ routes.map(routeToMojo_), sourceUrn, joinableRouteIds);
+};
+
+/**
+ * Called by the provider manager when sink availability has been updated.
+ * @param {!mediaRouter.mojom.MediaRouter.SinkAvailability} availability
+ * The new sink availability.
+ */
+MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) {
+ this.service_.onSinkAvailabilityUpdated(
+ mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, availability);
+};
+
+/**
+ * Called by the provider manager when the state of a presentation connected
+ * to a route has changed.
+ * @param {string} routeId
+ * @param {string} state
+ */
+MediaRouter.prototype.onPresentationConnectionStateChanged =
+ function(routeId, state) {
+ this.service_.onPresentationConnectionStateChanged(
+ routeId, presentationConnectionStateToMojo_(state));
+};
+
+/**
+ * Called by the provider manager when the state of a presentation connected
+ * to a route has closed.
+ * @param {string} routeId
+ * @param {string} reason
+ * @param {string} message
+ */
+MediaRouter.prototype.onPresentationConnectionClosed =
+ function(routeId, reason, message) {
+ this.service_.onPresentationConnectionClosed(
+ routeId, presentationConnectionCloseReasonToMojo_(reason), message);
+};
+
+/**
+ * @param {string} routeId
+ * @param {!Array<!RouteMessage>} mesages
+ */
+MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) {
+ this.service_.onRouteMessagesReceived(
+ routeId, messages.map(messageToMojo_));
+};
+
+/**
+ * @param {number} tabId
+ * @param {!media.mojom.MirrorServiceRemoterPtr} remoter
+ * @param {!mojo.InterfaceRequest} remotingSource
+ */
+MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter,
+ remotingSource) {
+ this.service_.onMediaRemoterCreated(
+ tabId,
+ new media.mojom.MirrorServiceRemoterPtr(remoter.ptr.passInterface()),
+ remotingSource);
+}
+
+/**
+ * Object containing callbacks set by the provider manager.
+ *
+ * @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): Promise}
+ */
+ this.terminateRoute = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.startObservingMediaSinks = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.stopObservingMediaSinks = null;
+
+ /**
+ * @type {function(string, string): Promise}
+ */
+ this.sendRouteMessage = null;
+
+ /**
+ * @type {function(string, Uint8Array): Promise}
+ */
+ this.sendRouteBinaryMessage = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.startListeningForRouteMessages = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.stopListeningForRouteMessages = null;
+
+ /**
+ * @type {function(string)}
+ */
+ this.detachRoute = null;
+
+ /**
+ * @type {function()}
+ */
+ this.startObservingMediaRoutes = null;
+
+ /**
+ * @type {function()}
+ */
+ this.stopObservingMediaRoutes = null;
+
+ /**
+ * @type {function()}
+ */
+ this.connectRouteByRouteId = null;
+
+ /**
+ * @type {function()}
+ */
+ this.enableMdnsDiscovery = null;
+
+ /**
+ * @type {function()}
+ */
+ this.updateMediaSinks = null;
+
+ /**
+ * @type {function(string, string, !SinkSearchCriteria): string}
+ */
+ this.searchSinks = null;
+
+ /**
+ * @type {function()}
+ */
+ this.provideSinks = null;
+
+ /**
+ * @type {function(string, !mojo.InterfaceRequest,
+ * !mediaRouter.mojom.MediaStatusObserverPtr): !Promise<void>}
+ */
+ this.createMediaRouteController = null;
+};
+
+/**
+ * Routes calls from Media Router to the provider manager extension.
+ * Registered with the MediaRouter stub.
+ * @param {!MediaRouter} MediaRouter proxy to call into the
+ * Media Router mojo interface.
+ * @constructor
+ */
+function MediaRouteProvider(mediaRouter) {
+ /**
+ * 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 {!MediaRouter}
+ */
+ this.mediaRouter_ = mediaRouter;
+}
+
+/*
+ * Sets the callback handler used to invoke methods in the provider manager.
+ *
+ * @param {!MediaRouterHandlers} handlers
+ */
+MediaRouteProvider.prototype.setHandlers = function(handlers) {
+ this.handlers_ = handlers;
+ var requiredHandlers = [
+ 'stopObservingMediaRoutes',
+ 'startObservingMediaRoutes',
+ 'sendRouteMessage',
+ 'sendRouteBinaryMessage',
+ 'startListeningForRouteMessages',
+ 'stopListeningForRouteMessages',
+ 'detachRoute',
+ 'terminateRoute',
+ 'joinRoute',
+ 'createRoute',
+ 'stopObservingMediaSinks',
+ 'startObservingMediaRoutes',
+ 'connectRouteByRouteId',
+ 'enableMdnsDiscovery',
+ 'updateMediaSinks',
+ 'searchSinks',
+ 'provideSinks',
+ 'createMediaRouteController',
+ 'onBeforeInvokeHandler'
+ ];
+ requiredHandlers.forEach(function(nextHandler) {
+ if (handlers[nextHandler] === undefined) {
+ console.error(nextHandler + ' handler not registered.');
+ }
+ });
+}
+
+/**
+ * Starts querying for sinks capable of displaying the media source
+ * designated by |sourceUrn|. Results are returned by calling
+ * OnSinksReceived.
+ * @param {!string} sourceUrn
+ */
+MediaRouteProvider.prototype.startObservingMediaSinks =
+ function(sourceUrn) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.startObservingMediaSinks(sourceUrn);
+};
+
+/**
+ * Stops querying for sinks capable of displaying |sourceUrn|.
+ * @param {!string} sourceUrn
+ */
+MediaRouteProvider.prototype.stopObservingMediaSinks =
+ function(sourceUrn) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.stopObservingMediaSinks(sourceUrn);
+};
+
+/**
+ * Requests that |sinkId| render the media referenced by |sourceUrn|. If the
+ * request is from the Presentation API, then origin and tabId will
+ * be populated.
+ * @param {!string} sourceUrn Media source to render.
+ * @param {!string} sinkId Media sink ID.
+ * @param {!string} presentationId Presentation ID from the site
+ * requesting presentation. TODO(mfoltz): Remove.
+ * @param {!url.mojom.Origin} origin Origin of site requesting presentation.
+ * @param {!number} tabId ID of tab requesting presentation.
+ * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
+ * duration for the request. Otherwise, the default duration will be used.
+ * @param {!boolean} incognito If true, the route is being requested by
+ * an incognito profile.
+ * @return {!Promise.<!Object>} A Promise resolving to an object describing
+ * the newly created media route, or rejecting with an error message on
+ * failure.
+ */
+MediaRouteProvider.prototype.createRoute =
+ function(sourceUrn, sinkId, presentationId, origin, tabId,
+ timeout, incognito) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.createRoute(
+ sourceUrn, sinkId, presentationId, origin, tabId,
+ Math.floor(timeout.microseconds / 1000), incognito)
+ .then(function(route) {
+ return toSuccessRouteResponse_(route);
+ },
+ function(err) {
+ return toErrorRouteResponse_(err);
+ });
+};
+
+/**
+ * Handles a request via the Presentation API to join an existing route given
+ * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for
+ * validating same-origin/tab scope.
+ * @param {!string} sourceUrn Media source to render.
+ * @param {!string} presentationId Presentation ID to join.
+ * @param {!url.mojom.Origin} origin Origin of site requesting join.
+ * @param {!number} tabId ID of tab requesting join.
+ * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
+ * duration for the request. Otherwise, the default duration will be used.
+ * @param {!boolean} incognito If true, the route is being requested by
+ * an incognito profile.
+ * @return {!Promise.<!Object>} A Promise resolving to an object describing
+ * the newly created media route, or rejecting with an error message on
+ * failure.
+ */
+MediaRouteProvider.prototype.joinRoute =
+ function(sourceUrn, presentationId, origin, tabId, timeout,
+ incognito) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.joinRoute(
+ sourceUrn, presentationId, origin, tabId,
+ Math.floor(timeout.microseconds / 1000), incognito)
+ .then(function(route) {
+ return toSuccessRouteResponse_(route);
+ },
+ function(err) {
+ return toErrorRouteResponse_(err);
+ });
+};
+
+/**
+ * Handles a request via the Presentation API to join an existing route given
+ * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for
+ * validating same-origin/tab scope.
+ * @param {!string} sourceUrn Media source to render.
+ * @param {!string} routeId Route ID to join.
+ * @param {!string} presentationId Presentation ID to join.
+ * @param {!url.mojom.Origin} origin Origin of site requesting join.
+ * @param {!number} tabId ID of tab requesting join.
+ * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
+ * duration for the request. Otherwise, the default duration will be used.
+ * @param {!boolean} incognito If true, the route is being requested by
+ * an incognito profile.
+ * @return {!Promise.<!Object>} A Promise resolving to an object describing
+ * the newly created media route, or rejecting with an error message on
+ * failure.
+ */
+MediaRouteProvider.prototype.connectRouteByRouteId =
+ function(sourceUrn, routeId, presentationId, origin, tabId,
+ timeout, incognito) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.connectRouteByRouteId(
+ sourceUrn, routeId, presentationId, origin, tabId,
+ Math.floor(timeout.microseconds / 1000), incognito)
+ .then(function(route) {
+ return toSuccessRouteResponse_(route);
+ },
+ function(err) {
+ return toErrorRouteResponse_(err);
+ });
+};
+
+/**
+ * Terminates the route specified by |routeId|.
+ * @param {!string} routeId
+ * @return {!Promise<!Object>} A Promise resolving to an object describing
+ * the result of the terminate operation, or rejecting with an error
+ * message and code if the operation failed.
+ */
+MediaRouteProvider.prototype.terminateRoute = function(routeId) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.terminateRoute(routeId).then(
+ () => ({resultCode: mediaRouter.mojom.RouteRequestResultCode.OK}),
+ (err) => toErrorRouteResponse_(err));
+};
+
+/**
+ * Posts a message to the route designated by |routeId|.
+ * @param {!string} routeId
+ * @param {!string} message
+ * @return {!Promise.<boolean>} Resolved with true if the message was sent,
+ * or false on failure.
+ */
+MediaRouteProvider.prototype.sendRouteMessage = function(
+ routeId, message) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.sendRouteMessage(routeId, message)
+ .then(function() {
+ return {'sent': true};
+ }, function() {
+ return {'sent': false};
+ });
+};
+
+/**
+ * Sends a binary message to the route designated by |routeId|.
+ * @param {!string} routeId
+ * @param {!Array<number>} data
+ * @return {!Promise.<boolean>} Resolved with true if the data was sent,
+ * or false on failure.
+ */
+MediaRouteProvider.prototype.sendRouteBinaryMessage = function(
+ routeId, data) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data))
+ .then(function() {
+ return {'sent': true};
+ }, function() {
+ return {'sent': false};
+ });
+};
+
+/**
+ * Listen for messages from a route.
+ * @param {!string} routeId
+ */
+MediaRouteProvider.prototype.startListeningForRouteMessages = function(
+ routeId) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.startListeningForRouteMessages(routeId);
+};
+
+/**
+ * @param {!string} routeId
+ */
+MediaRouteProvider.prototype.stopListeningForRouteMessages = function(
+ routeId) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.stopListeningForRouteMessages(routeId);
+};
+
+/**
+ * Indicates that the presentation connection that was connected to |routeId|
+ * is no longer connected to it.
+ * @param {!string} routeId
+ */
+MediaRouteProvider.prototype.detachRoute = function(
+ routeId) {
+ this.handlers_.detachRoute(routeId);
+};
+
+/**
+ * Requests that the provider manager start sending information about active
+ * media routes to the Media Router.
+ * @param {!string} sourceUrn
+ */
+MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.startObservingMediaRoutes(sourceUrn);
+};
+
+/**
+ * Requests that the provider manager stop sending information about active
+ * media routes to the Media Router.
+ * @param {!string} sourceUrn
+ */
+MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.stopObservingMediaRoutes(sourceUrn);
+};
+
+/**
+ * Enables mDNS device discovery.
+ */
+MediaRouteProvider.prototype.enableMdnsDiscovery = function() {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.enableMdnsDiscovery();
+};
+
+/**
+ * Requests that the provider manager update media sinks.
+ * @param {!string} sourceUrn
+ */
+MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.updateMediaSinks(sourceUrn);
+};
+
+/**
+ * Requests that the provider manager search its providers for a sink matching
+ * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found
+ * that can be used immediately for route creation, its ID is returned.
+ * Otherwise the empty string is returned.
+ *
+ * @param {string} sinkId Sink ID of the pseudo sink generating the request.
+ * @param {string} sourceUrn Media source to be used with the sink.
+ * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route
+ * providers.
+ * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the
+ * sink ID of the sink found by the search that can be used for route
+ * creation, or the empty string if no route can be immediately created.
+ */
+MediaRouteProvider.prototype.searchSinks = function(
+ sinkId, sourceUrn, searchCriteria) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria).then(
+ sinkId => {
+ return { 'sinkId': sinkId };
+ },
+ () => {
+ return { 'sinkId': '' };
+ });
+};
+
+/**
+ * Notifies the provider manager that MediaRouter has discovered a list of
+ * sinks.
+ * @param {string} providerName
+ * @param {!Array<!mediaRouter.mojom.MediaSink>} sinks
+ */
+MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) {
+ this.handlers_.onBeforeInvokeHandler();
+ this.handlers_.provideSinks(providerName,
+ sinks.map(MediaSinkAdapter.fromNewVersion));
+};
+
+/**
+ * Creates a controller for the given route and binds the given
+ * InterfaceRequest to it, and registers an observer for media status updates
+ * for the route.
+ * @param {string} routeId
+ * @param {!mojo.InterfaceRequest} controllerRequest
+ * @param {!mediaRouter.mojom.MediaStatusObserverPtr} observer
+ * @return {!Promise<!{success: boolean}>} Resolves to true if a controller
+ * is created. Resolves to false if a controller cannot be created, or if
+ * the controller is already bound.
+ */
+MediaRouteProvider.prototype.createMediaRouteController = function(
+ routeId, controllerRequest, observer) {
+ this.handlers_.onBeforeInvokeHandler();
+ return this.handlers_.createMediaRouteController(
+ routeId, controllerRequest,
+ new MediaStatusObserverPtrAdapter(observer.ptr.passInterface())).then(
+ () => ({success: true}), e => ({success: false}));
+};
+
+var ptr = new mediaRouter.mojom.MediaRouterPtr;
+Mojo.bindInterface(mediaRouter.mojom.MediaRouter.name,
+ mojo.makeRequest(ptr).handle);
+exports.$set('returnValue', new MediaRouter(ptr));
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index 521f0f8..ce1e9fd 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -36,9 +36,6 @@
"//mojo/common:common_custom_types",
"//url/mojo:url_mojom_gurl",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- js_bindings_mode = "both"
}
# This must be a static library because extensions common depends on
diff --git a/extensions/renderer/api/mojo_private/mojo_private_unittest.cc b/extensions/renderer/api/mojo_private/mojo_private_unittest.cc
index e73457e..9693bf28 100644
--- a/extensions/renderer/api/mojo_private/mojo_private_unittest.cc
+++ b/extensions/renderer/api/mojo_private/mojo_private_unittest.cc
@@ -36,10 +36,8 @@
};
TEST_F(MojoPrivateApiTest, RequireAsync) {
- env()->RegisterModule("add",
- "define('add', [], function() {"
- " return { Add: function(x, y) { return x + y; } };"
- "});");
+ env()->RegisterModule(
+ "add", "exports.$set('returnValue', function(x, y) { return x + y; });");
ASSERT_NO_FATAL_FAILURE(
RunTest("mojo_private_unittest.js", "testRequireAsync"));
}
diff --git a/extensions/renderer/resources/mime_handler_private_custom_bindings.js b/extensions/renderer/resources/mime_handler_private_custom_bindings.js
index 262c549..6d09de8b 100644
--- a/extensions/renderer/resources/mime_handler_private_custom_bindings.js
+++ b/extensions/renderer/resources/mime_handler_private_custom_bindings.js
@@ -14,7 +14,9 @@
'Streams are only available from a mime handler view guest.';
var STREAM_ABORTED_ERROR = 'Stream has been aborted.';
-loadScript('mojo_bindings');
+if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) {
+ loadScript('mojo_bindings');
+}
loadScript('extensions/common/api/mime_handler.mojom');
var servicePtr = new extensions.mimeHandler.MimeHandlerServicePtr;
diff --git a/extensions/renderer/resources/mojo_private_custom_bindings.js b/extensions/renderer/resources/mojo_private_custom_bindings.js
index 548e3a3a..794471b 100644
--- a/extensions/renderer/resources/mojo_private_custom_bindings.js
+++ b/extensions/renderer/resources/mojo_private_custom_bindings.js
@@ -12,7 +12,7 @@
let apiFunctions = bindingsAPI.apiFunctions;
apiFunctions.setHandleRequest('requireAsync', function(moduleName) {
- return requireAsync(moduleName);
+ return Promise.resolve(require(moduleName).returnValue);
});
});
diff --git a/extensions/test/data/mojo_private_unittest.js b/extensions/test/data/mojo_private_unittest.js
index 85a48da..cfdc9db 100644
--- a/extensions/test/data/mojo_private_unittest.js
+++ b/extensions/test/data/mojo_private_unittest.js
@@ -13,7 +13,7 @@
function testRequireAsync() {
mojoPrivate.requireAsync('add').then(
test.callbackPass(function(add) {
- test.assertEq('function', typeof add.Add);
+ test.assertEq('function', typeof add);
}));
},
], test.runTests, exports);
diff --git a/media/mojo/interfaces/BUILD.gn b/media/mojo/interfaces/BUILD.gn
index d49ed181..d7bacb7 100644
--- a/media/mojo/interfaces/BUILD.gn
+++ b/media/mojo/interfaces/BUILD.gn
@@ -69,9 +69,6 @@
sources = [
"remoting_common.mojom",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- use_new_js_bindings = false
}
mojom("mirror_service_remoting") {
@@ -82,9 +79,6 @@
public_deps = [
":remoting_common",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- use_new_js_bindings = false
}
mojom("remoting") {
diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn
index b43da6b..d9c8672 100644
--- a/mojo/common/BUILD.gn
+++ b/mojo/common/BUILD.gn
@@ -31,9 +31,6 @@
if (is_win) {
sources += [ "logfont_win.mojom" ]
}
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- js_bindings_mode = "both"
}
mojom("read_only_buffer") {
diff --git a/net/interfaces/BUILD.gn b/net/interfaces/BUILD.gn
index cbccdbc..0778246 100644
--- a/net/interfaces/BUILD.gn
+++ b/net/interfaces/BUILD.gn
@@ -13,7 +13,4 @@
public_deps = [
"//url/mojo:url_mojom_gurl",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- use_new_js_bindings = false
}
diff --git a/url/mojo/BUILD.gn b/url/mojo/BUILD.gn
index 970ed7a..7d5e5d6 100644
--- a/url/mojo/BUILD.gn
+++ b/url/mojo/BUILD.gn
@@ -8,9 +8,6 @@
sources = [
"url.mojom",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- js_bindings_mode = "both"
}
mojom("url_mojom_origin") {
@@ -21,9 +18,6 @@
public_deps = [
":url_mojom_gurl",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- js_bindings_mode = "both"
}
mojom("test_url_mojom_gurl") {