Repository navigation
MediaElement v11.0.0 Bug Fix-A-Palooza
·
16 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
MediaElement v11.0.0 Bug Fix-A-Palooza 🎉
We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage to 91.8% Code Coverage on CommunityToolkti.Maui.MediaElement.
Breaking Changes
To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.
All packages
- API: Null arguments throw
ArgumentNullExceptionat the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).- A null that used to cause a
NullReferenceExceptionlater (or was stored silently) fails at the call, with aParamName. What to do: fix the caller. - An async member throws from the call itself, before it returns a Task.
- Null arguments that a member handled before are still accepted, for example an
IProgress<double>or aPaintbackground of null. - Feature-specific effects are listed in each feature's section.
BasePlatformBehaviorguards onlybindable. A null platform view passes through, because the AndroidIconTintColorBehavioraccepts it.
- A null that used to cause a
- Setup: CommunityToolkit.Maui.Core on Android adds a
<queries>entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews<queries>, check the merged manifest. - Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references
System.Speech10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.
New APIs In This Release
Popupnow declaresIPaddingElement, which it already inherited fromContentViewGravatarImageSourcedeclaresIStreamImageSource, which it already inherited fromStreamImageSource, and overridesCancel()(see GravatarImageSource, after that ApiCompat run);[SupportedOSPlatform("android23.0")]on the AndroidStatusBarBehavior(see StatusBar and StatusBarBehavior).DefaultPopupSettings.BackgroundColorDarkandOnInitializing(#3345)NumericValidationBehavior.Interval(#3329)
MediaElement
-
API
- Null arguments:
FileMediaSourceConverter.ConvertFrom(null)throwsArgumentNullException. - Null arguments:
MediaFailedEventArgsrejects null for its non-nullable members.
Behavior
- An exception thrown by an event handler while
Sourcechanges is reported throughMediaFailed.- Before, an exception from a
StateChanged,PropertyChangedorPropertyChanginghandler reached the code that setSource, or ended the app when MAUI set it from XAML or a binding. - Now it is logged and the change goes on. The first exception is reported once through
MediaFailed:ErrorMessagenames its type and message, andCurrentStateis not set to Failed. - What to do: handle
MediaFailed, and checkErrorMessagebefore treating everyMediaFailedas a failed source.
- Before, an exception from a
- MediaElement playback.
SeekToclamps a position outside the media to its start or end and raisesSeekCompleted. On iOS such a seek never completed.SeekTofails with the platform's exception, for exampleInvalidOperationExceptionbefore the player is ready, where that exception ended the app.Play()at the end of the media starts it again on iOS and Mac Catalyst, as on Android.- On Android,
CurrentStatereportsBufferingwhile buffering (it wasPaused) andStoppedat the end of the media. - A source without data empties the player and reports
None. - What to do: check code that relied on the old states.
- A disconnected handler stops the position timer. The MediaElement no longer keeps its page alive after the page is left. No action is needed.
- Why: the dispatcher timer stops when the handler disconnects, and starts again when a handler connects later.
- Found on iOS: a probe left the Sample's
MediaElementPagealive 3 of 3 times after it was left (0 of 3 with the fix). The same leak is fixed and tested on Android, Mac Catalyst and Windows. - On Windows,
MediaOpenedarrives on the player's worker thread. An open that was still running when the handler disconnected no longer starts the timer again: the timer starts on the UI thread, and only while a handler is attached. - A second leak was in the Sample:
MediaElementFromStreamPagewasIAsyncDisposable, so the window's service scope kept every page that was opened.- iOS: a probe left the page alive 3 of 3 times before the change, 0 of 3 after.
- Windows (the Sample at 4a8d407, 5 visits, a GC dump after the 5th Back): 0 MediaElementFromStreamPage, MediaElement or StreamMediaSource stay alive, GC heap 6.5 MB. With the Sample change reverted: 5 of each, 167.7 MB.
- Also fixed:
FileMediaSourceConverter.ConvertFromhad an inverted condition. A real path threwInvalidOperationException, and an empty or white-space string returned a source. Now a real path returns theFileMediaSource, and an empty or white-space string throwsInvalidOperationException, as documented.
- Null arguments:
What's Changed
- Add Device Tests, Apply Fixes for Bugs Found by @TheCodeTraveler in #3344
- Apply MediaElement.Speed when playback starts on iOS and fix inverted AreFloatingPointNumbersEqual by @ne0rrmatrix in #3327
- Fix iOS MediaElement support for multiple ItemsViews and windows by @ne0rrmatrix in #3222
- Fix ios media element start bug by @ne0rrmatrix in #3281