diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 89e3a05b20e4..05cb63835da4 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,5 +1,9 @@ -## NEXT +## 6.0.0 +* **BREAKING CHANGE**: Removes `MethodChannelVideoPlayer`. The default + implementation is now only a placeholder with no functionality; + implementations of `video_player` must include their own `VideoPlayerPlatform` + Dart implementation. * Updates minimum Flutter version to 2.10. * Fixes violations of new analysis option use_named_constants. diff --git a/packages/video_player/video_player_platform_interface/CONTRIBUTING.md b/packages/video_player/video_player_platform_interface/CONTRIBUTING.md deleted file mode 100644 index 4108ae0d0030..000000000000 --- a/packages/video_player/video_player_platform_interface/CONTRIBUTING.md +++ /dev/null @@ -1,46 +0,0 @@ -## Updating pigeon-generated files - -**WARNING**: Because `messages.dart` is part of the public API of this package, -breaking changes in that file are breaking changes for the package. This means -that: -- You should never update the version of Pigeon used for this package unless - making a breaking change to the package for other reasons. -- Because the method channel is a legacy implementation for compatibility with - existing third-party `video_player` implementations, in many cases the best - option may be to simply not implemented new features in - `MethodChannelVideoPlayer`. Breaking changes in this package should never - be made solely to change `MethodChannelVideoPlayer`. - -### Update process - -If you update files in the pigeons/ directory, run the following -command in this directory (ignore the errors you get about -dependencies in the examples directory): - -```bash -flutter pub upgrade -flutter pub run pigeon --dart_null_safety --input pigeons/messages.dart -# git commit your changes so that your working environment is clean -(cd ../../../; ./script/tool_runner.sh format --clang-format=clang-format-7) -``` - -If you update pigeon itself and want to test the changes here, -temporarily update the pubspec.yaml by adding the following to the -`dependency_overrides` section, assuming you have checked out the -`flutter/packages` repo in a sibling directory to the `plugins` repo: - -```yaml - pigeon: - path: - ../../../../packages/packages/pigeon/ -``` - -Then, run the commands above. When you run `pub get` it should warn -you that you're using an override. If you do this, you will need to -publish pigeon before you can land the updates to this package, since -the CI tests run the analysis using latest published version of -pigeon, not your version or the version on `main`. - -In either case, the configuration will be obtained automatically from -the `pigeons/messages.dart` file (see `configurePigeon` at the bottom -of that file). diff --git a/packages/video_player/video_player_platform_interface/lib/messages.g.dart b/packages/video_player/video_player_platform_interface/lib/messages.g.dart deleted file mode 100644 index 831f4e3755d9..000000000000 --- a/packages/video_player/video_player_platform_interface/lib/messages.g.dart +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Autogenerated from Pigeon (v0.1.21), do not edit directly. -// See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, cast_nullable_to_non_nullable -// @dart = 2.12 -import 'dart:async'; -import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List; - -import 'package:flutter/services.dart'; - -class TextureMessage { - int? textureId; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['textureId'] = textureId; - return pigeonMap; - } - - static TextureMessage decode(Object message) { - final Map pigeonMap = message as Map; - return TextureMessage()..textureId = pigeonMap['textureId'] as int?; - } -} - -class CreateMessage { - String? asset; - String? uri; - String? packageName; - String? formatHint; - Map? httpHeaders; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['asset'] = asset; - pigeonMap['uri'] = uri; - pigeonMap['packageName'] = packageName; - pigeonMap['formatHint'] = formatHint; - pigeonMap['httpHeaders'] = httpHeaders; - return pigeonMap; - } - - static CreateMessage decode(Object message) { - final Map pigeonMap = message as Map; - return CreateMessage() - ..asset = pigeonMap['asset'] as String? - ..uri = pigeonMap['uri'] as String? - ..packageName = pigeonMap['packageName'] as String? - ..formatHint = pigeonMap['formatHint'] as String? - ..httpHeaders = pigeonMap['httpHeaders'] as Map?; - } -} - -class LoopingMessage { - int? textureId; - bool? isLooping; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['textureId'] = textureId; - pigeonMap['isLooping'] = isLooping; - return pigeonMap; - } - - static LoopingMessage decode(Object message) { - final Map pigeonMap = message as Map; - return LoopingMessage() - ..textureId = pigeonMap['textureId'] as int? - ..isLooping = pigeonMap['isLooping'] as bool?; - } -} - -class VolumeMessage { - int? textureId; - double? volume; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['textureId'] = textureId; - pigeonMap['volume'] = volume; - return pigeonMap; - } - - static VolumeMessage decode(Object message) { - final Map pigeonMap = message as Map; - return VolumeMessage() - ..textureId = pigeonMap['textureId'] as int? - ..volume = pigeonMap['volume'] as double?; - } -} - -class PlaybackSpeedMessage { - int? textureId; - double? speed; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['textureId'] = textureId; - pigeonMap['speed'] = speed; - return pigeonMap; - } - - static PlaybackSpeedMessage decode(Object message) { - final Map pigeonMap = message as Map; - return PlaybackSpeedMessage() - ..textureId = pigeonMap['textureId'] as int? - ..speed = pigeonMap['speed'] as double?; - } -} - -class PositionMessage { - int? textureId; - int? position; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['textureId'] = textureId; - pigeonMap['position'] = position; - return pigeonMap; - } - - static PositionMessage decode(Object message) { - final Map pigeonMap = message as Map; - return PositionMessage() - ..textureId = pigeonMap['textureId'] as int? - ..position = pigeonMap['position'] as int?; - } -} - -class MixWithOthersMessage { - bool? mixWithOthers; - - Object encode() { - final Map pigeonMap = {}; - pigeonMap['mixWithOthers'] = mixWithOthers; - return pigeonMap; - } - - static MixWithOthersMessage decode(Object message) { - final Map pigeonMap = message as Map; - return MixWithOthersMessage() - ..mixWithOthers = pigeonMap['mixWithOthers'] as bool?; - } -} - -class VideoPlayerApi { - Future initialize() async { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.initialize', StandardMessageCodec()); - final Map? replyMap = - await channel.send(null) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future create(CreateMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return TextureMessage.decode(replyMap['result']!); - } - } - - Future dispose(TextureMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future setLooping(LoopingMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setLooping', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future setVolume(VolumeMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setVolume', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future setPlaybackSpeed(PlaybackSpeedMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', - StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future play(TextureMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future position(TextureMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return PositionMessage.decode(replyMap['result']!); - } - } - - Future seekTo(PositionMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future pause(TextureMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } - - Future setMixWithOthers(MixWithOthersMessage arg) async { - final Object encoded = arg.encode(); - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', - StandardMessageCodec()); - final Map? replyMap = - await channel.send(encoded) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null, - ); - } else if (replyMap['error'] != null) { - final Map error = - replyMap['error'] as Map; - throw PlatformException( - code: error['code'] as String, - message: error['message'] as String?, - details: error['details'], - ); - } else { - // noop - } - } -} diff --git a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart deleted file mode 100644 index 0c2b4b8d6b14..000000000000 --- a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; - -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; - -import 'messages.g.dart'; -import 'video_player_platform_interface.dart'; - -/// An implementation of [VideoPlayerPlatform] that uses method channels. -/// -/// This is the default implementation, for compatibility with existing -/// third-party implementations. It is not used by other implementations in -/// this repository. -class MethodChannelVideoPlayer extends VideoPlayerPlatform { - final VideoPlayerApi _api = VideoPlayerApi(); - - @override - Future init() { - return _api.initialize(); - } - - @override - Future dispose(int textureId) { - return _api.dispose(TextureMessage()..textureId = textureId); - } - - @override - Future create(DataSource dataSource) async { - final CreateMessage message = CreateMessage(); - - switch (dataSource.sourceType) { - case DataSourceType.asset: - message.asset = dataSource.asset; - message.packageName = dataSource.package; - break; - case DataSourceType.network: - message.uri = dataSource.uri; - message.formatHint = _videoFormatStringMap[dataSource.formatHint]; - message.httpHeaders = dataSource.httpHeaders; - break; - case DataSourceType.file: - message.uri = dataSource.uri; - break; - case DataSourceType.contentUri: - message.uri = dataSource.uri; - break; - } - - final TextureMessage response = await _api.create(message); - return response.textureId; - } - - @override - Future setLooping(int textureId, bool looping) { - return _api.setLooping(LoopingMessage() - ..textureId = textureId - ..isLooping = looping); - } - - @override - Future play(int textureId) { - return _api.play(TextureMessage()..textureId = textureId); - } - - @override - Future pause(int textureId) { - return _api.pause(TextureMessage()..textureId = textureId); - } - - @override - Future setVolume(int textureId, double volume) { - return _api.setVolume(VolumeMessage() - ..textureId = textureId - ..volume = volume); - } - - @override - Future setPlaybackSpeed(int textureId, double speed) { - assert(speed > 0); - - return _api.setPlaybackSpeed(PlaybackSpeedMessage() - ..textureId = textureId - ..speed = speed); - } - - @override - Future seekTo(int textureId, Duration position) { - return _api.seekTo(PositionMessage() - ..textureId = textureId - ..position = position.inMilliseconds); - } - - @override - Future getPosition(int textureId) async { - final PositionMessage response = - await _api.position(TextureMessage()..textureId = textureId); - return Duration(milliseconds: response.position!); - } - - @override - Stream videoEventsFor(int textureId) { - return _eventChannelFor(textureId) - .receiveBroadcastStream() - .map((dynamic event) { - final Map map = event as Map; - switch (map['event']) { - case 'initialized': - return VideoEvent( - eventType: VideoEventType.initialized, - duration: Duration(milliseconds: map['duration']! as int), - size: Size((map['width'] as num?)?.toDouble() ?? 0.0, - (map['height'] as num?)?.toDouble() ?? 0.0), - rotationCorrection: map['rotationCorrection'] as int? ?? 0, - ); - case 'completed': - return VideoEvent( - eventType: VideoEventType.completed, - ); - case 'bufferingUpdate': - final List values = map['values']! as List; - - return VideoEvent( - buffered: values.map(_toDurationRange).toList(), - eventType: VideoEventType.bufferingUpdate, - ); - case 'bufferingStart': - return VideoEvent(eventType: VideoEventType.bufferingStart); - case 'bufferingEnd': - return VideoEvent(eventType: VideoEventType.bufferingEnd); - default: - return VideoEvent(eventType: VideoEventType.unknown); - } - }); - } - - @override - Widget buildView(int textureId) { - return Texture(textureId: textureId); - } - - @override - Future setMixWithOthers(bool mixWithOthers) { - return _api.setMixWithOthers( - MixWithOthersMessage()..mixWithOthers = mixWithOthers, - ); - } - - EventChannel _eventChannelFor(int textureId) { - return EventChannel('flutter.io/videoPlayer/videoEvents$textureId'); - } - - static const Map _videoFormatStringMap = - { - VideoFormat.ss: 'ss', - VideoFormat.hls: 'hls', - VideoFormat.dash: 'dash', - VideoFormat.other: 'other', - }; - - DurationRange _toDurationRange(dynamic value) { - final List pair = value as List; - return DurationRange( - Duration(milliseconds: pair[0]! as int), - Duration(milliseconds: pair[1]! as int), - ); - } -} diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 78173f1fb63c..92099eb6635a 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -6,8 +6,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'method_channel_video_player.dart'; - /// The interface that implementations of video_player must implement. /// /// Platform implementations should extend this class rather than implement it as `video_player` @@ -21,11 +19,12 @@ abstract class VideoPlayerPlatform extends PlatformInterface { static final Object _token = Object(); - static VideoPlayerPlatform _instance = MethodChannelVideoPlayer(); + static VideoPlayerPlatform _instance = _PlaceholderImplementation(); - /// The default instance of [VideoPlayerPlatform] to use. + /// The instance of [VideoPlayerPlatform] to use. /// - /// Defaults to [MethodChannelVideoPlayer]. + /// Defaults to a placeholder that does not override any methods, and thus + /// throws `UnimplementedError` in most cases. static VideoPlayerPlatform get instance => _instance; /// Platform-specific plugins should override this with their own @@ -105,6 +104,8 @@ abstract class VideoPlayerPlatform extends PlatformInterface { } } +class _PlaceholderImplementation extends VideoPlayerPlatform {} + /// Description of the data source used to create an instance of /// the video player. class DataSource { diff --git a/packages/video_player/video_player_platform_interface/pigeons/messages.dart b/packages/video_player/video_player_platform_interface/pigeons/messages.dart deleted file mode 100644 index 7a3490a955d4..000000000000 --- a/packages/video_player/video_player_platform_interface/pigeons/messages.dart +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// @dart = 2.9 - -import 'package:pigeon/pigeon_lib.dart'; - -class TextureMessage { - int textureId; -} - -class LoopingMessage { - int textureId; - bool isLooping; -} - -class VolumeMessage { - int textureId; - double volume; -} - -class PlaybackSpeedMessage { - int textureId; - double speed; -} - -class PositionMessage { - int textureId; - int position; -} - -class CreateMessage { - String asset; - String uri; - String packageName; - String formatHint; - Map httpHeaders; -} - -class MixWithOthersMessage { - bool mixWithOthers; -} - -@HostApi(dartHostTestHandler: 'TestHostVideoPlayerApi') -abstract class VideoPlayerApi { - void initialize(); - TextureMessage create(CreateMessage msg); - void dispose(TextureMessage msg); - void setLooping(LoopingMessage msg); - void setVolume(VolumeMessage msg); - void setPlaybackSpeed(PlaybackSpeedMessage msg); - void play(TextureMessage msg); - PositionMessage position(TextureMessage msg); - void seekTo(PositionMessage msg); - void pause(TextureMessage msg); - void setMixWithOthers(MixWithOthersMessage msg); -} - -void configurePigeon(PigeonOptions opts) { - opts.dartOut = 'lib/messages.g.dart'; - opts.dartTestOut = 'test/test.dart'; -} diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index 965641d2ee75..56e132dbb3a7 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/main/packages/video_player/v issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 5.1.4 +version: 6.0.0 environment: sdk: ">=2.12.0 <3.0.0" @@ -18,4 +18,3 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pigeon: 0.1.21 diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart deleted file mode 100644 index 7d64ac8ab7d7..000000000000 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#106316) -// ignore: unnecessary_import -import 'dart:ui'; - -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:video_player_platform_interface/messages.g.dart'; -import 'package:video_player_platform_interface/method_channel_video_player.dart'; -import 'package:video_player_platform_interface/video_player_platform_interface.dart'; - -import 'test.dart'; - -class _ApiLogger implements TestHostVideoPlayerApi { - final List log = []; - TextureMessage? textureMessage; - CreateMessage? createMessage; - PositionMessage? positionMessage; - LoopingMessage? loopingMessage; - VolumeMessage? volumeMessage; - PlaybackSpeedMessage? playbackSpeedMessage; - MixWithOthersMessage? mixWithOthersMessage; - - @override - TextureMessage create(CreateMessage arg) { - log.add('create'); - createMessage = arg; - return TextureMessage()..textureId = 3; - } - - @override - void dispose(TextureMessage arg) { - log.add('dispose'); - textureMessage = arg; - } - - @override - void initialize() { - log.add('init'); - } - - @override - void pause(TextureMessage arg) { - log.add('pause'); - textureMessage = arg; - } - - @override - void play(TextureMessage arg) { - log.add('play'); - textureMessage = arg; - } - - @override - void setMixWithOthers(MixWithOthersMessage arg) { - log.add('setMixWithOthers'); - mixWithOthersMessage = arg; - } - - @override - PositionMessage position(TextureMessage arg) { - log.add('position'); - textureMessage = arg; - return PositionMessage()..position = 234; - } - - @override - void seekTo(PositionMessage arg) { - log.add('seekTo'); - positionMessage = arg; - } - - @override - void setLooping(LoopingMessage arg) { - log.add('setLooping'); - loopingMessage = arg; - } - - @override - void setVolume(VolumeMessage arg) { - log.add('setVolume'); - volumeMessage = arg; - } - - @override - void setPlaybackSpeed(PlaybackSpeedMessage arg) { - log.add('setPlaybackSpeed'); - playbackSpeedMessage = arg; - } -} - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - // Store the initial instance before any tests change it. - final VideoPlayerPlatform initialInstance = VideoPlayerPlatform.instance; - - group('$VideoPlayerPlatform', () { - test('$MethodChannelVideoPlayer() is the default instance', () { - expect(initialInstance, isInstanceOf()); - }); - }); - - group('$MethodChannelVideoPlayer', () { - final MethodChannelVideoPlayer player = MethodChannelVideoPlayer(); - late _ApiLogger log; - - setUp(() { - log = _ApiLogger(); - TestHostVideoPlayerApi.setup(log); - }); - - test('init', () async { - await player.init(); - expect( - log.log.last, - 'init', - ); - }); - - test('dispose', () async { - await player.dispose(1); - expect(log.log.last, 'dispose'); - expect(log.textureMessage?.textureId, 1); - }); - - test('create with asset', () async { - final int? textureId = await player.create(DataSource( - sourceType: DataSourceType.asset, - asset: 'someAsset', - package: 'somePackage', - )); - expect(log.log.last, 'create'); - expect(log.createMessage?.asset, 'someAsset'); - expect(log.createMessage?.packageName, 'somePackage'); - expect(textureId, 3); - }); - - test('create with network', () async { - final int? textureId = await player.create(DataSource( - sourceType: DataSourceType.network, - uri: 'someUri', - formatHint: VideoFormat.dash, - )); - expect(log.log.last, 'create'); - expect(log.createMessage?.asset, null); - expect(log.createMessage?.uri, 'someUri'); - expect(log.createMessage?.packageName, null); - expect(log.createMessage?.formatHint, 'dash'); - expect(log.createMessage?.httpHeaders, {}); - expect(textureId, 3); - }); - - test('create with network (some headers)', () async { - final int? textureId = await player.create(DataSource( - sourceType: DataSourceType.network, - uri: 'someUri', - httpHeaders: {'Authorization': 'Bearer token'}, - )); - expect(log.log.last, 'create'); - expect(log.createMessage?.asset, null); - expect(log.createMessage?.uri, 'someUri'); - expect(log.createMessage?.packageName, null); - expect(log.createMessage?.formatHint, null); - expect(log.createMessage?.httpHeaders, - {'Authorization': 'Bearer token'}); - expect(textureId, 3); - }); - - test('create with file', () async { - final int? textureId = await player.create(DataSource( - sourceType: DataSourceType.file, - uri: 'someUri', - )); - expect(log.log.last, 'create'); - expect(log.createMessage?.uri, 'someUri'); - expect(textureId, 3); - }); - - test('setLooping', () async { - await player.setLooping(1, true); - expect(log.log.last, 'setLooping'); - expect(log.loopingMessage?.textureId, 1); - expect(log.loopingMessage?.isLooping, true); - }); - - test('play', () async { - await player.play(1); - expect(log.log.last, 'play'); - expect(log.textureMessage?.textureId, 1); - }); - - test('pause', () async { - await player.pause(1); - expect(log.log.last, 'pause'); - expect(log.textureMessage?.textureId, 1); - }); - - test('setMixWithOthers', () async { - await player.setMixWithOthers(true); - expect(log.log.last, 'setMixWithOthers'); - expect(log.mixWithOthersMessage?.mixWithOthers, true); - - await player.setMixWithOthers(false); - expect(log.log.last, 'setMixWithOthers'); - expect(log.mixWithOthersMessage?.mixWithOthers, false); - }); - - test('setVolume', () async { - await player.setVolume(1, 0.7); - expect(log.log.last, 'setVolume'); - expect(log.volumeMessage?.textureId, 1); - expect(log.volumeMessage?.volume, 0.7); - }); - - test('setPlaybackSpeed', () async { - await player.setPlaybackSpeed(1, 1.5); - expect(log.log.last, 'setPlaybackSpeed'); - expect(log.playbackSpeedMessage?.textureId, 1); - expect(log.playbackSpeedMessage?.speed, 1.5); - }); - - test('seekTo', () async { - await player.seekTo(1, const Duration(milliseconds: 12345)); - expect(log.log.last, 'seekTo'); - expect(log.positionMessage?.textureId, 1); - expect(log.positionMessage?.position, 12345); - }); - - test('getPosition', () async { - final Duration position = await player.getPosition(1); - expect(log.log.last, 'position'); - expect(log.textureMessage?.textureId, 1); - expect(position, const Duration(milliseconds: 234)); - }); - - test('videoEventsFor', () async { - _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .setMockMessageHandler( - 'flutter.io/videoPlayer/videoEvents123', - (ByteData? message) async { - final MethodCall methodCall = - const StandardMethodCodec().decodeMethodCall(message); - if (methodCall.method == 'listen') { - await _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .handlePlatformMessage( - 'flutter.io/videoPlayer/videoEvents123', - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'initialized', - 'duration': 98765, - 'width': 1920, - 'height': 1080, - }), - (ByteData? data) {}); - - await _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .handlePlatformMessage( - 'flutter.io/videoPlayer/videoEvents123', - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'initialized', - 'duration': 98765, - 'width': 1920, - 'height': 1080, - 'rotationCorrection': 180, - }), - (ByteData? data) {}); - - await _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .handlePlatformMessage( - 'flutter.io/videoPlayer/videoEvents123', - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'completed', - }), - (ByteData? data) {}); - - await _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .handlePlatformMessage( - 'flutter.io/videoPlayer/videoEvents123', - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'bufferingUpdate', - 'values': >[ - [0, 1234], - [1235, 4000], - ], - }), - (ByteData? data) {}); - - await _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .handlePlatformMessage( - 'flutter.io/videoPlayer/videoEvents123', - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'bufferingStart', - }), - (ByteData? data) {}); - - await _ambiguate(ServicesBinding.instance) - ?.defaultBinaryMessenger - .handlePlatformMessage( - 'flutter.io/videoPlayer/videoEvents123', - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'bufferingEnd', - }), - (ByteData? data) {}); - - return const StandardMethodCodec().encodeSuccessEnvelope(null); - } else if (methodCall.method == 'cancel') { - return const StandardMethodCodec().encodeSuccessEnvelope(null); - } else { - fail('Expected listen or cancel'); - } - }, - ); - expect( - player.videoEventsFor(123), - emitsInOrder([ - VideoEvent( - eventType: VideoEventType.initialized, - duration: const Duration(milliseconds: 98765), - size: const Size(1920, 1080), - rotationCorrection: 0, - ), - VideoEvent( - eventType: VideoEventType.initialized, - duration: const Duration(milliseconds: 98765), - size: const Size(1920, 1080), - rotationCorrection: 180, - ), - VideoEvent(eventType: VideoEventType.completed), - VideoEvent( - eventType: VideoEventType.bufferingUpdate, - buffered: [ - DurationRange( - Duration.zero, - const Duration(milliseconds: 1234), - ), - DurationRange( - const Duration(milliseconds: 1235), - const Duration(milliseconds: 4000), - ), - ]), - VideoEvent(eventType: VideoEventType.bufferingStart), - VideoEvent(eventType: VideoEventType.bufferingEnd), - ])); - }); - }); -} - -/// This allows a value of type T or T? to be treated as a value of type T?. -/// -/// We use this so that APIs that have become non-nullable can still be used -/// with `!` and `?` on the stable branch. -// TODO(ianh): Remove this once we roll stable in late 2021. -T? _ambiguate(T? value) => value; diff --git a/packages/video_player/video_player_platform_interface/test/test.dart b/packages/video_player/video_player_platform_interface/test/test.dart deleted file mode 100644 index c696434826a3..000000000000 --- a/packages/video_player/video_player_platform_interface/test/test.dart +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Autogenerated from Pigeon (v0.1.21), do not edit directly. -// See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import -// @dart = 2.12 -import 'dart:async'; -import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:video_player_platform_interface/messages.g.dart'; - -abstract class TestHostVideoPlayerApi { - void initialize(); - TextureMessage create(CreateMessage arg); - void dispose(TextureMessage arg); - void setLooping(LoopingMessage arg); - void setVolume(VolumeMessage arg); - void setPlaybackSpeed(PlaybackSpeedMessage arg); - void play(TextureMessage arg); - PositionMessage position(TextureMessage arg); - void seekTo(PositionMessage arg); - void pause(TextureMessage arg); - void setMixWithOthers(MixWithOthersMessage arg); - static void setup(TestHostVideoPlayerApi? api) { - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.initialize', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - // ignore message - api.initialize(); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.create was null. Expected CreateMessage.'); - final CreateMessage input = CreateMessage.decode(message!); - final TextureMessage output = api.create(input); - return {'result': output.encode()}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.dispose was null. Expected TextureMessage.'); - final TextureMessage input = TextureMessage.decode(message!); - api.dispose(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setLooping', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.setLooping was null. Expected LoopingMessage.'); - final LoopingMessage input = LoopingMessage.decode(message!); - api.setLooping(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setVolume', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.setVolume was null. Expected VolumeMessage.'); - final VolumeMessage input = VolumeMessage.decode(message!); - api.setVolume(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed was null. Expected PlaybackSpeedMessage.'); - final PlaybackSpeedMessage input = - PlaybackSpeedMessage.decode(message!); - api.setPlaybackSpeed(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.play was null. Expected TextureMessage.'); - final TextureMessage input = TextureMessage.decode(message!); - api.play(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.position was null. Expected TextureMessage.'); - final TextureMessage input = TextureMessage.decode(message!); - final PositionMessage output = api.position(input); - return {'result': output.encode()}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.seekTo was null. Expected PositionMessage.'); - final PositionMessage input = PositionMessage.decode(message!); - api.seekTo(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.pause was null. Expected TextureMessage.'); - final TextureMessage input = TextureMessage.decode(message!); - api.pause(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers was null. Expected MixWithOthersMessage.'); - final MixWithOthersMessage input = - MixWithOthersMessage.decode(message!); - api.setMixWithOthers(input); - return {}; - }); - } - } - } -} diff --git a/packages/video_player/video_player_platform_interface/test/video_player_platform_interface_test.dart b/packages/video_player/video_player_platform_interface/test/video_player_platform_interface_test.dart new file mode 100644 index 000000000000..8aa7ad9bd3c1 --- /dev/null +++ b/packages/video_player/video_player_platform_interface/test/video_player_platform_interface_test.dart @@ -0,0 +1,15 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:video_player_platform_interface/video_player_platform_interface.dart'; + +void main() { + // Store the initial instance before any tests change it. + final VideoPlayerPlatform initialInstance = VideoPlayerPlatform.instance; + + test('default implementation throws uninimpletemented', () async { + await expectLater(() => initialInstance.init(), throwsUnimplementedError); + }); +}