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

Commit

Permalink
Merge branch 'develop' into 1.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Redth committed Jul 20, 2020
2 parents f30a865 + 94717ca commit 85af246
Show file tree
Hide file tree
Showing 47 changed files with 586 additions and 73 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Every pull request which affects public types or members should include correspo

If you're looking for something to fix, please browse [open issues](https://github.com/xamarin/Essentials/issues).

Follow the style used by the [.NET Foundation](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md), with two primary exceptions:
Follow the style used by the [.NET Foundation](https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/coding-style.md), with two primary exceptions:

- We do not use the `private` keyword as it is the default accessibility level in C#.
- We will **not** use `_` or `s_` as a prefix for internal or private field names
Expand Down
15 changes: 15 additions & 0 deletions DeviceTests/DeviceTests.Shared/HapticFeedback_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using Xamarin.Essentials;
using Xunit;

namespace DeviceTests
{
public class HapticFeedback_Tests
{
[Fact]
public void Click() => HapticFeedback.Perform(HapticFeedbackType.Click);

[Fact]
public void LongPress() => HapticFeedback.Perform(HapticFeedbackType.LongPress);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ public async Task Get([FromRoute]string scheme)
}
else
{
var claims = auth.Principal.Identities.FirstOrDefault()?.Claims;
var email = string.Empty;
email = claims?.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value;

// Get parameters to send back to the callback
var qs = new Dictionary<string, string>
{
{ "access_token", auth.Properties.GetTokenValue("access_token") },
{ "refresh_token", auth.Properties.GetTokenValue("refresh_token") ?? string.Empty },
{ "expires", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() }
};
{
{ "access_token", auth.Properties.GetTokenValue("access_token") },
{ "refresh_token", auth.Properties.GetTokenValue("refresh_token") ?? string.Empty },
{ "expires", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() },
{ "email", email }
};

// Build the result url
var url = callbackScheme + "://#" + string.Join(
Expand Down
7 changes: 7 additions & 0 deletions Samples/Sample.Server.WebAuthenticator/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public void ConfigureServices(IServiceCollection services)
=> WebHostEnvironment.ContentRootFileProvider.GetFileInfo($"AuthKey_{keyId}.p8"));
a.SaveTokens = true;
});

/*
* For Apple signin
* If you are running the app on Azure you must add the Configuration setting
* WEBSITE_LOAD_USER_PROFILE = 1
* Without this setting you will get a File Not Found exception when AppleAuthenticationHandler tries to generate a certificate using your Auth_{keyId].P8 file.
*/
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
4 changes: 2 additions & 2 deletions Samples/Samples.Android/Samples.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<AndroidManagedSymbols>true</AndroidManagedSymbols>
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
<AndroidSupportedAbis>armeabi-v7a;x86</AndroidSupportedAbis>
<EnableProguard>true</EnableProguard>
<AndroidLinkTool>r8</AndroidLinkTool>
<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkSkip>Xamarin.Forms.Platform.Android;Xamarin.Forms.Platform;Xamarin.Forms.Core;Xamarin.Forms.Xaml;Samples;FormsViewGroup;</AndroidLinkSkip>
</PropertyGroup>
Expand Down Expand Up @@ -123,4 +123,4 @@
<AndroidAsset Include="Assets\FileSystemTemplate.txt" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>
</Project>
24 changes: 24 additions & 0 deletions Samples/Samples/View/HapticFeedbackPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Samples.View"
xmlns:viewmodels="clr-namespace:Samples.ViewModel"
x:Class="Samples.View.HapticFeedbackPage"
Title="Vibration">
<views:BasePage.BindingContext>
<viewmodels:HapticFeedbackViewModel />
</views:BasePage.BindingContext>

<StackLayout>
<Label Text="Quickly and easily make the device provide haptic feedback." FontAttributes="Bold" Margin="12" />

<ScrollView>
<StackLayout Padding="12,0,12,12" Spacing="6">
<Button Text="Click" Command="{Binding ClickCommand}" />
<Button Text="LongPress" Command="{Binding LongPressCommand}" />
<Label Text="HapticFeadback is not supported." TextColor="Red" FontAttributes="Italic"
IsVisible="{Binding IsSupported, Converter={StaticResource NegativeConverter}}" />
</StackLayout>
</ScrollView>
</StackLayout>

