OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 var mediaRouter; | |
6 | |
7 define('media_router_bindings', [ | |
8 'content/public/renderer/frame_interfaces', | |
9 'chrome/browser/media/router/mojo/media_controller.mojom', | |
10 'chrome/browser/media/router/mojo/media_router.mojom', | |
11 'chrome/browser/media/router/mojo/media_status.mojom', | |
12 'extensions/common/mojo/keep_alive.mojom', | |
13 'mojo/common/time.mojom', | |
14 'mojo/public/js/bindings', | |
15 'net/interfaces/ip_address.mojom', | |
16 'url/mojo/origin.mojom', | |
17 'url/mojo/url.mojom', | |
18 ], function(frameInterfaces, | |
19 mediaControllerMojom, | |
20 mediaRouterMojom, | |
21 mediaStatusMojom, | |
22 keepAliveMojom, | |
23 timeMojom, | |
24 bindings, | |
25 ipAddressMojom, | |
26 originMojom, | |
27 urlMojom) { | |
28 'use strict'; | |
29 | |
30 /** | |
31 * Converts a media sink to a MediaSink Mojo object. | |
32 * @param {!MediaSink} sink A media sink. | |
33 * @return {!mediaRouterMojom.MediaSink} A Mojo MediaSink object. | |
34 */ | |
35 function sinkToMojo_(sink) { | |
36 return new mediaRouterMojom.MediaSink({ | |
37 'name': sink.friendlyName, | |
38 'description': sink.description, | |
39 'domain': sink.domain, | |
40 'sink_id': sink.id, | |
41 'icon_type': sinkIconTypeToMojo(sink.iconType), | |
42 }); | |
43 } | |
44 | |
45 /** | |
46 * Converts a media sink's icon type to a MediaSink.IconType Mojo object. | |
47 * @param {!MediaSink.IconType} type A media sink's icon type. | |
48 * @return {!mediaRouterMojom.MediaSink.IconType} A Mojo MediaSink.IconType | |
49 * object. | |
50 */ | |
51 function sinkIconTypeToMojo(type) { | |
52 switch (type) { | |
53 case 'cast': | |
54 return mediaRouterMojom.MediaSink.IconType.CAST; | |
55 case 'cast_audio': | |
56 return mediaRouterMojom.MediaSink.IconType.CAST_AUDIO; | |
57 case 'cast_audio_group': | |
58 return mediaRouterMojom.MediaSink.IconType.CAST_AUDIO_GROUP; | |
59 case 'generic': | |
60 return mediaRouterMojom.MediaSink.IconType.GENERIC; | |
61 case 'hangout': | |
62 return mediaRouterMojom.MediaSink.IconType.HANGOUT; | |
63 case 'meeting': | |
64 return mediaRouterMojom.MediaSink.IconType.MEETING; | |
65 default: | |
66 console.error('Unknown sink icon type : ' + type); | |
67 return mediaRouterMojom.MediaSink.IconType.GENERIC; | |
68 } | |
69 } | |
70 | |
71 /** | |
72 * Returns a Mojo MediaRoute object given a MediaRoute and a | |
73 * media sink name. | |
74 * @param {!MediaRoute} route | |
75 * @return {!mojo.MediaRoute} | |
76 */ | |
77 function routeToMojo_(route) { | |
78 return new mediaRouterMojom.MediaRoute({ | |
79 'media_route_id': route.id, | |
80 'media_source': route.mediaSource, | |
81 'media_sink_id': route.sinkId, | |
82 'description': route.description, | |
83 'icon_url': route.iconUrl, | |
84 'is_local': route.isLocal, | |
85 'custom_controller_path': route.customControllerPath, | |
86 // Begin newly added properties, followed by the milestone they were | |
87 // added. The guard should be safe to remove N+2 milestones later. | |
88 'for_display': route.forDisplay, // M47 | |
89 'is_incognito': !!route.offTheRecord, // M50 | |
90 'is_offscreen_presentation': !!route.isOffscreenPresentation // M56 | |
91 }); | |
92 } | |
93 | |
94 /** | |
95 * Converts a route message to a RouteMessage Mojo object. | |
96 * @param {!RouteMessage} message | |
97 * @return {!mediaRouterMojom.RouteMessage} A Mojo RouteMessage object. | |
98 */ | |
99 function messageToMojo_(message) { | |
100 if ("string" == typeof message.message) { | |
101 return new mediaRouterMojom.RouteMessage({ | |
102 'type': mediaRouterMojom.RouteMessage.Type.TEXT, | |
103 'message': message.message, | |
104 }); | |
105 } else { | |
106 return new mediaRouterMojom.RouteMessage({ | |
107 'type': mediaRouterMojom.RouteMessage.Type.BINARY, | |
108 'data': message.message, | |
109 }); | |
110 } | |
111 } | |
112 | |
113 /** | |
114 * Converts presentation connection state to Mojo enum value. | |
115 * @param {!string} state | |
116 * @return {!mediaRouterMojom.MediaRouter.PresentationConnectionState} | |
117 */ | |
118 function presentationConnectionStateToMojo_(state) { | |
119 var PresentationConnectionState = | |
120 mediaRouterMojom.MediaRouter.PresentationConnectionState; | |
121 switch (state) { | |
122 case 'connecting': | |
123 return PresentationConnectionState.CONNECTING; | |
124 case 'connected': | |
125 return PresentationConnectionState.CONNECTED; | |
126 case 'closed': | |
127 return PresentationConnectionState.CLOSED; | |
128 case 'terminated': | |
129 return PresentationConnectionState.TERMINATED; | |
130 default: | |
131 console.error('Unknown presentation connection state: ' + state); | |
132 return PresentationConnectionState.TERMINATED; | |
133 } | |
134 } | |
135 | |
136 /** | |
137 * Converts presentation connection close reason to Mojo enum value. | |
138 * @param {!string} reason | |
139 * @return {!mediaRouterMojom.MediaRouter.PresentationConnectionCloseReason} | |
140 */ | |
141 function presentationConnectionCloseReasonToMojo_(reason) { | |
142 var PresentationConnectionCloseReason = | |
143 mediaRouterMojom.MediaRouter.PresentationConnectionCloseReason; | |
144 switch (reason) { | |
145 case 'error': | |
146 return PresentationConnectionCloseReason.CONNECTION_ERROR; | |
147 case 'closed': | |
148 return PresentationConnectionCloseReason.CLOSED; | |
149 case 'went_away': | |
150 return PresentationConnectionCloseReason.WENT_AWAY; | |
151 default: | |
152 console.error('Unknown presentation connection close reason : ' + | |
153 reason); | |
154 return PresentationConnectionCloseReason.CONNECTION_ERROR; | |
155 } | |
156 } | |
157 | |
158 // TODO(crbug.com/688177): remove this conversion. | |
159 /** | |
160 * Converts Mojo origin to string. | |
161 * @param {!originMojom.Origin} Mojo origin | |
162 * @return {string} | |
163 */ | |
164 function mojoOriginToString_(origin) { | |
165 return origin.unique ? '' : | |
166 `${origin.scheme}:\/\/${origin.host}` + | |
167 `${origin.port ? `:${origin.port}` : ''}/` | |
168 } | |
169 | |
170 // TODO(crbug.com/688177): remove this conversion. | |
171 /** | |
172 * Converts string to Mojo origin. | |
173 * @param {string} origin | |
174 * @return {!originMojom.Origin} | |
175 */ | |
176 function stringToMojoOrigin_(origin) { | |
177 var url = new URL(origin); | |
178 var mojoOrigin = {}; | |
179 mojoOrigin.scheme = url.protocol.replace(':', ''); | |
180 mojoOrigin.host = url.hostname; | |
181 var port = url.port ? Number.parseInt(url.port) : 0; | |
182 switch (mojoOrigin.scheme) { | |
183 case 'http': | |
184 mojoOrigin.port = port || 80; | |
185 break; | |
186 case 'https': | |
187 mojoOrigin.port = port || 443; | |
188 break; | |
189 default: | |
190 throw new Error('Scheme must be http or https'); | |
191 } | |
192 return new originMojom.Origin(mojoOrigin); | |
193 } | |
194 | |
195 /** | |
196 * Parses the given route request Error object and converts it to the | |
197 * corresponding result code. | |
198 * @param {!Error} error | |
199 * @return {!mediaRouterMojom.RouteRequestResultCode} | |
200 */ | |
201 function getRouteRequestResultCode_(error) { | |
202 return error.errorCode ? error.errorCode : | |
203 mediaRouterMojom.RouteRequestResultCode.UNKNOWN_ERROR; | |
204 } | |
205 | |
206 /** | |
207 * Creates and returns a successful route response from given route. | |
208 * @param {!MediaRoute} route | |
209 * @return {!Object} | |
210 */ | |
211 function toSuccessRouteResponse_(route) { | |
212 return { | |
213 route: routeToMojo_(route), | |
214 result_code: mediaRouterMojom.RouteRequestResultCode.OK | |
215 }; | |
216 } | |
217 | |
218 /** | |
219 * Creates and returns a error route response from given Error object. | |
220 * @param {!Error} error | |
221 * @return {!Object} | |
222 */ | |
223 function toErrorRouteResponse_(error) { | |
224 return { | |
225 error_text: error.message, | |
226 result_code: getRouteRequestResultCode_(error) | |
227 }; | |
228 } | |
229 | |
230 /** | |
231 * Creates a new MediaRouter. | |
232 * Converts a route struct to its Mojo form. | |
233 * @param {!mediaRouterMojom.MediaRouterPtr} service | |
234 * @constructor | |
235 */ | |
236 function MediaRouter(service) { | |
237 /** | |
238 * The Mojo service proxy. Allows extension code to call methods that reside | |
239 * in the browser. | |
240 * @type {!mediaRouterMojom.MediaRouterPtr} | |
241 */ | |
242 this.service_ = service; | |
243 | |
244 /** | |
245 * The provider manager service delegate. Its methods are called by the | |
246 * browser-resident Mojo service. | |
247 * @type {!MediaRouter} | |
248 */ | |
249 this.mrpm_ = new MediaRouteProvider(this); | |
250 | |
251 /** | |
252 * Handle to a KeepAlive service object, which prevents the extension from | |
253 * being suspended as long as it remains in scope. | |
254 * @type {boolean} | |
255 */ | |
256 this.keepAlive_ = null; | |
257 | |
258 /** | |
259 * The bindings to bind the service delegate to the Mojo interface. | |
260 * Object must remain in scope for the lifetime of the connection to | |
261 * prevent the connection from closing automatically. | |
262 * @type {!bindings.Binding} | |
263 */ | |
264 this.mediaRouteProviderBinding_ = new bindings.Binding( | |
265 mediaRouterMojom.MediaRouteProvider, this.mrpm_); | |
266 } | |
267 | |
268 /** | |
269 * Returns definitions of Mojo core and generated Mojom classes that can be | |
270 * used directly by the component. | |
271 * @return {!Object} | |
272 * TODO(imcheng): We should export these along with MediaRouter. This requires | |
273 * us to modify the component to handle multiple exports. When that logic is | |
274 * baked in for a couple of milestones, we should be able to remove this | |
275 * method. | |
276 */ | |
277 MediaRouter.prototype.getMojoExports = function() { | |
278 return { | |
279 Binding: bindings.Binding, | |
280 DialMediaSink: mediaRouterMojom.DialMediaSink, | |
281 CastMediaSink: mediaRouterMojom.CastMediaSink, | |
282 IPAddress: ipAddressMojom.IPAddress, | |
283 InterfacePtrController: bindings.InterfacePtrController, | |
284 InterfaceRequest: bindings.InterfaceRequest, | |
285 MediaController: mediaControllerMojom.MediaController, | |
286 MediaStatus: mediaStatusMojom.MediaStatus, | |
287 MediaStatusObserverPtr: mediaStatusMojom.MediaStatusObserverPtr, | |
288 Sink: mediaRouterMojom.MediaSink, | |
289 SinkExtraData: mediaRouterMojom.MediaSinkExtraData, | |
290 TimeDelta: timeMojom.TimeDelta, | |
291 Url: urlMojom.Url, | |
292 }; | |
293 }; | |
294 | |
295 /** | |
296 * Registers the Media Router Provider Manager with the Media Router. | |
297 * @return {!Promise<string>} Instance ID for the Media Router. | |
298 */ | |
299 MediaRouter.prototype.start = function() { | |
300 return this.service_.registerMediaRouteProvider( | |
301 this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then( | |
302 function(result) { | |
303 return result.instance_id; | |
304 }.bind(this)); | |
305 } | |
306 | |
307 /** | |
308 * Sets the service delegate methods. | |
309 * @param {Object} handlers | |
310 */ | |
311 MediaRouter.prototype.setHandlers = function(handlers) { | |
312 this.mrpm_.setHandlers(handlers); | |
313 } | |
314 | |
315 /** | |
316 * The keep alive status. | |
317 * @return {boolean} | |
318 */ | |
319 MediaRouter.prototype.getKeepAlive = function() { | |
320 return this.keepAlive_ != null; | |
321 }; | |
322 | |
323 /** | |
324 * Called by the provider manager when a sink list for a given source is | |
325 * updated. | |
326 * @param {!string} sourceUrn | |
327 * @param {!Array<!MediaSink>} sinks | |
328 * @param {!Array<string>} origins | |
329 */ | |
330 MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, | |
331 origins) { | |
332 this.service_.onSinksReceived(sourceUrn, sinks.map(sinkToMojo_), | |
333 origins.map(stringToMojoOrigin_)); | |
334 }; | |
335 | |
336 /** | |
337 * Called by the provider manager when a sink is found to notify the MR of the | |
338 * sink's ID. The actual sink will be returned through the normal sink list | |
339 * update process, so this helps the MR identify the search result in the | |
340 * list. | |
341 * @param {string} pseudoSinkId ID of the pseudo sink that started the | |
342 * search. | |
343 * @param {string} sinkId ID of the newly-found sink. | |
344 */ | |
345 MediaRouter.prototype.onSearchSinkIdReceived = function( | |
346 pseudoSinkId, sinkId) { | |
347 this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId); | |
348 }; | |
349 | |
350 /** | |
351 * Called by the provider manager to keep the extension from suspending | |
352 * if it enters a state where suspension is undesirable (e.g. there is an | |
353 * active MediaRoute.) | |
354 * If keepAlive is true, the extension is kept alive. | |
355 * If keepAlive is false, the extension is allowed to suspend. | |
356 * @param {boolean} keepAlive | |
357 */ | |
358 MediaRouter.prototype.setKeepAlive = function(keepAlive) { | |
359 if (keepAlive === false && this.keepAlive_) { | |
360 this.keepAlive_.ptr.reset(); | |
361 this.keepAlive_ = null; | |
362 } else if (keepAlive === true && !this.keepAlive_) { | |
363 this.keepAlive_ = new keepAliveMojom.KeepAlivePtr( | |
364 frameInterfaces.getInterface(keepAliveMojom.KeepAlive.name)); | |
365 } | |
366 }; | |
367 | |
368 /** | |
369 * Called by the provider manager to send an issue from a media route | |
370 * provider to the Media Router, to show the user. | |
371 * @param {!Object} issue The issue object. | |
372 */ | |
373 MediaRouter.prototype.onIssue = function(issue) { | |
374 function issueSeverityToMojo_(severity) { | |
375 switch (severity) { | |
376 case 'fatal': | |
377 return mediaRouterMojom.Issue.Severity.FATAL; | |
378 case 'warning': | |
379 return mediaRouterMojom.Issue.Severity.WARNING; | |
380 case 'notification': | |
381 return mediaRouterMojom.Issue.Severity.NOTIFICATION; | |
382 default: | |
383 console.error('Unknown issue severity: ' + severity); | |
384 return mediaRouterMojom.Issue.Severity.NOTIFICATION; | |
385 } | |
386 } | |
387 | |
388 function issueActionToMojo_(action) { | |
389 switch (action) { | |
390 case 'dismiss': | |
391 return mediaRouterMojom.Issue.ActionType.DISMISS; | |
392 case 'learn_more': | |
393 return mediaRouterMojom.Issue.ActionType.LEARN_MORE; | |
394 default: | |
395 console.error('Unknown issue action type : ' + action); | |
396 return mediaRouterMojom.Issue.ActionType.OK; | |
397 } | |
398 } | |
399 | |
400 var secondaryActions = (issue.secondaryActions || []).map(function(e) { | |
401 return issueActionToMojo_(e); | |
402 }); | |
403 this.service_.onIssue(new mediaRouterMojom.Issue({ | |
404 'route_id': issue.routeId, | |
405 'severity': issueSeverityToMojo_(issue.severity), | |
406 'title': issue.title, | |
407 'message': issue.message, | |
408 'default_action': issueActionToMojo_(issue.defaultAction), | |
409 'secondary_actions': secondaryActions, | |
410 'help_page_id': issue.helpPageId, | |
411 'is_blocking': issue.isBlocking | |
412 })); | |
413 }; | |
414 | |
415 /** | |
416 * Called by the provider manager when the set of active routes | |
417 * has been updated. | |
418 * @param {!Array<MediaRoute>} routes The active set of media routes. | |
419 * @param {string=} sourceUrn The sourceUrn associated with this route | |
420 * query. | |
421 * @param {Array<string>=} joinableRouteIds The active set of joinable | |
422 * media routes. | |
423 */ | |
424 MediaRouter.prototype.onRoutesUpdated = | |
425 function(routes, sourceUrn = '', joinableRouteIds = []) { | |
426 this.service_.onRoutesUpdated( | |
427 routes.map(routeToMojo_), | |
428 sourceUrn, | |
429 joinableRouteIds); | |
430 }; | |
431 | |
432 /** | |
433 * Called by the provider manager when sink availability has been updated. | |
434 * @param {!mediaRouterMojom.MediaRouter.SinkAvailability} availability | |
435 * The new sink availability. | |
436 */ | |
437 MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) { | |
438 this.service_.onSinkAvailabilityUpdated(availability); | |
439 }; | |
440 | |
441 /** | |
442 * Called by the provider manager when the state of a presentation connected | |
443 * to a route has changed. | |
444 * @param {string} routeId | |
445 * @param {string} state | |
446 */ | |
447 MediaRouter.prototype.onPresentationConnectionStateChanged = | |
448 function(routeId, state) { | |
449 this.service_.onPresentationConnectionStateChanged( | |
450 routeId, presentationConnectionStateToMojo_(state)); | |
451 }; | |
452 | |
453 /** | |
454 * Called by the provider manager when the state of a presentation connected | |
455 * to a route has closed. | |
456 * @param {string} routeId | |
457 * @param {string} reason | |
458 * @param {string} message | |
459 */ | |
460 MediaRouter.prototype.onPresentationConnectionClosed = | |
461 function(routeId, reason, message) { | |
462 this.service_.onPresentationConnectionClosed( | |
463 routeId, presentationConnectionCloseReasonToMojo_(reason), message); | |
464 }; | |
465 | |
466 /** | |
467 * @param {string} routeId | |
468 * @param {!Array<!RouteMessage>} mesages | |
469 */ | |
470 MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) { | |
471 this.service_.onRouteMessagesReceived( | |
472 routeId, messages.map(messageToMojo_)); | |
473 }; | |
474 | |
475 /** | |
476 * Object containing callbacks set by the provider manager. | |
477 * | |
478 * @constructor | |
479 * @struct | |
480 */ | |
481 function MediaRouterHandlers() { | |
482 /** | |
483 * @type {function(!string, !string, !string, !string, !number)} | |
484 */ | |
485 this.createRoute = null; | |
486 | |
487 /** | |
488 * @type {function(!string, !string, !string, !number)} | |
489 */ | |
490 this.joinRoute = null; | |
491 | |
492 /** | |
493 * @type {function(string): Promise} | |
494 */ | |
495 this.terminateRoute = null; | |
496 | |
497 /** | |
498 * @type {function(string)} | |
499 */ | |
500 this.startObservingMediaSinks = null; | |
501 | |
502 /** | |
503 * @type {function(string)} | |
504 */ | |
505 this.stopObservingMediaSinks = null; | |
506 | |
507 /** | |
508 * @type {function(string, string): Promise} | |
509 */ | |
510 this.sendRouteMessage = null; | |
511 | |
512 /** | |
513 * @type {function(string, Uint8Array): Promise} | |
514 */ | |
515 this.sendRouteBinaryMessage = null; | |
516 | |
517 /** | |
518 * @type {function(string)} | |
519 */ | |
520 this.startListeningForRouteMessages = null; | |
521 | |
522 /** | |
523 * @type {function(string)} | |
524 */ | |
525 this.stopListeningForRouteMessages = null; | |
526 | |
527 /** | |
528 * @type {function(string)} | |
529 */ | |
530 this.detachRoute = null; | |
531 | |
532 /** | |
533 * @type {function()} | |
534 */ | |
535 this.startObservingMediaRoutes = null; | |
536 | |
537 /** | |
538 * @type {function()} | |
539 */ | |
540 this.stopObservingMediaRoutes = null; | |
541 | |
542 /** | |
543 * @type {function()} | |
544 */ | |
545 this.connectRouteByRouteId = null; | |
546 | |
547 /** | |
548 * @type {function()} | |
549 */ | |
550 this.enableMdnsDiscovery = null; | |
551 | |
552 /** | |
553 * @type {function()} | |
554 */ | |
555 this.updateMediaSinks = null; | |
556 | |
557 /** | |
558 * @type {function(string, string, !SinkSearchCriteria): string} | |
559 */ | |
560 this.searchSinks = null; | |
561 | |
562 /** | |
563 * @type {function()} | |
564 */ | |
565 this.provideSinks = null; | |
566 | |
567 /** | |
568 * @type {function(string, !bindings.InterfaceRequest): !Promise<boolean>} | |
569 */ | |
570 this.createMediaRouteController = null; | |
571 | |
572 /** | |
573 * @type {function(string, !mediaStatusMojom.MediaStatusObserverPtr)} | |
574 */ | |
575 this.setMediaRouteStatusObserver = null; | |
576 }; | |
577 | |
578 /** | |
579 * Routes calls from Media Router to the provider manager extension. | |
580 * Registered with the MediaRouter stub. | |
581 * @param {!MediaRouter} MediaRouter proxy to call into the | |
582 * Media Router mojo interface. | |
583 * @constructor | |
584 */ | |
585 function MediaRouteProvider(mediaRouter) { | |
586 /** | |
587 * Object containing JS callbacks into Provider Manager code. | |
588 * @type {!MediaRouterHandlers} | |
589 */ | |
590 this.handlers_ = new MediaRouterHandlers(); | |
591 | |
592 /** | |
593 * Proxy class to the browser's Media Router Mojo service. | |
594 * @type {!MediaRouter} | |
595 */ | |
596 this.mediaRouter_ = mediaRouter; | |
597 } | |
598 | |
599 /* | |
600 * Sets the callback handler used to invoke methods in the provider manager. | |
601 * | |
602 * @param {!MediaRouterHandlers} handlers | |
603 */ | |
604 MediaRouteProvider.prototype.setHandlers = function(handlers) { | |
605 // TODO(mfoltz): Remove when component that supports this method is | |
606 // rolled out to all Chrome channels in M56. | |
607 if (!handlers['onBeforeInvokeHandler']) | |
608 handlers['onBeforeInvokeHandler'] = () => {}; | |
609 this.handlers_ = handlers; | |
610 var requiredHandlers = [ | |
611 'stopObservingMediaRoutes', | |
612 'startObservingMediaRoutes', | |
613 'sendRouteMessage', | |
614 'sendRouteBinaryMessage', | |
615 'startListeningForRouteMessages', | |
616 'stopListeningForRouteMessages', | |
617 'detachRoute', | |
618 'terminateRoute', | |
619 'joinRoute', | |
620 'createRoute', | |
621 'stopObservingMediaSinks', | |
622 'startObservingMediaRoutes', | |
623 'connectRouteByRouteId', | |
624 'enableMdnsDiscovery', | |
625 'updateMediaSinks', | |
626 'searchSinks', | |
627 'provideSinks', | |
628 'createMediaRouteController', | |
629 'setMediaRouteStatusObserver', | |
630 'onBeforeInvokeHandler' | |
631 ]; | |
632 requiredHandlers.forEach(function(nextHandler) { | |
633 if (handlers[nextHandler] === undefined) { | |
634 console.error(nextHandler + ' handler not registered.'); | |
635 } | |
636 }); | |
637 } | |
638 | |
639 /** | |
640 * Starts querying for sinks capable of displaying the media source | |
641 * designated by |sourceUrn|. Results are returned by calling | |
642 * OnSinksReceived. | |
643 * @param {!string} sourceUrn | |
644 */ | |
645 MediaRouteProvider.prototype.startObservingMediaSinks = | |
646 function(sourceUrn) { | |
647 this.handlers_.onBeforeInvokeHandler(); | |
648 this.handlers_.startObservingMediaSinks(sourceUrn); | |
649 }; | |
650 | |
651 /** | |
652 * Stops querying for sinks capable of displaying |sourceUrn|. | |
653 * @param {!string} sourceUrn | |
654 */ | |
655 MediaRouteProvider.prototype.stopObservingMediaSinks = | |
656 function(sourceUrn) { | |
657 this.handlers_.onBeforeInvokeHandler(); | |
658 this.handlers_.stopObservingMediaSinks(sourceUrn); | |
659 }; | |
660 | |
661 /** | |
662 * Requests that |sinkId| render the media referenced by |sourceUrn|. If the | |
663 * request is from the Presentation API, then origin and tabId will | |
664 * be populated. | |
665 * @param {!string} sourceUrn Media source to render. | |
666 * @param {!string} sinkId Media sink ID. | |
667 * @param {!string} presentationId Presentation ID from the site | |
668 * requesting presentation. TODO(mfoltz): Remove. | |
669 * @param {!originMojom.Origin} origin Origin of site requesting presentation. | |
670 * @param {!number} tabId ID of tab requesting presentation. | |
671 * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for | |
672 * the request. Otherwise, the default duration will be used. | |
673 * @param {!boolean} incognito If true, the route is being requested by | |
674 * an incognito profile. | |
675 * @return {!Promise.<!Object>} A Promise resolving to an object describing | |
676 * the newly created media route, or rejecting with an error message on | |
677 * failure. | |
678 */ | |
679 MediaRouteProvider.prototype.createRoute = | |
680 function(sourceUrn, sinkId, presentationId, origin, tabId, | |
681 timeout, incognito) { | |
682 this.handlers_.onBeforeInvokeHandler(); | |
683 return this.handlers_.createRoute( | |
684 sourceUrn, sinkId, presentationId, mojoOriginToString_(origin), tabId, | |
685 Math.floor(timeout.microseconds / 1000), incognito) | |
686 .then(function(route) { | |
687 return toSuccessRouteResponse_(route); | |
688 }, | |
689 function(err) { | |
690 return toErrorRouteResponse_(err); | |
691 }); | |
692 }; | |
693 | |
694 /** | |
695 * Handles a request via the Presentation API to join an existing route given | |
696 * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for | |
697 * validating same-origin/tab scope. | |
698 * @param {!string} sourceUrn Media source to render. | |
699 * @param {!string} presentationId Presentation ID to join. | |
700 * @param {!originMojom.Origin} origin Origin of site requesting join. | |
701 * @param {!number} tabId ID of tab requesting join. | |
702 * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for | |
703 * the request. Otherwise, the default duration will be used. | |
704 * @param {!boolean} incognito If true, the route is being requested by | |
705 * an incognito profile. | |
706 * @return {!Promise.<!Object>} A Promise resolving to an object describing | |
707 * the newly created media route, or rejecting with an error message on | |
708 * failure. | |
709 */ | |
710 MediaRouteProvider.prototype.joinRoute = | |
711 function(sourceUrn, presentationId, origin, tabId, timeout, | |
712 incognito) { | |
713 this.handlers_.onBeforeInvokeHandler(); | |
714 return this.handlers_.joinRoute( | |
715 sourceUrn, presentationId, mojoOriginToString_(origin), tabId, | |
716 Math.floor(timeout.microseconds / 1000), incognito) | |
717 .then(function(route) { | |
718 return toSuccessRouteResponse_(route); | |
719 }, | |
720 function(err) { | |
721 return toErrorRouteResponse_(err); | |
722 }); | |
723 }; | |
724 | |
725 /** | |
726 * Handles a request via the Presentation API to join an existing route given | |
727 * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for | |
728 * validating same-origin/tab scope. | |
729 * @param {!string} sourceUrn Media source to render. | |
730 * @param {!string} routeId Route ID to join. | |
731 * @param {!string} presentationId Presentation ID to join. | |
732 * @param {!originMojom.Origin} origin Origin of site requesting join. | |
733 * @param {!number} tabId ID of tab requesting join. | |
734 * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for | |
735 * the request. Otherwise, the default duration will be used. | |
736 * @param {!boolean} incognito If true, the route is being requested by | |
737 * an incognito profile. | |
738 * @return {!Promise.<!Object>} A Promise resolving to an object describing | |
739 * the newly created media route, or rejecting with an error message on | |
740 * failure. | |
741 */ | |
742 MediaRouteProvider.prototype.connectRouteByRouteId = | |
743 function(sourceUrn, routeId, presentationId, origin, tabId, | |
744 timeout, incognito) { | |
745 this.handlers_.onBeforeInvokeHandler(); | |
746 return this.handlers_.connectRouteByRouteId( | |
747 sourceUrn, routeId, presentationId, mojoOriginToString_(origin), tabId, | |
748 Math.floor(timeout.microseconds / 1000), incognito) | |
749 .then(function(route) { | |
750 return toSuccessRouteResponse_(route); | |
751 }, | |
752 function(err) { | |
753 return toErrorRouteResponse_(err); | |
754 }); | |
755 }; | |
756 | |
757 /** | |
758 * Terminates the route specified by |routeId|. | |
759 * @param {!string} routeId | |
760 * @return {!Promise<!Object>} A Promise resolving to an object describing | |
761 * the result of the terminate operation, or rejecting with an error | |
762 * message and code if the operation failed. | |
763 */ | |
764 MediaRouteProvider.prototype.terminateRoute = function(routeId) { | |
765 this.handlers_.onBeforeInvokeHandler(); | |
766 return this.handlers_.terminateRoute(routeId).then( | |
767 () => ({result_code: mediaRouterMojom.RouteRequestResultCode.OK}), | |
768 (err) => toErrorRouteResponse_(err)); | |
769 }; | |
770 | |
771 /** | |
772 * Posts a message to the route designated by |routeId|. | |
773 * @param {!string} routeId | |
774 * @param {!string} message | |
775 * @return {!Promise.<boolean>} Resolved with true if the message was sent, | |
776 * or false on failure. | |
777 */ | |
778 MediaRouteProvider.prototype.sendRouteMessage = function( | |
779 routeId, message) { | |
780 this.handlers_.onBeforeInvokeHandler(); | |
781 return this.handlers_.sendRouteMessage(routeId, message) | |
782 .then(function() { | |
783 return {'sent': true}; | |
784 }, function() { | |
785 return {'sent': false}; | |
786 }); | |
787 }; | |
788 | |
789 /** | |
790 * Sends a binary message to the route designated by |routeId|. | |
791 * @param {!string} routeId | |
792 * @param {!Array<number>} data | |
793 * @return {!Promise.<boolean>} Resolved with true if the data was sent, | |
794 * or false on failure. | |
795 */ | |
796 MediaRouteProvider.prototype.sendRouteBinaryMessage = function( | |
797 routeId, data) { | |
798 this.handlers_.onBeforeInvokeHandler(); | |
799 return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data)) | |
800 .then(function() { | |
801 return {'sent': true}; | |
802 }, function() { | |
803 return {'sent': false}; | |
804 }); | |
805 }; | |
806 | |
807 /** | |
808 * Listen for messages from a route. | |
809 * @param {!string} routeId | |
810 */ | |
811 MediaRouteProvider.prototype.startListeningForRouteMessages = function( | |
812 routeId) { | |
813 this.handlers_.onBeforeInvokeHandler(); | |
814 this.handlers_.startListeningForRouteMessages(routeId); | |
815 }; | |
816 | |
817 /** | |
818 * @param {!string} routeId | |
819 */ | |
820 MediaRouteProvider.prototype.stopListeningForRouteMessages = function( | |
821 routeId) { | |
822 this.handlers_.onBeforeInvokeHandler(); | |
823 this.handlers_.stopListeningForRouteMessages(routeId); | |
824 }; | |
825 | |
826 /** | |
827 * Indicates that the presentation connection that was connected to |routeId| | |
828 * is no longer connected to it. | |
829 * @param {!string} routeId | |
830 */ | |
831 MediaRouteProvider.prototype.detachRoute = function( | |
832 routeId) { | |
833 this.handlers_.detachRoute(routeId); | |
834 }; | |
835 | |
836 /** | |
837 * Requests that the provider manager start sending information about active | |
838 * media routes to the Media Router. | |
839 * @param {!string} sourceUrn | |
840 */ | |
841 MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) { | |
842 this.handlers_.onBeforeInvokeHandler(); | |
843 this.handlers_.startObservingMediaRoutes(sourceUrn); | |
844 }; | |
845 | |
846 /** | |
847 * Requests that the provider manager stop sending information about active | |
848 * media routes to the Media Router. | |
849 * @param {!string} sourceUrn | |
850 */ | |
851 MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) { | |
852 this.handlers_.onBeforeInvokeHandler(); | |
853 this.handlers_.stopObservingMediaRoutes(sourceUrn); | |
854 }; | |
855 | |
856 /** | |
857 * Enables mDNS device discovery. | |
858 */ | |
859 MediaRouteProvider.prototype.enableMdnsDiscovery = function() { | |
860 this.handlers_.onBeforeInvokeHandler(); | |
861 this.handlers_.enableMdnsDiscovery(); | |
862 }; | |
863 | |
864 /** | |
865 * Requests that the provider manager update media sinks. | |
866 * @param {!string} sourceUrn | |
867 */ | |
868 MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) { | |
869 this.handlers_.onBeforeInvokeHandler(); | |
870 this.handlers_.updateMediaSinks(sourceUrn); | |
871 }; | |
872 | |
873 /** | |
874 * Requests that the provider manager search its providers for a sink matching | |
875 * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found | |
876 * that can be used immediately for route creation, its ID is returned. | |
877 * Otherwise the empty string is returned. | |
878 * | |
879 * @param {string} sinkId Sink ID of the pseudo sink generating the request. | |
880 * @param {string} sourceUrn Media source to be used with the sink. | |
881 * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route | |
882 * providers. | |
883 * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the | |
884 * sink ID of the sink found by the search that can be used for route | |
885 * creation, or the empty string if no route can be immediately created. | |
886 */ | |
887 MediaRouteProvider.prototype.searchSinks = function( | |
888 sinkId, sourceUrn, searchCriteria) { | |
889 this.handlers_.onBeforeInvokeHandler(); | |
890 const searchSinksResponse = | |
891 this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria); | |
892 | |
893 if ('string' == typeof searchSinksResponse) { | |
894 // TODO (zijiang): Remove this check when M59 is stable and the | |
895 // extension is always returning a promise. | |
896 return Promise.resolve({ | |
897 'sink_id': sink_id | |
898 }); | |
899 } | |
900 return searchSinksResponse.then( | |
901 sink_id => { | |
902 return { 'sink_id': sink_id }; | |
903 }, | |
904 () => { | |
905 return { 'sink_id': '' }; | |
906 }); | |
907 }; | |
908 | |
909 /** | |
910 * Notifies the provider manager that MediaRouter has discovered a list of | |
911 * sinks. | |
912 * @param {string} providerName | |
913 * @param {!Array<!mediaRouterMojom.MediaSink>} sinks | |
914 */ | |
915 MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) { | |
916 this.handlers_.onBeforeInvokeHandler(); | |
917 this.handlers_.provideSinks(providerName, sinks); | |
918 }; | |
919 | |
920 /** | |
921 * Creates a controller for the given route and binds the given | |
922 * InterfaceRequest to it. | |
923 * @param {string} routeId | |
924 * @param {!bindings.InterfaceRequest} controllerRequest | |
925 * @return {!Promise<!{success: boolean}>} Resolves to true if a controller | |
926 * is created. Resolves to false if a controller cannot be created, or if | |
927 * the controller is already bound. | |
928 */ | |
929 MediaRouteProvider.prototype.createMediaRouteController = function( | |
930 routeId, controllerRequest) { | |
931 // TODO(imcheng): Remove this check when M59 is in stable. | |
932 if (!this.handlers_.createMediaRouteController) { | |
933 return Promise.resolve({success: false}); | |
934 } | |
935 | |
936 this.handlers_.onBeforeInvokeHandler(); | |
937 this.handlers_.createMediaRouteController(routeId, controllerRequest) | |
938 .then(controller => {success: true}, | |
939 e => {success: false}); | |
940 } | |
941 | |
942 /** | |
943 * Sets the MediaStatus oberver for a given route. MediaStatus updates are | |
944 * notified via the given observer interface. | |
945 * @param {string} routeId | |
946 * @param {!mediaStatusMojom.MediaStatusObserverPtr} observer | |
947 */ | |
948 MediaRouteProvider.prototype.setMediaRouteStatusObserver = function( | |
949 routeId, observer) { | |
950 // TODO(imcheng): Remove this check when M59 is in stable. | |
951 if (!this.handlers_.setMediaRouteStatusObserver) { | |
952 return; | |
953 } | |
954 this.handlers_.onBeforeInvokeHandler(); | |
955 this.handlers_.setMediaRouteStatusObserver(routeId, observer); | |
956 }; | |
957 | |
958 mediaRouter = new MediaRouter(new mediaRouterMojom.MediaRouterPtr( | |
959 frameInterfaces.getInterface(mediaRouterMojom.MediaRouter.name))); | |
960 | |
961 return mediaRouter; | |
962 }); | |
OLD | NEW |