From d09c637c6ab43448e99b79647a08b66f74faf7f7 Mon Sep 17 00:00:00 2001 From: Jonathan Dick Date: Tue, 3 Mar 2020 17:58:18 -0500 Subject: [PATCH 1/2] 1.5.1 (#1145) * Implement vertical accuracy in GeoLocation API (#1103) * Location: add property 'VerticalAccuracy' (#1099) * vertical accuracy is only available in Android API level 26 and above (#1099) * update Samples app to show vertical accuracy on GeolocationPage * add missing documentation bits for Location.VerticalAccuracy * .gitattributes: get better diff context for C# code (#1115) * Location.VerticalAccuracy: add runtime check for Android version (#1099) (#1116) * the compile-time check is not enough * it crashed on old Android versions (<8.0) * GH-1102 Fix launcher on older devices (#1120) * Update Launcher.ios.tvos.cs * OpenUrlAsync was introduced in iOS 10 not 12 https://docs.microsoft.com/en-us/dotnet/api/uikit.uiapplication.openurlasync?view=xamarin-ios-sdk-12 * Fix trailing whitespace * Really? fix whitespace * Really! Fix whitespace * Fixes #1129 - set empty required declarations on UWP (#1133) * Fixes #1129 - set empty required declarations on UWP * Update Permissions.uwp.cs * Update Xamarin.Essentials.csproj (#1136) * GH-1142 AccessBackgroundLocation only when compile & running Q (#1143) * AccessBackgroundLocation only when compile & running Q * put if compile check around permission * GH-1121 If VC is null use TraitCollection (#1144) * Fixes #1123 (#1126) * Update PlacemarkExtensions.xml (#1132) Co-authored-by: Janus Weil Co-authored-by: James Montemagno Co-authored-by: Michael --- .../AppInfo/AppInfo.ios.tvos.watchos.cs | 5 ++++- .../Launcher/Launcher.shared.cs | 2 +- .../Permissions/Permissions.android.cs | 19 +++++++++++++------ .../Permissions/Permissions.uwp.cs | 2 +- .../Platform/Platform.android.cs | 7 +++++++ Xamarin.Essentials/Xamarin.Essentials.csproj | 1 + .../PlacemarkExtensions.xml | 2 +- 7 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Xamarin.Essentials/AppInfo/AppInfo.ios.tvos.watchos.cs b/Xamarin.Essentials/AppInfo/AppInfo.ios.tvos.watchos.cs index 62332f287..263c42338 100644 --- a/Xamarin.Essentials/AppInfo/AppInfo.ios.tvos.watchos.cs +++ b/Xamarin.Essentials/AppInfo/AppInfo.ios.tvos.watchos.cs @@ -30,7 +30,10 @@ static AppTheme PlatformRequestedTheme() if (!Platform.HasOSVersion(13, 0)) return AppTheme.Unspecified; - return Platform.GetCurrentViewController().TraitCollection.UserInterfaceStyle switch + var uiStyle = Platform.GetCurrentUIViewController()?.TraitCollection?.UserInterfaceStyle ?? + UITraitCollection.CurrentTraitCollection.UserInterfaceStyle; + + return uiStyle switch { UIUserInterfaceStyle.Light => AppTheme.Light, UIUserInterfaceStyle.Dark => AppTheme.Dark, diff --git a/Xamarin.Essentials/Launcher/Launcher.shared.cs b/Xamarin.Essentials/Launcher/Launcher.shared.cs index f7aa5a166..3ad9a6b39 100644 --- a/Xamarin.Essentials/Launcher/Launcher.shared.cs +++ b/Xamarin.Essentials/Launcher/Launcher.shared.cs @@ -56,7 +56,7 @@ public static Task TryOpenAsync(Uri uri) if (uri == null) throw new ArgumentNullException(nameof(uri)); - return PlatformCanOpenAsync(uri); + return PlatformTryOpenAsync(uri); } } diff --git a/Xamarin.Essentials/Permissions/Permissions.android.cs b/Xamarin.Essentials/Permissions/Permissions.android.cs index 59fbb843d..57f0ec17c 100644 --- a/Xamarin.Essentials/Permissions/Permissions.android.cs +++ b/Xamarin.Essentials/Permissions/Permissions.android.cs @@ -224,15 +224,22 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions public partial class LocationAlways : BasePlatformPermission { - public override (string androidPermission, bool isRuntime)[] RequiredPermissions => - new (string, bool)[] + public override (string androidPermission, bool isRuntime)[] RequiredPermissions + { + get { + var permissions = new List<(string, bool)>(); #if __ANDROID_29__ - (Manifest.Permission.AccessBackgroundLocation, true), + if (Platform.HasApiLevelQ) + permissions.Add((Manifest.Permission.AccessBackgroundLocation, true)); #endif - (Manifest.Permission.AccessCoarseLocation, true), - (Manifest.Permission.AccessFineLocation, true) - }; + + permissions.Add((Manifest.Permission.AccessCoarseLocation, true)); + permissions.Add((Manifest.Permission.AccessFineLocation, true)); + + return permissions.ToArray(); + } + } } public partial class Maps : BasePlatformPermission diff --git a/Xamarin.Essentials/Permissions/Permissions.uwp.cs b/Xamarin.Essentials/Permissions/Permissions.uwp.cs index aa3d5db08..772b4d5a1 100644 --- a/Xamarin.Essentials/Permissions/Permissions.uwp.cs +++ b/Xamarin.Essentials/Permissions/Permissions.uwp.cs @@ -27,7 +27,7 @@ public static bool IsCapabilityDeclared(string capabilityName) public abstract partial class BasePlatformPermission : BasePermission { - protected virtual Func> RequiredDeclarations { get; } + protected virtual Func> RequiredDeclarations { get; } = () => Array.Empty(); public override Task CheckStatusAsync() { diff --git a/Xamarin.Essentials/Platform/Platform.android.cs b/Xamarin.Essentials/Platform/Platform.android.cs index e0e53fcbe..9a3f06a21 100644 --- a/Xamarin.Essentials/Platform/Platform.android.cs +++ b/Xamarin.Essentials/Platform/Platform.android.cs @@ -173,6 +173,13 @@ internal static AndroidUri GetShareableFileUri(string filename) false; #endif + internal static bool HasApiLevelQ => +#if __ANDROID_29__ + HasApiLevel(BuildVersionCodes.Q); +#else + false; +#endif + internal static bool HasApiLevel(BuildVersionCodes versionCode) => (int)Build.VERSION.SdkInt >= (int)versionCode; diff --git a/Xamarin.Essentials/Xamarin.Essentials.csproj b/Xamarin.Essentials/Xamarin.Essentials.csproj index 0c9335ab5..84e63d885 100644 --- a/Xamarin.Essentials/Xamarin.Essentials.csproj +++ b/Xamarin.Essentials/Xamarin.Essentials.csproj @@ -51,6 +51,7 @@ + diff --git a/docs/en/Xamarin.Essentials/PlacemarkExtensions.xml b/docs/en/Xamarin.Essentials/PlacemarkExtensions.xml index 9eea797c8..58896fb83 100644 --- a/docs/en/Xamarin.Essentials/PlacemarkExtensions.xml +++ b/docs/en/Xamarin.Essentials/PlacemarkExtensions.xml @@ -11,7 +11,7 @@ - Extensions for the palcemark. + Extensions for the placemark. To be added. From bc3c859280abcbe2329b6a867967f191b1a06dbe Mon Sep 17 00:00:00 2001 From: Ben Askren Date: Fri, 6 Mar 2020 15:32:46 -0500 Subject: [PATCH 2/2] Fixed: Fatal iOS 13 memory leak when using TextToSpeach.SpeekAsync #1112 --- .../TextToSpeech.ios.tvos.watchos.cs | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Xamarin.Essentials/TextToSpeech/TextToSpeech.ios.tvos.watchos.cs b/Xamarin.Essentials/TextToSpeech/TextToSpeech.ios.tvos.watchos.cs index 71c650014..2569a757a 100644 --- a/Xamarin.Essentials/TextToSpeech/TextToSpeech.ios.tvos.watchos.cs +++ b/Xamarin.Essentials/TextToSpeech/TextToSpeech.ios.tvos.watchos.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -8,14 +9,18 @@ namespace Xamarin.Essentials { public static partial class TextToSpeech { + static readonly Lazy speechSynthesizer = new Lazy(); + internal static Task> PlatformGetLocalesAsync() => Task.FromResult(AVSpeechSynthesisVoice.GetSpeechVoices() .Select(v => new Locale(v.Language, null, v.Language, v.Identifier))); - internal static Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default) + internal static async Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default) { - var speechUtterance = GetSpeechUtterance(text, options); - return SpeakUtterance(speechUtterance, cancelToken); + using (var speechUtterance = GetSpeechUtterance(text, options)) + { + await SpeakUtterance(speechUtterance, cancelToken); + } } static AVSpeechUtterance GetSpeechUtterance(string text, SpeechOptions options) @@ -44,11 +49,10 @@ static AVSpeechUtterance GetSpeechUtterance(string text, SpeechOptions options) internal static async Task SpeakUtterance(AVSpeechUtterance speechUtterance, CancellationToken cancelToken) { var tcsUtterance = new TaskCompletionSource(); - var speechSynthesizer = new AVSpeechSynthesizer(); try { - speechSynthesizer.DidFinishSpeechUtterance += OnFinishedSpeechUtterance; - speechSynthesizer.SpeakUtterance(speechUtterance); + speechSynthesizer.Value.DidFinishSpeechUtterance += OnFinishedSpeechUtterance; + speechSynthesizer.Value.SpeakUtterance(speechUtterance); using (cancelToken.Register(TryCancel)) { await tcsUtterance.Task; @@ -56,12 +60,12 @@ internal static async Task SpeakUtterance(AVSpeechUtterance speechUtterance, Can } finally { - speechSynthesizer.DidFinishSpeechUtterance -= OnFinishedSpeechUtterance; + speechSynthesizer.Value.DidFinishSpeechUtterance -= OnFinishedSpeechUtterance; } void TryCancel() { - speechSynthesizer?.StopSpeaking(AVSpeechBoundary.Word); + speechSynthesizer.Value?.StopSpeaking(AVSpeechBoundary.Word); tcsUtterance?.TrySetResult(true); }