</views:BasePage>
10 changes: 10 additions & 0 deletions Samples/Samples/View/HapticFeedbackPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Samples.View
{
public partial class HapticFeedbackPage : BasePage
{
public HapticFeedbackPage()
{
InitializeComponent();
}
}
}
60 changes: 60 additions & 0 deletions Samples/Samples/ViewModel/HapticFeedbackViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Samples.ViewModel
{
public class HapticFeedbackViewModel : BaseViewModel
{
bool isSupported = true;

public HapticFeedbackViewModel()
{
ClickCommand = new Command(OnClick);
LongPressCommand = new Command(OnLongPress);
}

public ICommand ClickCommand { get; }

public ICommand LongPressCommand { get; }

public bool IsSupported
{
get => isSupported;
set => SetProperty(ref isSupported, value);
}

void OnClick()
{
try
{
HapticFeedback.Perform(HapticFeedbackType.Click);
}
catch (FeatureNotSupportedException)
{
IsSupported = false;
}
catch (Exception ex)
{
DisplayAlertAsync($"Unable to HapticFeedback: {ex.Message}");
}
}

void OnLongPress()
{
try
{
HapticFeedback.Perform(HapticFeedbackType.LongPress);
}
catch (FeatureNotSupportedException)
{
IsSupported = false;
}
catch (Exception ex)
{
DisplayAlertAsync($"Unable to HapticFeedback: {ex.Message}");
}
}
}
}
6 changes: 6 additions & 0 deletions Samples/Samples/ViewModel/HomeViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ public HomeViewModel()
typeof(VibrationPage),
"Quickly and easily make the device vibrate.",
new[] { "vibration", "vibrate", "hardware", "device" }),
new SampleItem(
"📳",
"Haptic Feedback",
typeof(HapticFeedbackPage),
"Quickly and easily make the device provide haptic feedback",
new[] { "haptic", "feedback", "hardware", "device" }),
new SampleItem(
"🔓",
"Web Authenticator",
Expand Down
2 changes: 1 addition & 1 deletion Xamarin.Essentials.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{6330
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{EE4495FA-9869-45CF-A11D-69F2218C6F62}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Server.WebAuthenticator", "Samples\Sample.Server.WebAuthenticator\Sample.Server.WebAuthenticator.csproj", "{553D51A8-8E79-40D9-9FB3-9FC2386FF886}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Server.WebAuthenticator", "Samples\Sample.Server.WebAuthenticator\Sample.Server.WebAuthenticator.csproj", "{553D51A8-8E79-40D9-9FB3-9FC2386FF886}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Mac", "Samples\Samples.Mac\Samples.Mac.csproj", "{89899D16-4BD1-49B1-9903-9F6BB26C5DC5}"
EndProject
Expand Down
14 changes: 11 additions & 3 deletions Xamarin.Essentials/Email/Email.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,18 @@ static Task PlatformComposeAsync(EmailMessage message)

static Intent CreateIntent(EmailMessage message)
{
var action = message?.Attachments?.Count > 1 ? Intent.ActionSendMultiple : Intent.ActionSend;
var action = (message?.Attachments?.Count ?? 0) switch
{
0 => Intent.ActionSendto,
1 => Intent.ActionSend,
_ => Intent.ActionSendMultiple
};
var intent = new Intent(action);
intent.SetType("message/rfc822");
intent.SetData(Uri.Parse("mailto:")); // only email apps should handle this

if (action == Intent.ActionSendto)
intent.SetData(Uri.Parse("mailto:"));
else
intent.SetType("message/rfc822");

if (!string.IsNullOrEmpty(message?.Body))
{
Expand Down
2 changes: 1 addition & 1 deletion Xamarin.Essentials/Flashlight/Flashlight.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static async Task CheckSupportAsync()
if (!IsSupported)
throw new FeatureNotSupportedException();

await Permissions.RequestAsync<Permissions.Flashlight>();
await Permissions.EnsureGrantedAsync<Permissions.Flashlight>();
}

static Task ToggleTorchAsync(bool switchOn)
Expand Down
4 changes: 2 additions & 2 deletions Xamarin.Essentials/Geolocation/Geolocation.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static partial class Geolocation

static async Task<Location> PlatformLastKnownLocationAsync()
{
await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();

var lm = Platform.LocationManager;
AndroidLocation bestLocation = null;
Expand All @@ -37,7 +37,7 @@ static async Task<Location> PlatformLastKnownLocationAsync()

static async Task<Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();

var locationManager = Platform.LocationManager;

Expand Down
4 changes: 2 additions & 2 deletions Xamarin.Essentials/Geolocation/Geolocation.ios.macos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static async Task<Location> PlatformLastKnownLocationAsync()
if (!CLLocationManager.LocationServicesEnabled)
throw new FeatureNotEnabledException("Location services are not enabled on device.");

await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();

var manager = new CLLocationManager();
var location = manager.Location;
Expand All @@ -27,7 +27,7 @@ static async Task<Location> PlatformLocationAsync(GeolocationRequest request, Ca
if (!CLLocationManager.LocationServicesEnabled)
throw new FeatureNotEnabledException("Location services are not enabled on device.");

await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();

// the location manager requires an active run loop
// so just use the main loop
Expand Down
9 changes: 2 additions & 7 deletions Xamarin.Essentials/Geolocation/Geolocation.tizen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ public static partial class Geolocation
{
static Location lastKnownLocation = new Location();

static async Task<Location> PlatformLastKnownLocationAsync()
{
await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

return lastKnownLocation;
}
static Task<Location> PlatformLastKnownLocationAsync() => Task.FromResult(lastKnownLocation);

static async Task<Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();

Locator service = null;
var gps = Platform.GetFeatureInfo<bool>("location.gps");
Expand Down
2 changes: 1 addition & 1 deletion Xamarin.Essentials/Geolocation/Geolocation.uwp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static async Task<Location> PlatformLastKnownLocationAsync()

static async Task<Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
{
await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
await Permissions.EnsureGrantedAsync<Permissions.LocationWhenInUse>();

var geolocator = new Geolocator
{
Expand Down
33 changes: 33 additions & 0 deletions Xamarin.Essentials/HapticFeedback/HapticFeedback.android.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Android.Views;

namespace Xamarin.Essentials
{
public static partial class HapticFeedback
{
internal static bool IsSupported => true;

static void PlatformPerform(HapticFeedbackType type)
{
Permissions.EnsureDeclared<Permissions.Vibrate>();

try
{
Platform.CurrentActivity?.Window?.DecorView?.PerformHapticFeedback(ConvertType(type));
}
catch (Exception ex)
{
Debug.WriteLine($"HapticFeedback Exception: {ex.Message}");
}
}

static FeedbackConstants ConvertType(HapticFeedbackType type) =>
type switch
{
HapticFeedbackType.LongPress => FeedbackConstants.LongPress,
_ => FeedbackConstants.ContextClick
};
}
}
46 changes: 46 additions & 0 deletions Xamarin.Essentials/HapticFeedback/HapticFeedback.ios.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using UIKit;

namespace Xamarin.Essentials
{
public static partial class HapticFeedback
{
internal static bool IsSupported => true;

static void PlatformPerform(HapticFeedbackType type)
{
switch (type)
{
case HapticFeedbackType.LongPress:
PlatformLongPress();
break;
default:
PlatformClick();
break;
}
}

static void PlatformClick()
{
if (Platform.HasOSVersion(10, 0))
{
var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light);
impact.Prepare();
impact.ImpactOccurred();
impact.Dispose();
}
}

static void PlatformLongPress()
{
if (Platform.HasOSVersion(10, 0))
{
var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium);
impact.Prepare();
impact.ImpactOccurred();
impact.Dispose();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Threading.Tasks;

namespace Xamarin.Essentials
{
public static partial class HapticFeedback
{
internal static bool IsSupported
=> throw ExceptionUtils.NotSupportedOrImplementedException;

static void PlatformPerform(HapticFeedbackType type)
=> throw ExceptionUtils.NotSupportedOrImplementedException;
}
}
Loading

0 comments on commit 85af246

Please sign in to comment.