@@ -120,16 +120,14 @@ void main() {
120120 controllerCompleter.complete (controller);
121121 },
122122 javascriptMode: JavascriptMode .unrestricted,
123- // TODO(iskakaushik): Remove this when collection literals makes it to stable.
124- // ignore: prefer_collection_literals
125- javascriptChannels: < JavascriptChannel > [
123+ javascriptChannels: < JavascriptChannel > {
126124 JavascriptChannel (
127125 name: 'Echo' ,
128126 onMessageReceived: (JavascriptMessage message) {
129127 messagesReceived.add (message.message);
130128 },
131129 ),
132- ]. toSet () ,
130+ } ,
133131 onPageStarted: (String url) {
134132 pageStarted.complete (null );
135133 },
@@ -180,16 +178,14 @@ void main() {
180178 onWebViewCreated: (WebViewController controller) {
181179 controllerCompleter.complete (controller);
182180 },
183- // TODO(iskakaushik): Remove this when collection literals makes it to stable.
184- // ignore: prefer_collection_literals
185- javascriptChannels: < JavascriptChannel > [
181+ javascriptChannels: < JavascriptChannel > {
186182 JavascriptChannel (
187183 name: 'Resize' ,
188184 onMessageReceived: (JavascriptMessage message) {
189185 resizeCompleter.complete (true );
190186 },
191187 ),
192- ]. toSet () ,
188+ } ,
193189 onPageStarted: (String url) {
194190 pageStarted.complete (null );
195191 },
@@ -327,7 +323,222 @@ void main() {
327323 expect (customUserAgent2, defaultPlatformUserAgent);
328324 });
329325
330- group ('Media playback policy' , () {
326+ group ('Video playback policy' , () {
327+ String videoTestBase64;
328+ setUpAll (() async {
329+ final ByteData videoData =
330+ await rootBundle.load ('assets/sample_video.mp4' );
331+ final String base64VideoData =
332+ base64Encode (Uint8List .view (videoData.buffer));
333+ final String videoTest = '''
334+ <!DOCTYPE html><html>
335+ <head><title>Video auto play</title>
336+ <script type="text/javascript">
337+ function play() {
338+ var video = document.getElementById("video");
339+ video.play();
340+ }
341+ function isPaused() {
342+ var video = document.getElementById("video");
343+ return video.paused;
344+ }
345+ function isFullScreen() {
346+ var video = document.getElementById("video");
347+ return video.webkitDisplayingFullscreen;
348+ }
349+ </script>
350+ </head>
351+ <body onload="play();">
352+ <video controls playsinline autoplay id="video">
353+ <source src="data:video/mp4;charset=utf-8;base64,$base64VideoData ">
354+ </video>
355+ </body>
356+ </html>
357+ ''' ;
358+ videoTestBase64 = base64Encode (const Utf8Encoder ().convert (videoTest));
359+ });
360+
361+ test ('Auto media playback' , () async {
362+ Completer <WebViewController > controllerCompleter =
363+ Completer <WebViewController >();
364+ Completer <void > pageLoaded = Completer <void >();
365+
366+ await pumpWidget (
367+ Directionality (
368+ textDirection: TextDirection .ltr,
369+ child: WebView (
370+ key: GlobalKey (),
371+ initialUrl: 'data:text/html;charset=utf-8;base64,$videoTestBase64 ' ,
372+ onWebViewCreated: (WebViewController controller) {
373+ controllerCompleter.complete (controller);
374+ },
375+ javascriptMode: JavascriptMode .unrestricted,
376+ onPageFinished: (String url) {
377+ pageLoaded.complete (null );
378+ },
379+ initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy .always_allow,
380+ ),
381+ ),
382+ );
383+ WebViewController controller = await controllerCompleter.future;
384+ await pageLoaded.future;
385+
386+ String isPaused = await controller.evaluateJavascript ('isPaused();' );
387+ expect (isPaused, _webviewBool (false ));
388+
389+ controllerCompleter = Completer <WebViewController >();
390+ pageLoaded = Completer <void >();
391+
392+ // We change the key to re-create a new webview as we change the initialMediaPlaybackPolicy
393+ await pumpWidget (
394+ Directionality (
395+ textDirection: TextDirection .ltr,
396+ child: WebView (
397+ key: GlobalKey (),
398+ initialUrl: 'data:text/html;charset=utf-8;base64,$videoTestBase64 ' ,
399+ onWebViewCreated: (WebViewController controller) {
400+ controllerCompleter.complete (controller);
401+ },
402+ javascriptMode: JavascriptMode .unrestricted,
403+ onPageFinished: (String url) {
404+ pageLoaded.complete (null );
405+ },
406+ initialMediaPlaybackPolicy:
407+ AutoMediaPlaybackPolicy .require_user_action_for_all_media_types,
408+ ),
409+ ),
410+ );
411+
412+ controller = await controllerCompleter.future;
413+ await pageLoaded.future;
414+
415+ isPaused = await controller.evaluateJavascript ('isPaused();' );
416+ expect (isPaused, _webviewBool (true ));
417+ });
418+
419+ test ('Changes to initialMediaPlaybackPolicy are ignored' , () async {
420+ final Completer <WebViewController > controllerCompleter =
421+ Completer <WebViewController >();
422+ Completer <void > pageLoaded = Completer <void >();
423+
424+ final GlobalKey key = GlobalKey ();
425+ await pumpWidget (
426+ Directionality (
427+ textDirection: TextDirection .ltr,
428+ child: WebView (
429+ key: key,
430+ initialUrl: 'data:text/html;charset=utf-8;base64,$videoTestBase64 ' ,
431+ onWebViewCreated: (WebViewController controller) {
432+ controllerCompleter.complete (controller);
433+ },
434+ javascriptMode: JavascriptMode .unrestricted,
435+ onPageFinished: (String url) {
436+ pageLoaded.complete (null );
437+ },
438+ initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy .always_allow,
439+ ),
440+ ),
441+ );
442+ final WebViewController controller = await controllerCompleter.future;
443+ await pageLoaded.future;
444+
445+ String isPaused = await controller.evaluateJavascript ('isPaused();' );
446+ expect (isPaused, _webviewBool (false ));
447+
448+ pageLoaded = Completer <void >();
449+
450+ await pumpWidget (
451+ Directionality (
452+ textDirection: TextDirection .ltr,
453+ child: WebView (
454+ key: key,
455+ initialUrl: 'data:text/html;charset=utf-8;base64,$videoTestBase64 ' ,
456+ onWebViewCreated: (WebViewController controller) {
457+ controllerCompleter.complete (controller);
458+ },
459+ javascriptMode: JavascriptMode .unrestricted,
460+ onPageFinished: (String url) {
461+ pageLoaded.complete (null );
462+ },
463+ initialMediaPlaybackPolicy:
464+ AutoMediaPlaybackPolicy .require_user_action_for_all_media_types,
465+ ),
466+ ),
467+ );
468+
469+ await controller.reload ();
470+
471+ await pageLoaded.future;
472+
473+ isPaused = await controller.evaluateJavascript ('isPaused();' );
474+ expect (isPaused, _webviewBool (false ));
475+ });
476+
477+ test ('Video plays inline when allowsInlineMediaPlayback is true' , () async {
478+ if (Platform .isIOS) {
479+ Completer <WebViewController > controllerCompleter =
480+ Completer <WebViewController >();
481+ Completer <void > pageLoaded = Completer <void >();
482+
483+ await pumpWidget (
484+ Directionality (
485+ textDirection: TextDirection .ltr,
486+ child: WebView (
487+ key: GlobalKey (),
488+ initialUrl:
489+ 'data:text/html;charset=utf-8;base64,$videoTestBase64 ' ,
490+ onWebViewCreated: (WebViewController controller) {
491+ controllerCompleter.complete (controller);
492+ },
493+ javascriptMode: JavascriptMode .unrestricted,
494+ onPageFinished: (String url) {
495+ pageLoaded.complete (null );
496+ },
497+ initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy .always_allow,
498+ allowsInlineMediaPlayback: true ,
499+ ),
500+ ),
501+ );
502+ WebViewController controller = await controllerCompleter.future;
503+ await pageLoaded.future;
504+
505+ String isFullScreen =
506+ await controller.evaluateJavascript ('isFullScreen();' );
507+ expect (isFullScreen, _webviewBool (false ));
508+
509+ controllerCompleter = Completer <WebViewController >();
510+ pageLoaded = Completer <void >();
511+
512+ await pumpWidget (
513+ Directionality (
514+ textDirection: TextDirection .ltr,
515+ child: WebView (
516+ key: GlobalKey (),
517+ initialUrl:
518+ 'data:text/html;charset=utf-8;base64,$videoTestBase64 ' ,
519+ onWebViewCreated: (WebViewController controller) {
520+ controllerCompleter.complete (controller);
521+ },
522+ javascriptMode: JavascriptMode .unrestricted,
523+ onPageFinished: (String url) {
524+ pageLoaded.complete (null );
525+ },
526+ initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy .always_allow,
527+ allowsInlineMediaPlayback: false ,
528+ ),
529+ ),
530+ );
531+
532+ controller = await controllerCompleter.future;
533+ await pageLoaded.future;
534+
535+ isFullScreen = await controller.evaluateJavascript ('isFullScreen();' );
536+ expect (isFullScreen, _webviewBool (true ));
537+ }
538+ });
539+ });
540+
541+ group ('Audio playback policy' , () {
331542 String audioTestBase64;
332543 setUpAll (() async {
333544 final ByteData audioData =
0 commit comments