-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
flutter/engine
#24308Labels
P0Critical issues such as a build break or regressionCritical issues such as a build break or regressiona: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)a: platform-viewsEmbedding Android/iOS views in Flutter appsEmbedding Android/iOS views in Flutter appscustomer: mulligan (g3)found in release: 1.22Found to occur in 1.22Found to occur in 1.22has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: webviewThe WebView pluginThe WebView pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.platform-iosiOS applications specificallyiOS applications specificallyr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
Description
Internal: b/178003647
Reproduction with Youtube API + Webview Flutter plugin:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title, style: TextStyle(fontFamily: 'ProductSans')),
),
body: Center(
child: TextButton(
onPressed: () => _launchVideo(context), child: Text('Launch Video'),
),
),
);
}
Future<void> _launchVideo(BuildContext context) async {
await Navigator.push(
context,
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) => _buildPopover(context),
));
}
Widget _buildPopover(BuildContext context) {
return OrientationBuilder(
builder: (context, orientation) {
final isPortrait = orientation == Orientation.portrait;
return Scaffold(
appBar: isPortrait
? AppBar(
title: Text('Video', ),
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () async {
await Navigator.of(context).maybePop();
},
),
)
: null,
body: Container(
decoration: BoxDecoration(
color: Colors.black,
),
child: SafeArea(child: YoutubePlayerWidget()),
),
);
},
);
}
}
const _userAgent =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36';
const _aspectRatio = 16 / 9;
/// A youtube player widget which interacts with the underlying webview
/// to play YouTube videos.
class YoutubePlayerWidget extends StatefulWidget {
@override
_YoutubePlayerWidgetState createState() => _YoutubePlayerWidgetState();
}
class _YoutubePlayerWidgetState extends State<YoutubePlayerWidget> {
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: _aspectRatio,
child: IgnorePointer(
ignoring: false,
child: WebView(
key: widget.key,
userAgent: _userAgent,
initialUrl: _player,
javascriptMode: JavascriptMode.unrestricted,
initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
),
));
}
String get _player {
final _player = '''
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
margin: 0;
padding: 0;
background-color: #000000;
overflow: hidden;
position: fixed;
height: 100%;
width: 100%;
}
</style>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>
</head>
<body>
<div id="player"></div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
var timerId;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '100%',
width: '100%',
videoId: '6wnPeqh4m2k',
host: 'https://www.youtube.com',
playerVars: {
'controls': 1,
'playsinline': 1,
'enablejsapi': 1,
'fs': 0,
'rel': 0,
'showinfo': 0,
'iv_load_policy': 3,
'modestbranding': 1,
'cc_load_policy': 0,
'cc_lang_pref': 'en',
'autoplay': true
},
events: {
onError: (error) => Errors.postMessage(error.data)
},
});
}
</script>
</body>
</html>
''';
return 'data:text/html;base64,'
'${base64Encode(const Utf8Encoder().convert(_player))}';
}
}Steps:
- Tap launch video.
- After the video starts playing, enable picture-in-picture mode by tapping on this icon:
- Tap close button.
Observe that the video stops and the platform view is gone.
Now enable voiceover and repeat the same steps. You will see that after tapping close, the video continues to play. The dispose logic of platform view is not executed correctly with voiceover on.
Metadata
Metadata
Assignees
Labels
P0Critical issues such as a build break or regressionCritical issues such as a build break or regressiona: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)a: platform-viewsEmbedding Android/iOS views in Flutter appsEmbedding Android/iOS views in Flutter appscustomer: mulligan (g3)found in release: 1.22Found to occur in 1.22Found to occur in 1.22has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: webviewThe WebView pluginThe WebView pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.platform-iosiOS applications specificallyiOS applications specificallyr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
