Skip to content

Commit a3bacb4

Browse files
Refactor Permission Handling for Improved Readability (#1164)
* Add `PermissionCallbacks` * Fix * Clean tests * Update permission_handler/CHANGELOG.md Co-authored-by: Maurits van Beusekom <maurits@baseflow.com> * Fix type * Merge `PermissionCallbacks` to `PermissionActions` * Fix format * Fix test * Convert all the variables to private --------- Co-authored-by: Maurits van Beusekom <maurits@baseflow.com>
1 parent 83329fa commit a3bacb4

File tree

4 files changed

+144
-3
lines changed

4 files changed

+144
-3
lines changed

permission_handler/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 11.0.1
2+
3+
* Adds extension methods to the `PermissionStatus` enum allowing developers to register callback methods, which will improve code readability.
4+
15
## 11.0.0
26

37
* **BREAKING CHANGE:** Updates `permission_handler_android` dependency to version 11.0.0.

permission_handler/lib/permission_handler.dart

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:async';
2+
13
import 'package:flutter/foundation.dart';
24
import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart';
35

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

2224
/// Actions that can be executed on a permission.
2325
extension PermissionActions on Permission {
26+
/// Callback for when permission is denied.
27+
static FutureOr<void>? Function()? _onDenied;
28+
29+
/// Callback for when permission is granted.
30+
static FutureOr<void>? Function()? _onGranted;
31+
32+
/// Callback for when permission is permanently denied.
33+
static FutureOr<void>? Function()? _onPermanentlyDenied;
34+
35+
/// Callback for when permission is restricted.
36+
static FutureOr<void>? Function()? _onRestricted;
37+
38+
/// Callback for when permission is limited.
39+
static FutureOr<void>? Function()? _onLimited;
40+
41+
/// Callback for when permission is Provisional.
42+
static FutureOr<void>? Function()? _onProvisional;
43+
44+
/// Method to set a callback for when permission is denied.
45+
Permission onDeniedCallback(FutureOr<void>? Function()? callback) {
46+
_onDenied = callback;
47+
return this;
48+
}
49+
50+
/// Method to set a callback for when permission is granted.
51+
Permission onGrantedCallback(FutureOr<void>? Function()? callback) {
52+
_onGranted = callback;
53+
return this;
54+
}
55+
56+
/// Method to set a callback for when permission is permanently denied.
57+
Permission onPermanentlyDeniedCallback(FutureOr<void>? Function()? callback) {
58+
_onPermanentlyDenied = callback;
59+
return this;
60+
}
61+
62+
/// Method to set a callback for when permission is restricted.
63+
Permission onRestrictedCallback(FutureOr<void>? Function()? callback) {
64+
_onRestricted = callback;
65+
return this;
66+
}
67+
68+
/// Method to set a callback for when permission is limited.
69+
Permission onLimitedCallback(FutureOr<void>? Function()? callback) {
70+
_onLimited = callback;
71+
return this;
72+
}
73+
74+
/// Method to set a callback for when permission is provisional.
75+
Permission onProvisionalCallback(FutureOr<void>? Function()? callback) {
76+
_onProvisional = callback;
77+
return this;
78+
}
79+
2480
/// Checks the current status of the given [Permission].
2581
///
2682
/// Notes about specific permissions:
@@ -49,8 +105,24 @@ extension PermissionActions on Permission {
49105
///
50106
/// Returns the new [PermissionStatus].
51107
Future<PermissionStatus> request() async {
52-
final permissionStatus = (await [this].request())[this];
53-
return permissionStatus ?? PermissionStatus.denied;
108+
final permissionStatus =
109+
(await [this].request())[this] ?? PermissionStatus.denied;
110+
111+
if (permissionStatus.isDenied) {
112+
_onDenied?.call();
113+
} else if (permissionStatus.isGranted) {
114+
_onGranted?.call();
115+
} else if (permissionStatus.isPermanentlyDenied) {
116+
_onPermanentlyDenied?.call();
117+
} else if (permissionStatus.isRestricted) {
118+
_onRestricted?.call();
119+
} else if (permissionStatus.isLimited) {
120+
_onLimited?.call();
121+
} else if (permissionStatus.isProvisional) {
122+
_onProvisional?.call();
123+
}
124+
125+
return permissionStatus;
54126
}
55127
}
56128

permission_handler/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: permission_handler
22
description: Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
33
repository: https://github.com/baseflow/flutter-permission-handler
44
issue_tracker: https://github.com/Baseflow/flutter-permission-handler/issues
5-
version: 11.0.0
5+
version: 11.0.1
66

77
environment:
88
sdk: ">=2.15.0 <4.0.0"

permission_handler/test/permission_handler_test.dart

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,71 @@ void main() {
9494

9595
expect(permissionMap, isA<Map<Permission, PermissionStatus>>());
9696
});
97+
98+
test('onDeniedCallback sets onDenied', () async {
99+
bool callbackCalled = false;
100+
callback() => callbackCalled = true;
101+
await Permission.location.onDeniedCallback(callback).request();
102+
expect(callbackCalled, isTrue);
103+
});
104+
105+
test('onGrantedCallback sets onGranted', () async {
106+
bool callbackCalled = false;
107+
callback() => callbackCalled = true;
108+
await Permission.location.onGrantedCallback(callback).request();
109+
expect(callbackCalled, isFalse);
110+
});
111+
112+
test('onPermanentlyDeniedCallback sets onPermanentlyDenied', () async {
113+
bool callbackCalled = false;
114+
callback() => callbackCalled = true;
115+
await Permission.location.onPermanentlyDeniedCallback(callback).request();
116+
expect(callbackCalled, isFalse);
117+
});
118+
119+
test('onRestrictedCallback sets onRestricted', () async {
120+
bool callbackCalled = false;
121+
callback() => callbackCalled = true;
122+
await Permission.location.onRestrictedCallback(callback).request();
123+
expect(callbackCalled, isFalse);
124+
});
125+
126+
test('onLimitedCallback sets onLimited', () async {
127+
bool callbackCalled = false;
128+
callback() => callbackCalled = true;
129+
await Permission.location.onLimitedCallback(callback).request();
130+
expect(callbackCalled, isFalse);
131+
});
132+
133+
test('onProvisionalCallback sets onProvisional', () async {
134+
bool callbackCalled = false;
135+
callback() => callbackCalled = true;
136+
await Permission.location.onProvisionalCallback(callback).request();
137+
expect(callbackCalled, isFalse);
138+
});
139+
140+
test('onGrantedCallback sets onGranted', () async {
141+
bool callbackCalled = false;
142+
callback() => callbackCalled = true;
143+
await Permission.location.onGrantedCallback(callback).request();
144+
expect(callbackCalled, isFalse);
145+
});
146+
147+
test('ask calls the appropriate callback', () async {
148+
List<String> callbackCalled = [];
149+
150+
await Permission.camera
151+
.onDeniedCallback(() => callbackCalled.add('Denied'))
152+
.onGrantedCallback(() => callbackCalled.add('Granted'))
153+
.onPermanentlyDeniedCallback(
154+
() => callbackCalled.add('PermanentlyDenied'))
155+
.onRestrictedCallback(() => callbackCalled.add('Restricted'))
156+
.onLimitedCallback(() => callbackCalled.add('Limited'))
157+
.onProvisionalCallback(() => callbackCalled.add('Provisional'))
158+
.request();
159+
160+
expect(callbackCalled, ['Denied']);
161+
});
97162
});
98163
}
99164

0 commit comments

Comments
 (0)