Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
A few fixes for the release. (#228)
Browse files Browse the repository at this point in the history
* Setting the correct flags for Chrome Tabs. Fixes #225

* Make sure that there is data to decrypt before starting. Fixes #226

* Fixes for TTS. Fixes #227

* A bit of the fixes for emails on iOS. Relates to #224

* Update the email bit for iOS #224

* Cleaning up the code #224
  • Loading branch information
mattleibow authored and Redth committed May 5, 2018
1 parent 9295ce3 commit 480cac0
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 46 deletions.
4 changes: 3 additions & 1 deletion Xamarin.Essentials/Browser/Browser.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ static Task PlatformOpenAsync(Uri uri, BrowserLaunchType launchType)
{
case BrowserLaunchType.SystemPreferred:
var tabsBuilder = new CustomTabsIntent.Builder();
var tabsIntent = tabsBuilder.Build();
tabsBuilder.SetShowTitle(true);
var tabsIntent = tabsBuilder.Build();
tabsIntent.Intent.SetFlags(ActivityFlags.ClearTop);
tabsIntent.Intent.SetFlags(ActivityFlags.NewTask);
tabsIntent.LaunchUrl(Platform.AppContext, nativeUri);
break;
case BrowserLaunchType.External:
Expand Down
36 changes: 35 additions & 1 deletion Xamarin.Essentials/Email/Email.ios.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
using System.Threading.Tasks;
using Foundation;
using MessageUI;
using UIKit;

namespace Xamarin.Essentials
{
public static partial class Email
{
internal static bool IsComposeSupported
=> MFMailComposeViewController.CanSendMail;
{
get
{
var can = MFMailComposeViewController.CanSendMail;
if (!can)
{
var url = NSUrl.FromString("mailto:");
NSRunLoop.Main.InvokeOnMainThread(() => can = UIApplication.SharedApplication.CanOpenUrl(url));
}
return can;
}
}

static Task PlatformComposeAsync(EmailMessage message)
{
if (MFMailComposeViewController.CanSendMail)
return ComposeWithMailCompose(message);
else
return ComposeWithUrl(message);
}

static Task ComposeWithMailCompose(EmailMessage message)
{
// do this first so we can throw as early as possible
var parentController = Platform.GetCurrentViewController();
Expand Down Expand Up @@ -37,5 +58,18 @@ static Task PlatformComposeAsync(EmailMessage message)

return tcs.Task;
}

static Task ComposeWithUrl(EmailMessage message)
{
var url = GetMailToUri(message);

var tcs = new TaskCompletionSource<bool>();
NSRunLoop.Main.InvokeOnMainThread(() =>
{
var nsurl = NSUrl.FromString(url);
UIApplication.SharedApplication.OpenUrl(nsurl, new UIApplicationOpenUrlOptions(), r => tcs.TrySetResult(r));
});
return tcs.Task;
}
}
}
26 changes: 25 additions & 1 deletion Xamarin.Essentials/Email/Email.shared.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

Expand All @@ -19,6 +20,29 @@ public static Task ComposeAsync(EmailMessage message)

return PlatformComposeAsync(message);
}

static string GetMailToUri(EmailMessage message)
{
if (message != null && message.BodyFormat != EmailBodyFormat.PlainText)
throw new FeatureNotSupportedException("Only EmailBodyFormat.PlainText is supported if no email account is set up.");

var parts = new List<string>();
if (!string.IsNullOrEmpty(message?.Body))
parts.Add("body=" + Uri.EscapeUriString(message.Body));
if (!string.IsNullOrEmpty(message?.Subject))
parts.Add("subject=" + Uri.EscapeUriString(message.Subject));
if (message?.To.Count > 0)
parts.Add("to=" + string.Join(",", message.To));
if (message?.Cc.Count > 0)
parts.Add("cc=" + string.Join(",", message.Cc));
if (message?.Bcc.Count > 0)
parts.Add("bcc=" + string.Join(",", message.Bcc));

var uri = "mailto:";
if (parts.Count > 0)
uri += "?" + string.Join("&", parts);
return uri;
}
}

public class EmailMessage
Expand Down
11 changes: 7 additions & 4 deletions Xamarin.Essentials/SecureStorage/SecureStorage.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ static Task<string> PlatformGetAsync(string key)
using (var prefs = context.GetSharedPreferences(Alias, FileCreationMode.Private))
encStr = prefs.GetString(Utils.Md5Hash(key), null);

var encData = Convert.FromBase64String(encStr);

