Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Permission Handling for Improved Readability #1164

Merged
merged 9 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions permission_handler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 11.0.1

* Adds extension methods to the `PermissionStatus` enum allowing developers to register callback methods, which will improve code readability.

## 11.0.0

* **BREAKING CHANGE:** Updates `permission_handler_android` dependency to version 11.0.0.
Expand Down
76 changes: 74 additions & 2 deletions permission_handler/lib/permission_handler.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart';

Expand All @@ -21,6 +23,60 @@ Future<bool> openAppSettings() => _handler.openAppSettings();

/// Actions that can be executed on a permission.
extension PermissionActions on Permission {
/// Callback for when permission is denied.
static FutureOr<void>? Function()? onDenied;
michaelnabil230 marked this conversation as resolved.
Show resolved Hide resolved

/// Callback for when permission is granted.
static FutureOr<void>? Function()? onGranted;

/// Callback for when permission is permanently denied.
static FutureOr<void>? Function()? onPermanentlyDenied;

/// Callback for when permission is restricted.
static FutureOr<void>? Function()? onRestricted;

/// Callback for when permission is limited.
static FutureOr<void>? Function()? onLimited;

/// Callback for when permission is Provisional.
static FutureOr<void>? Function()? onProvisional;

/// Method to set a callback for when permission is denied.
Permission onDeniedCallback(FutureOr<void>? Function()? callback) {
onDenied = callback;
return this;
}

/// Method to set a callback for when permission is granted.
Permission onGrantedCallback(FutureOr<void>? Function()? callback) {
onGranted = callback;
return this;
}

/// Method to set a callback for when permission is permanently denied.
Permission onPermanentlyDeniedCallback(FutureOr<void>? Function()? callback) {
onPermanentlyDenied = callback;
return this;
}

/// Method to set a callback for when permission is restricted.
Permission onRestrictedCallback(FutureOr<void>? Function()? callback) {
onRestricted = callback;
return this;
}

/// Method to set a callback for when permission is limited.
Permission onLimitedCallback(FutureOr<void>? Function()? callback) {
onLimited = callback;
return this;
}

/// Method to set a callback for when permission is provisional.
Permission onProvisionalCallback(FutureOr<void>? Function()? callback) {
onProvisional = callback;
return this;
}

/// Checks the current status of the given [Permission].
///
/// Notes about specific permissions:
Expand Down Expand Up @@ -49,8 +105,24 @@ extension PermissionActions on Permission {
///
/// Returns the new [PermissionStatus].
Future<PermissionStatus> request() async {
final permissionStatus = (await [this].request())[this];
return permissionStatus ?? PermissionStatus.denied;
final permissionStatus =
(await [this].request())[this] ?? PermissionStatus.denied;

if (permissionStatus.isDenied) {
onDenied?.call();
} else if (permissionStatus.isGranted) {
onGranted?.call();
} else if (permissionStatus.isPermanentlyDenied) {
onPermanentlyDenied?.call();
} else if (permissionStatus.isRestricted) {
onRestricted?.call();
} else if (permissionStatus.isLimited) {
onLimited?.call();
} else if (permissionStatus.isProvisional) {
onProvisional?.call();
}

return permissionStatus;
}
}

Expand Down
2 changes: 1 addition & 1 deletion permission_handler/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: permission_handler
description: Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
repository: https://github.com/baseflow/flutter-permission-handler
issue_tracker: https://github.com/Baseflow/flutter-permission-handler/issues
version: 11.0.0
version: 11.0.1

environment:
sdk: ">=2.15.0 <4.0.0"
Expand Down
58 changes: 57 additions & 1 deletion permission_handler/test/permission_handler_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ void main() {
setUp(() {
PermissionHandlerPlatform.instance = MockPermissionHandlerPlatform();
});

test('openAppSettings', () async {
final hasOpened = await openAppSettings();

Expand Down Expand Up @@ -94,6 +93,63 @@ void main() {

expect(permissionMap, isA<Map<Permission, PermissionStatus>>());
});

test('onDeniedCallback sets onDenied', () {
callback() => true;
const permission = Permission.camera;
permission.onDeniedCallback(callback);
expect(PermissionActions.onDenied, callback);
});

test('onGrantedCallback sets onGranted', () {
callback() => true;
const permission = Permission.camera;
permission.onGrantedCallback(callback);
expect(PermissionActions.onGranted, callback);
});

test('onPermanentlyDeniedCallback sets onPermanentlyDenied', () {
callback() => true;
const permission = Permission.camera;
permission.onPermanentlyDeniedCallback(callback);
expect(PermissionActions.onPermanentlyDenied, callback);
});

test('onRestrictedCallback sets onRestricted', () {
callback() => true;
const permission = Permission.camera;
permission.onRestrictedCallback(callback);
expect(PermissionActions.onRestricted, callback);
});

test('onLimitedCallback sets onLimited', () {
const permission = Permission.camera;
callback() => true;
permission.onLimitedCallback(callback);
expect(PermissionActions.onLimited, callback);
});

test('onProvisionalCallback sets onProvisional', () {
callback() => true;
const permission = Permission.camera;
permission.onProvisionalCallback(callback);
expect(PermissionActions.onProvisional, callback);
});

test('ask calls the appropriate callback', () async {
callback() => true;

final status = Permission.camera
.onDeniedCallback(callback)
.onGrantedCallback(callback)
.onPermanentlyDeniedCallback(callback)
.onRestrictedCallback(callback)
.onLimitedCallback(callback)
.onProvisionalCallback(callback)
.request();

expect(status, isA<Future<PermissionStatus>>());
});
});
}

Expand Down