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

Commit

Permalink
Fix #1999 - checkasync should return restricted for locationinuse whe…
Browse files Browse the repository at this point in the history
…n only coarse is granted
  • Loading branch information
aritchie committed May 2, 2022
1 parent 31f3de2 commit e8ce50d
Showing 1 changed file with 44 additions and 16 deletions.
60 changes: 44 additions & 16 deletions Xamarin.Essentials/Permissions/Permissions.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,13 @@ public override Task<PermissionStatus> CheckStatusAsync()
if (RequiredPermissions == null || RequiredPermissions.Length <= 0)
return Task.FromResult(PermissionStatus.Granted);

var context = Platform.AppContext;
var targetsMOrHigher = context.ApplicationInfo.TargetSdkVersion >= BuildVersionCodes.M;

foreach (var (androidPermission, isRuntime) in RequiredPermissions)
{
var ap = androidPermission;
if (!IsDeclaredInManifest(ap))
throw new PermissionException($"You need to declare using the permission: `{androidPermission}` in your AndroidManifest.xml");

var status = PermissionStatus.Granted;

if (targetsMOrHigher)
{
if (ContextCompat.CheckSelfPermission(context, androidPermission) != Permission.Granted)
status = PermissionStatus.Denied;
}
else
{
if (PermissionChecker.CheckSelfPermission(context, androidPermission) != PermissionChecker.PermissionGranted)
status = PermissionStatus.Denied;
}

var status = DoCheck(ap);
if (status != PermissionStatus.Granted)
return Task.FromResult(PermissionStatus.Denied);
}
Expand Down Expand Up @@ -107,6 +92,38 @@ public override async Task<PermissionStatus> RequestAsync()
return PermissionStatus.Granted;
}

protected virtual PermissionStatus DoCheck(string androidPermission)
{
var context = Platform.AppContext;
var targetsMOrHigher = context.ApplicationInfo.TargetSdkVersion >= BuildVersionCodes.M;

if (!IsDeclaredInManifest(androidPermission))
throw new PermissionException($"You need to declare using the permission: `{androidPermission}` in your AndroidManifest.xml");

var status = PermissionStatus.Granted;

if (targetsMOrHigher)
{
status = ContextCompat.CheckSelfPermission(context, androidPermission) switch
{
Permission.Granted => PermissionStatus.Granted,
Permission.Denied => PermissionStatus.Denied,
_ => PermissionStatus.Unknown
};
}
else
{
status = PermissionChecker.CheckSelfPermission(context, androidPermission) switch
{
PermissionChecker.PermissionGranted => PermissionStatus.Granted,
PermissionChecker.PermissionDenied => PermissionStatus.Denied,
PermissionChecker.PermissionDeniedAppOp => PermissionStatus.Denied,
_ => PermissionStatus.Unknown
};
}
return status;
}

protected virtual async Task<PermissionResult> DoRequest(string[] permissions)
{
TaskCompletionSource<PermissionResult> tcs;
Expand Down Expand Up @@ -233,6 +250,17 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions
(Manifest.Permission.AccessFineLocation, true)
};

public override Task<PermissionStatus> CheckStatusAsync()
{
if (DoCheck(Manifest.Permission.AccessFineLocation) == PermissionStatus.Granted)
return Task.FromResult(PermissionStatus.Granted);

if (DoCheck(Manifest.Permission.AccessCoarseLocation) == PermissionStatus.Granted)
return Task.FromResult(PermissionStatus.Restricted);

return Task.FromResult(PermissionStatus.Denied);
}

public override async Task<PermissionStatus> RequestAsync()
{
// Check status before requesting first
Expand Down

0 comments on commit e8ce50d

Please sign in to comment.