var ks = new AndroidKeyStore(context, Alias, AlwaysUseAsymmetricKeyStorage);
var decryptedData = ks.Decrypt(encData);
string decryptedData = null;
if (!string.IsNullOrEmpty(encStr))
{
var encData = Convert.FromBase64String(encStr);
var ks = new AndroidKeyStore(context, Alias, AlwaysUseAsymmetricKeyStorage);
decryptedData = ks.Decrypt(encData);
}

return Task.FromResult(decryptedData);
}
Expand Down
73 changes: 34 additions & 39 deletions Xamarin.Essentials/TextToSpeech/TextToSpeech.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ internal class TextToSpeechImplementation : Java.Lang.Object, AndroidTextToSpeec
TaskCompletionSource<bool> tcsInitialize;
TaskCompletionSource<bool> tcsUtterances;

public TextToSpeechImplementation()
{
}

Task<bool> Initialize()
{
if (tcsInitialize != null && tts != null)
Expand All @@ -88,11 +84,16 @@ Task<bool> Initialize()
return tcsInitialize.Task;
}

public new void Dispose()
protected override void Dispose(bool disposing)
{
tts?.Stop();
tts?.Shutdown();
tts = null;
if (disposing)
{
tts?.Stop();
tts?.Shutdown();
tts = null;
}

base.Dispose(disposing);
}

int numExpectedUtterances = 0;
Expand Down Expand Up @@ -138,10 +139,9 @@ public async Task SpeakAsync(string text, int max, SpeakSettings settings, Cance
}

if (settings?.Pitch.HasValue ?? false)
{
var pitch = settings.Pitch.Value;
tts.SetPitch(pitch);
}
tts.SetPitch(settings.Pitch.Value);
else
tts.SetPitch(TextToSpeech.PitchDefault);

var parts = text.SplitSpeak(max);

Expand All @@ -150,11 +150,8 @@ public async Task SpeakAsync(string text, int max, SpeakSettings settings, Cance

var guid = Guid.NewGuid().ToString();

for (var i = 0; i < parts.Count; i++)
for (var i = 0; i < parts.Count && !cancelToken.IsCancellationRequested; i++)
{
if (cancelToken.IsCancellationRequested)
break;

// We require the utterance id to be set if we want the completed listener to fire
var map = new Dictionary<string, string>
{
Expand All @@ -164,10 +161,9 @@ public async Task SpeakAsync(string text, int max, SpeakSettings settings, Cance
if (settings != null && settings.Volume.HasValue)
map.Add(AndroidTextToSpeech.Engine.KeyParamVolume, settings.Volume.Value.ToString());

#pragma warning disable CS0618

// We use an obsolete overload here so it works on older API levels at runtime
// Flush on first entry and add (to not flush our own previous) subsequent entries
#pragma warning disable CS0618
tts.Speak(parts[i], i == 0 ? QueueMode.Flush : QueueMode.Add, map);
#pragma warning restore CS0618
}
Expand All @@ -178,13 +174,9 @@ public async Task SpeakAsync(string text, int max, SpeakSettings settings, Cance
public void OnInit(OperationResult status)
{
if (status.Equals(OperationResult.Success))
{
tcsInitialize.TrySetResult(true);
}
else
{
tcsInitialize.TrySetException(new ArgumentException("Failed to initialize Text to Speech engine."));
}
}

public async Task<IEnumerable<Locale>> GetLocalesAsync()
Expand All @@ -203,27 +195,30 @@ public async Task<IEnumerable<Locale>> GetLocalesAsync()
}
}

return JavaLocale.GetAvailableLocales().
Where(l =>
{
try
{
var r = tts.IsLanguageAvailable(l);
return r == LanguageAvailableResult.Available
|| r == LanguageAvailableResult.CountryAvailable
|| r == LanguageAvailableResult.CountryVarAvailable;
}
catch (Exception ex)
{
Console.WriteLine("Error checking language; " + l + " " + ex);
}
return false;
}).
Select(l => new Locale(l.Language, l.Country, l.DisplayName, string.Empty))
return JavaLocale.GetAvailableLocales()
.Where(IsLocaleAvailable)
.Select(l => new Locale(l.Language, l.Country, l.DisplayName, string.Empty))
.GroupBy(c => c.ToString())
.Select(g => g.First());
}

private bool IsLocaleAvailable(JavaLocale l)
{
try
{
var r = tts.IsLanguageAvailable(l);
return
r == LanguageAvailableResult.Available ||
r == LanguageAvailableResult.CountryAvailable ||
r == LanguageAvailableResult.CountryVarAvailable;
}
catch (Exception ex)
{
Console.WriteLine("Error checking language; " + l + " " + ex);
}
return false;
}

public void OnUtteranceCompleted(string utteranceId)
{
numCompletedUtterances++;
Expand Down

0 comments on commit 480cac0

Please sign in to comment.