Commit e53ffd09 by Marcel Garus

update permission_handler_platform_interface to support new api

parent f3d2fd81
...@@ -5,4 +5,6 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; ...@@ -5,4 +5,6 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'src/method_channel/method_channel_permission_handler.dart'; import 'src/method_channel/method_channel_permission_handler.dart';
part 'src/permission_handler_platform_interface.dart'; part 'src/permission_handler_platform_interface.dart';
part 'src/permission_handler_enums.dart'; part 'src/permission_status.dart';
part 'src/permissions.dart';
part 'src/service_status.dart';
...@@ -13,9 +13,8 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform { ...@@ -13,9 +13,8 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform {
/// Check current permission status. /// Check current permission status.
/// ///
/// Returns a [Future] containing the current permission status for the /// Returns a [Future] containing the current permission status for the
/// supplied [PermissionGroup]. /// supplied [Permission].
Future<PermissionStatus> checkPermissionStatus( Future<PermissionStatus> checkPermissionStatus(Permission permission) async {
PermissionGroup permission) async {
final status = await _methodChannel.invokeMethod( final status = await _methodChannel.invokeMethod(
'checkPermissionStatus', permission.value); 'checkPermissionStatus', permission.value);
...@@ -25,10 +24,10 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform { ...@@ -25,10 +24,10 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform {
/// Check current service status. /// Check current service status.
/// ///
/// Returns a [Future] containing the current service status for the supplied /// Returns a [Future] containing the current service status for the supplied
/// [PermissionGroup]. /// [Permission].
/// ///
/// Notes about specific PermissionGroups: /// Notes about specific permissions:
/// - **PermissionGroup.phone** /// - **[Permission.phone]**
/// - Android: /// - Android:
/// - The method will return [ServiceStatus.notApplicable] when: /// - The method will return [ServiceStatus.notApplicable] when:
/// 1. the device lacks the TELEPHONY feature /// 1. the device lacks the TELEPHONY feature
...@@ -45,7 +44,7 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform { ...@@ -45,7 +44,7 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform {
/// - **PLEASE NOTE that this is still not a perfect indication** of the /// - **PLEASE NOTE that this is still not a perfect indication** of the
/// devices' capability to place & connect phone calls /// devices' capability to place & connect phone calls
/// as it also depends on the network condition. /// as it also depends on the network condition.
Future<ServiceStatus> checkServiceStatus(PermissionGroup permission) async { Future<ServiceStatus> checkServiceStatus(Permission permission) async {
final status = await _methodChannel.invokeMethod( final status = await _methodChannel.invokeMethod(
'checkServiceStatus', permission.value); 'checkServiceStatus', permission.value);
...@@ -62,12 +61,12 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform { ...@@ -62,12 +61,12 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform {
return hasOpened; return hasOpened;
} }
/// Request the user for access to the supplied list of permissiongroups. /// Request the user for access to the supplied list of Permissions.
/// ///
/// Returns a [Map] containing the status per requested permissiongroup. /// Returns a [Map] containing the status per requested Permission.
Future<Map<PermissionGroup, PermissionStatus>> requestPermissions( Future<Map<Permission, PermissionStatus>> requestPermissions(
List<PermissionGroup> permissions) async { List<Permission> permissions) async {
final data = Codec.encodePermissionGroups(permissions); final data = Codec.encodePermissions(permissions);
final status = final status =
await _methodChannel.invokeMethod('requestPermissions', data); await _methodChannel.invokeMethod('requestPermissions', data);
...@@ -79,7 +78,7 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform { ...@@ -79,7 +78,7 @@ class MethodChannelPermissionHandler extends PermissionHandlerPlatform {
/// This method is only implemented on Android, calling this on iOS always /// This method is only implemented on Android, calling this on iOS always
/// returns [false]. /// returns [false].
Future<bool> shouldShowRequestPermissionRationale( Future<bool> shouldShowRequestPermissionRationale(
PermissionGroup permission) async { Permission permission) async {
final shouldShowRationale = await _methodChannel.invokeMethod( final shouldShowRationale = await _methodChannel.invokeMethod(
'shouldShowRequestPermissionRationale', permission.value); 'shouldShowRequestPermissionRationale', permission.value);
......
...@@ -5,27 +5,26 @@ import '../../../permission_handler_platform_interface.dart'; ...@@ -5,27 +5,26 @@ import '../../../permission_handler_platform_interface.dart';
class Codec { class Codec {
/// Converts the supplied integer value into a [PermissionStatus] instance. /// Converts the supplied integer value into a [PermissionStatus] instance.
static PermissionStatus decodePermissionStatus(int value) { static PermissionStatus decodePermissionStatus(int value) {
return PermissionStatus.values[value]; return PermissionStatusValue.statusByValue(value);
} }
/// Converts the supplied integer value into a [ServiceStatus] instance. /// Converts the supplied integer value into a [ServiceStatus] instance.
static ServiceStatus decodeServiceStatus(int value) { static ServiceStatus decodeServiceStatus(int value) {
return ServiceStatus.values[value]; return ServiceStatusValue.statusByValue(value);
} }
/// Converts the supplied [Map] of integers into a [Map] of /// Converts the supplied [Map] of integers into a [Map] of [Permission] key
/// [PermissionGroup] key and [PermissionStatus] value instances. /// and [PermissionStatus] value instances.
static Map<PermissionGroup, PermissionStatus> decodePermissionRequestResult( static Map<Permission, PermissionStatus> decodePermissionRequestResult(
Map<int, int> value) { Map<int, int> value) {
return value.map((key, value) => return value.map((key, value) => MapEntry<Permission, PermissionStatus>(
MapEntry<PermissionGroup, PermissionStatus>( Permission.byValue(key), PermissionStatusValue.statusByValue(value)));
PermissionGroup.values[key], PermissionStatus.values[value]));
} }
/// Converts the supplied [List] containing [PermissionGroup] instances into /// Converts the supplied [List] containing [Permission] instances into
/// a [List] containing integers which can be used to send on the Flutter /// a [List] containing integers which can be used to send on the Flutter
/// method channel. /// method channel.
static List<int> encodePermissionGroups(List<PermissionGroup> permissions) { static List<int> encodePermissions(List<Permission> permissions) {
return permissions.map((it) => it.value).toList(); return permissions.map((it) => it.value).toList();
} }
} }
part of permission_handler_platform_interface;
/// Defines the state of a permission group
class PermissionStatus {
const PermissionStatus._(this.value);
/// Integer representation of the [PermissionStatus].
final int value;
/// Permission to access the requested feature is denied by the user.
static const PermissionStatus denied = PermissionStatus._(0);
/// Permission to access the requested feature is granted by the user.
static const PermissionStatus granted = PermissionStatus._(1);
/// Permission to access the requested feature is denied by the OS (only on
/// iOS). The user cannot change this app's status, possibly due to active
/// restrictions such as parental controls being in place.
static const PermissionStatus restricted = PermissionStatus._(2);
/// Permission is in an unknown state
static const PermissionStatus unknown = PermissionStatus._(3);
/// Permission to access the requested feature is denied by the user and
/// never show selected (only on Android).
static const PermissionStatus neverAskAgain = PermissionStatus._(4);
/// Returns a list of all possible [PermissionStatus] values.
static const List<PermissionStatus> values = <PermissionStatus>[
denied,
granted,
restricted,
unknown,
neverAskAgain,
];
static const List<String> _names = <String>[
'denied',
'granted',
'restricted',
'unknown',
'neverAskAgain',
];
@override
String toString() => 'PermissionStatus.${_names[value]}';
}
/// Defines the state of a service related to the permission group
class ServiceStatus {
const ServiceStatus._(this.value);
/// Integer representation of the [ServiceStatus].
final int value;
/// The service for the supplied permission group is disabled.
static const ServiceStatus disabled = ServiceStatus._(0);
/// The service for the supplied permission group is enabled.
static const ServiceStatus enabled = ServiceStatus._(1);
/// There is no service for the supplied permission group.
static const ServiceStatus notApplicable = ServiceStatus._(2);
/// The unknown service status indicates the state of the service could not
/// be determined.
static const ServiceStatus unknown = ServiceStatus._(3);
/// Returns a list of all possible [ServiceStatus] values.
static const List<ServiceStatus> values = <ServiceStatus>[
disabled,
enabled,
notApplicable,
unknown,
];
static const List<String> _names = <String>[
'disabled',
'enabled',
'notApplicable',
'unknown',
];
@override
String toString() => 'ServiceStatus.${_names[value]}';
}
/// Defines the permission groups for which permissions can be checked or
/// requested.
class PermissionGroup {
const PermissionGroup._(this.value);
/// Integer representation of the [PermissionGroup].
final int value;
/// Android: Calendar
/// iOS: Calendar (Events)
static const PermissionGroup calendar = PermissionGroup._(0);
/// Android: Camera
/// iOS: Photos (Camera Roll and Camera)
static const PermissionGroup camera = PermissionGroup._(1);
/// Android: Contacts
/// iOS: AddressBook
static const PermissionGroup contacts = PermissionGroup._(2);
/// Android: Fine and Coarse Location
/// iOS: CoreLocation (Always and WhenInUse)
static const PermissionGroup location = PermissionGroup._(3);
/// Android:
/// When running on Android < Q: Fine and Coarse Location
/// When running on Android Q and above: Background Location Permission
/// iOS: CoreLocation - Always
static const PermissionGroup locationAlways = PermissionGroup._(4);
/// Android: Fine and Coarse Location
/// iOS: CoreLocation - WhenInUse
static const PermissionGroup locationWhenInUse = PermissionGroup._(5);
/// Android: None
/// iOS: MPMediaLibrary
static const PermissionGroup mediaLibrary = PermissionGroup._(6);
/// Android: Microphone
/// iOS: Microphone
static const PermissionGroup microphone = PermissionGroup._(7);
/// Android: Phone
/// iOS: Nothing
static const PermissionGroup phone = PermissionGroup._(8);
/// Android: Nothing
/// iOS: Photos
static const PermissionGroup photos = PermissionGroup._(9);
/// Android: Nothing
/// iOS: Reminders
static const PermissionGroup reminders = PermissionGroup._(10);
/// Android: Body Sensors
/// iOS: CoreMotion
static const PermissionGroup sensors = PermissionGroup._(11);
/// Android: Sms
/// iOS: Nothing
static const PermissionGroup sms = PermissionGroup._(12);
/// Android: Microphone
/// iOS: Speech
static const PermissionGroup speech = PermissionGroup._(13);
/// Android: External Storage
/// iOS: Access to folders like `Documents` or `Downloads`. Implicitly
/// granted.
static const PermissionGroup storage = PermissionGroup._(14);
/// Android: Ignore Battery Optimizations
static const PermissionGroup ignoreBatteryOptimizations =
PermissionGroup._(15);
/// Android: Notification
/// iOS: Notification
static const PermissionGroup notification = PermissionGroup._(16);
/// Android: Allows an application to access any geographic locations
/// persisted in the user's shared collection.
static const PermissionGroup accessMediaLocation = PermissionGroup._(17);
/// When running on Android Q and above: Activity Recognition
/// When running on Android < Q: Nothing
/// iOS: Nothing
static const PermissionGroup activityRecognition = PermissionGroup._(18);
/// The unknown permission only used for return type, never requested
static const PermissionGroup unknown = PermissionGroup._(19);
/// Returns a list of all possible [PermissionGroup] values.
static const List<PermissionGroup> values = <PermissionGroup>[
calendar,
camera,
contacts,
location,
locationAlways,
locationWhenInUse,
mediaLibrary,
microphone,
phone,
photos,
reminders,
sensors,
sms,
speech,
storage,
ignoreBatteryOptimizations,
notification,
accessMediaLocation,
activityRecognition,
unknown,
];
static const List<String> _names = <String>[
'calendar',
'camera',
'contacts',
'location',
'locationAlways',
'locationWhenInUse',
'mediaLibrary',
'microphone',
'phone',
'photos',
'reminders',
'sensors',
'sms',
'speech',
'storage',
'ignoreBatteryOptimizations',
'notification',
'access_media_location',
'activity_recognition',
'unknown',
];
@override
String toString() => 'PermissionGroup.${_names[value]}';
}
...@@ -32,7 +32,7 @@ abstract class PermissionHandlerPlatform extends PlatformInterface { ...@@ -32,7 +32,7 @@ abstract class PermissionHandlerPlatform extends PlatformInterface {
/// ///
/// Returns a [Future] containing the current permission status for the /// Returns a [Future] containing the current permission status for the
/// supplied [PermissionGroup]. /// supplied [PermissionGroup].
Future<PermissionStatus> checkPermissionStatus(PermissionGroup permission) { Future<PermissionStatus> checkPermissionStatus(Permission permission) {
throw UnimplementedError( throw UnimplementedError(
'checkPermissionStatus() has not been implemented.'); 'checkPermissionStatus() has not been implemented.');
} }
...@@ -40,10 +40,10 @@ abstract class PermissionHandlerPlatform extends PlatformInterface { ...@@ -40,10 +40,10 @@ abstract class PermissionHandlerPlatform extends PlatformInterface {
/// Check current service status. /// Check current service status.
/// ///
/// Returns a [Future] containing the current service status for the supplied /// Returns a [Future] containing the current service status for the supplied
/// [PermissionGroup]. /// [Permission].
/// ///
/// Notes about specific PermissionGroups: /// Notes about specific [Permission]s:
/// - **PermissionGroup.phone** /// - **[Permission.phone]**
/// - Android: /// - Android:
/// - The method will return [ServiceStatus.notApplicable] when: /// - The method will return [ServiceStatus.notApplicable] when:
/// 1. the device lacks the TELEPHONY feature /// 1. the device lacks the TELEPHONY feature
...@@ -60,7 +60,7 @@ abstract class PermissionHandlerPlatform extends PlatformInterface { ...@@ -60,7 +60,7 @@ abstract class PermissionHandlerPlatform extends PlatformInterface {
/// - **PLEASE NOTE that this is still not a perfect indication** of the /// - **PLEASE NOTE that this is still not a perfect indication** of the
/// devices' capability to place & connect phone calls /// devices' capability to place & connect phone calls
/// as it also depends on the network condition. /// as it also depends on the network condition.
Future<ServiceStatus> checkServiceStatus(PermissionGroup permission) { Future<ServiceStatus> checkServiceStatus(Permission permission) {
throw UnimplementedError('checkServiceStatus() has not been implemented.'); throw UnimplementedError('checkServiceStatus() has not been implemented.');
} }
...@@ -75,8 +75,8 @@ abstract class PermissionHandlerPlatform extends PlatformInterface { ...@@ -75,8 +75,8 @@ abstract class PermissionHandlerPlatform extends PlatformInterface {
/// Request the user for access to the supplied list of permissiongroups. /// Request the user for access to the supplied list of permissiongroups.
/// ///
/// Returns a [Map] containing the status per requested permissiongroup. /// Returns a [Map] containing the status per requested permissiongroup.
Future<Map<PermissionGroup, PermissionStatus>> requestPermissions( Future<Map<Permission, PermissionStatus>> requestPermissions(
List<PermissionGroup> permissions) { List<Permission> permissions) {
throw UnimplementedError('requestPermissions() has not been implemented.'); throw UnimplementedError('requestPermissions() has not been implemented.');
} }
...@@ -84,8 +84,7 @@ abstract class PermissionHandlerPlatform extends PlatformInterface { ...@@ -84,8 +84,7 @@ abstract class PermissionHandlerPlatform extends PlatformInterface {
/// ///
/// This method is only implemented on Android, calling this on iOS always /// This method is only implemented on Android, calling this on iOS always
/// returns [false]. /// returns [false].
Future<bool> shouldShowRequestPermissionRationale( Future<bool> shouldShowRequestPermissionRationale(Permission permission) {
PermissionGroup permission) {
throw UnimplementedError( throw UnimplementedError(
'shouldShowRequestPermissionRationale() has not been implemented.'); 'shouldShowRequestPermissionRationale() has not been implemented.');
} }
......
part of permission_handler_platform_interface;
/// Defines the state of a [Permission].
enum PermissionStatus {
/// The user denied access to the requested feature.
denied,
/// The user granted access to the requested feature.
granted,
/// The OS denied access to the requested feature. The user cannot change
/// this app's status, possibly due to active restrictions such as parental
/// controls being in place.
/// *Only supported on iOS.*
restricted,
/// The permission is in an unknown state.
unknown,
/// The user denied access to the requested feature and selected to never
/// again show a request for this permission.
/// *Only supported on Android.*
neverAskAgain,
}
extension PermissionStatusValue on PermissionStatus {
int get value {
switch (this) {
case PermissionStatus.denied:
return 0;
case PermissionStatus.granted:
return 1;
case PermissionStatus.restricted:
return 2;
case PermissionStatus.unknown:
return 3;
case PermissionStatus.neverAskAgain:
return 4;
default:
throw UnimplementedError();
}
}
static PermissionStatus statusByValue(int value) {
return [
PermissionStatus.denied,
PermissionStatus.granted,
PermissionStatus.restricted,
PermissionStatus.unknown,
PermissionStatus.neverAskAgain,
][value];
}
}
extension PermissionStatusGetters on PermissionStatus {
/// If the user denied access to the requested feature.
bool get isDenied => this == PermissionStatus.denied;
/// If the user granted access to the requested feature.
bool get isGranted => this == PermissionStatus.granted;
/// If the OS denied access to the requested feature. The user cannot change
/// this app's status, possibly due to active restrictions such as parental
/// controls being in place.
/// *Only supported on iOS.*
bool get isRestricted => this == PermissionStatus.restricted;
/// If the permission is in an unknown state.
bool get isUnknown => this == PermissionStatus.unknown;
/// If the user denied access to the requested feature and selected to never
/// again show a request for this permission.
/// *Only supported on Android.*
bool get isNeverAskAgain => this == PermissionStatus.neverAskAgain;
}
extension FuturePermissionStatusGetters on Future<PermissionStatus> {
/// If the user denied access to the requested feature.
Future<bool> get isDenied async => (await this).isDenied;
/// If the user granted access to the requested feature.
Future<bool> get isGranted async => (await this).isGranted;
/// If the OS denied access to the requested feature. The user cannot change
/// this app's status, possibly due to active restrictions such as parental
/// controls being in place.
/// *Only supported on iOS.*
Future<bool> get isRestricted async => (await this).isRestricted;
/// If the permission is in an unknown state.
Future<bool> get isUnknown async => (await this).isUnknown;
/// If the user denied access to the requested feature and selected to never
/// again show a request for this permission.
/// *Only supported on Android.*
Future<bool> get isNeverAskAgain async => (await this).isNeverAskAgain;
}
part of permission_handler_platform_interface;
/// A special kind of permission used to access a service. Additionally to
/// normal [Permission]s, you can also query the status of the related service.
class ServicePermission extends Permission {
const ServicePermission._(int value) : super._(value);
}
/// Defines the permissions which can be checked and requested.
class Permission {
const Permission._(this.value);
factory Permission.byValue(int value) => values[value];
/// Integer representation of the [Permission].
final int value;
/// Android: Calendar
/// iOS: Calendar (Events)
static const calendar = Permission._(0);
/// Android: Camera
/// iOS: Photos (Camera Roll and Camera)
static const camera = Permission._(1);
/// Android: Contacts
/// iOS: AddressBook
static const contacts = Permission._(2);
/// Android: Fine and Coarse Location
/// iOS: CoreLocation (Always and WhenInUse)
static const location = ServicePermission._(3);
/// Android:
/// When running on Android < Q: Fine and Coarse Location
/// When running on Android Q and above: Background Location Permission
/// iOS: CoreLocation - Always
static const locationAlways = ServicePermission._(4);
/// Android: Fine and Coarse Location
/// iOS: CoreLocation - WhenInUse
static const locationWhenInUse = ServicePermission._(5);
/// Android: None
/// iOS: MPMediaLibrary
static const mediaLibrary = Permission._(6);
/// Android: Microphone
/// iOS: Microphone
static const microphone = Permission._(7);
/// Android: Phone
/// iOS: Nothing
static const phone = Permission._(8);
/// Android: Nothing
/// iOS: Photos
static const photos = Permission._(9);
/// Android: Nothing
/// iOS: Reminders
static const reminders = Permission._(10);
/// Android: Body Sensors
/// iOS: CoreMotion
static const sensors = Permission._(11);
/// Android: Sms
/// iOS: Nothing
static const sms = Permission._(12);
/// Android: Microphone
/// iOS: Speech
static const speech = Permission._(13);
/// Android: External Storage
/// iOS: Access to folders like `Documents` or `Downloads`. Implicitly
/// granted.
static const storage = Permission._(14);
/// Android: Ignore Battery Optimizations
static const ignoreBatteryOptimizations = Permission._(15);
/// Android: Notification
/// iOS: Notification
static const notification = Permission._(16);
/// Android: Allows an application to access any geographic locations
/// persisted in the user's shared collection.
static const accessMediaLocation = Permission._(17);
/// When running on Android Q and above: Activity Recognition
/// When running on Android < Q: Nothing
/// iOS: Nothing
static const activityRecognition = Permission._(18);
/// The unknown only used for return type, never requested
static const unknown = Permission._(19);
/// Returns a list of all possible [PermissionGroup] values.
static const List<Permission> values = <Permission>[
calendar,
camera,
contacts,
location,
locationAlways,
locationWhenInUse,
mediaLibrary,
microphone,
phone,
photos,
reminders,
sensors,
sms,
speech,
storage,
ignoreBatteryOptimizations,
notification,
accessMediaLocation,
activityRecognition,
unknown,
];
static const List<String> _names = <String>[
'calendar',
'camera',
'contacts',
'location',
'locationAlways',
'locationWhenInUse',
'mediaLibrary',
'microphone',
'phone',
'photos',
'reminders',
'sensors',
'sms',
'speech',
'storage',
'ignoreBatteryOptimizations',
'notification',
'access_media_location',
'activity_recognition',
'unknown',
];
@override
String toString() => 'PermissionGroup.${_names[value]}';
}
part of permission_handler_platform_interface;
enum ServiceStatus {
/// The service for the permission is disabled.
disabled,
/// The service for the permission is enabled.
enabled,
/// The permission does not have an associated service.
notApplicable,
/// The state of the service could not be determined.
unknown,
}
extension ServiceStatusValue on ServiceStatus {
int get value {
switch (this) {
case ServiceStatus.disabled:
return 0;
case ServiceStatus.enabled:
return 1;
case ServiceStatus.notApplicable:
return 2;
case ServiceStatus.unknown:
return 3;
default:
throw UnimplementedError();
}
}
static ServiceStatus statusByValue(int value) {
return [
ServiceStatus.disabled,
ServiceStatus.enabled,
ServiceStatus.notApplicable,
ServiceStatus.unknown,
][value];
}
}
extension ServiceStatusGetters on ServiceStatus {
/// If the service for the permission is disabled.
bool get isDisabled => this == ServiceStatus.disabled;
/// If the service for the permission is enabled.
bool get isEnabled => this == ServiceStatus.enabled;
/// If the permission does not have an associated service.
bool get isNotApplicable => this == ServiceStatus.notApplicable;
/// If the state of the service could not be determined.
bool get isUnknown => this == ServiceStatus.unknown;
}
extension FutureServiceStatusGetters on Future<ServiceStatus> {
/// If the service for the permission is disabled.
Future<bool> get isDisabled async => (await this).isDisabled;
/// If the service for the permission is enabled.
Future<bool> get isEnabled async => (await this).isEnabled;
/// If the permission does not have an associated service.
Future<bool> get isNotApplicable async => (await this).isNotApplicable;
/// If the state of the service could not be determined.
Future<bool> get isUnknown async => (await this).isUnknown;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment