Skip to content

Commit 9907d20

Browse files
authored
Html non secure permissions (#1240)
* fixed plugin init with non-https web app * fixed plugin init with non-https web app * fixed handling of nullable values * fixed _locationPermissionName * better error handling * PR feedback * PR feedback
1 parent e3c92e3 commit 9907d20

File tree

5 files changed

+54
-74
lines changed

5 files changed

+54
-74
lines changed

permission_handler_html/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.1.1
2+
3+
* Fixed plugin initialization for non-https web app.
4+
* Fixed location permission name
5+
* Improved error handling in the example app
6+
17
## 0.1.0+1
28

39
* Updates `permission_handler_platform_interface` dependency to version `^4.0.2`.

permission_handler_html/example/lib/main.dart

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,17 @@ void main() {
1111
}
1212

1313
///Defines the main theme color
14-
final MaterialColor themeMaterialColor =
15-
BaseflowPluginExample.createMaterialColor(
16-
const Color.fromRGBO(48, 49, 60, 1));
14+
final MaterialColor themeMaterialColor = BaseflowPluginExample.createMaterialColor(const Color.fromRGBO(48, 49, 60, 1));
1715

1816
/// A Flutter application demonstrating the functionality of this plugin
1917
class PermissionHandlerWidget extends StatefulWidget {
2018
/// Create a page containing the functionality of this plugin
2119
static ExamplePage createPage() {
22-
return ExamplePage(
23-
Icons.location_on, (context) => PermissionHandlerWidget());
20+
return ExamplePage(Icons.location_on, (context) => PermissionHandlerWidget());
2421
}
2522

2623
@override
27-
_PermissionHandlerWidgetState createState() =>
28-
_PermissionHandlerWidgetState();
24+
_PermissionHandlerWidgetState createState() => _PermissionHandlerWidgetState();
2925
}
3026

3127
class _PermissionHandlerWidgetState extends State<PermissionHandlerWidget> {
@@ -64,8 +60,7 @@ class _PermissionState extends State<PermissionWidget> {
6460
_PermissionState(this._permission);
6561

6662
final Permission _permission;
67-
final PermissionHandlerPlatform _permissionHandler =
68-
PermissionHandlerPlatform.instance;
63+
final PermissionHandlerPlatform _permissionHandler = PermissionHandlerPlatform.instance;
6964
PermissionStatus _permissionStatus = PermissionStatus.denied;
7065

7166
@override
@@ -76,8 +71,9 @@ class _PermissionState extends State<PermissionWidget> {
7671
}
7772

7873
void _listenForPermissionStatus() async {
79-
final status = await _permissionHandler.checkPermissionStatus(_permission);
80-
setState(() => _permissionStatus = status);
74+
await _permissionHandler
75+
.checkPermissionStatus(_permission)
76+
.then((status) => setState(() => _permissionStatus = status), onError: (error, st) => print('$error'));
8177
}
8278

8379
Color getPermissionColor() {
@@ -111,8 +107,7 @@ class _PermissionState extends State<PermissionWidget> {
111107
color: Colors.white,
112108
),
113109
onPressed: () {
114-
checkServiceStatus(
115-
context, _permission as PermissionWithService);
110+
checkServiceStatus(context, _permission as PermissionWithService);
116111
})
117112
: null,
118113
onTap: () {
@@ -121,21 +116,19 @@ class _PermissionState extends State<PermissionWidget> {
121116
);
122117
}
123118

124-
void checkServiceStatus(
125-
BuildContext context, PermissionWithService permission) async {
119+
void checkServiceStatus(BuildContext context, PermissionWithService permission) async {
126120
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
127-
content: Text(
128-
(await _permissionHandler.checkServiceStatus(permission)).toString()),
121+
content: Text((await _permissionHandler.checkServiceStatus(permission)).toString()),
129122
));
130123
}
131124

132125
Future<void> requestPermission(Permission permission) async {
133-
final status = await _permissionHandler.requestPermissions([permission]);
134-
135-
setState(() {
136-
print(status);
137-
_permissionStatus = status[permission] ?? PermissionStatus.denied;
138-
print(_permissionStatus);
139-
});
126+
await _permissionHandler.requestPermissions([permission]).then(
127+
(status) => setState(() {
128+
print(status);
129+
_permissionStatus = status[permission] ?? PermissionStatus.denied;
130+
print(_permissionStatus);
131+
}),
132+
onError: (error, st) => print('$error'));
140133
}
141134
}

permission_handler_html/lib/permission_handler_html.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import 'web_delegate.dart';
99

1010
/// Platform implementation of the permission_handler Flutter plugin.
1111
class WebPermissionHandler extends PermissionHandlerPlatform {
12-
static final html.MediaDevices _devices = html.window.navigator.mediaDevices!;
12+
static final html.MediaDevices? _devices = html.window.navigator.mediaDevices;
1313
static final html.Geolocation _geolocation =
1414
html.window.navigator.geolocation;
1515
static final html.Permissions? _htmlPermissions =

permission_handler_html/lib/web_delegate.dart

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class WebDelegate {
3434
static const _notificationsPermissionName = 'notifications';
3535

3636
/// The permission name to request access to the user's location.
37-
static const _locationPermissionName = 'location';
37+
/// https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query#name
38+
static const _locationPermissionName = 'geolocation';
3839

3940
/// The status indicates that permission has been granted by the user.
4041
static const _grantedPermissionStatus = 'granted';
@@ -57,18 +58,18 @@ class WebDelegate {
5758
}
5859
}
5960

60-
Future<PermissionStatus> _permissionStatusState(
61-
String webPermissionName, html.Permissions? permissions) async {
62-
final webPermissionStatus =
63-
await permissions?.query({'name': webPermissionName});
61+
Future<PermissionStatus> _permissionStatusState(String webPermissionName, html.Permissions? permissions) async {
62+
final webPermissionStatus = await permissions?.query({'name': webPermissionName});
6463
return _toPermissionStatus(webPermissionStatus?.state);
6564
}
6665

67-
Future<bool> _requestMicrophonePermission(html.MediaDevices devices) async {
68-
html.MediaStream? mediaStream;
66+
Future<bool> _requestMicrophonePermission() async {
67+
if (_devices == null) {
68+
return false;
69+
}
6970

7071
try {
71-
mediaStream = await devices.getUserMedia({'audio': true});
72+
html.MediaStream mediaStream = await _devices!.getUserMedia({'audio': true});
7273

7374
// In browsers, calling [getUserMedia] will start the recording
7475
// automatically right after. This is undesired behavior as
@@ -77,7 +78,7 @@ class WebDelegate {
7778
// The manual stop action is then needed here for to stop the automatic
7879
// recording.
7980

80-
if (mediaStream.active!) {
81+
if (mediaStream.active ?? false) {
8182
final audioTracks = mediaStream.getAudioTracks();
8283
if (audioTracks.isNotEmpty) {
8384
audioTracks[0].stop();
@@ -90,11 +91,13 @@ class WebDelegate {
9091
return true;
9192
}
9293

93-
Future<bool> _requestCameraPermission(html.MediaDevices devices) async {
94-
html.MediaStream? mediaStream;
94+
Future<bool> _requestCameraPermission() async {
95+
if (_devices == null) {
96+
return false;
97+
}
9598

9699
try {
97-
mediaStream = await devices.getUserMedia({'video': true});
100+
html.MediaStream mediaStream = await _devices!.getUserMedia({'video': true});
98101

99102
// In browsers, calling [getUserMedia] will start the recording
100103
// automatically right after. This is undesired behavior as
@@ -103,7 +106,7 @@ class WebDelegate {
103106
// The manual stop action is then needed here for to stop the automatic
104107
// recording.
105108

106-
if (mediaStream.active!) {
109+
if (mediaStream.active ?? false) {
107110
final videoTracks = mediaStream.getVideoTracks();
108111
if (videoTracks.isNotEmpty) {
109112
videoTracks[0].stop();
@@ -117,45 +120,25 @@ class WebDelegate {
117120
}
118121

119122
Future<bool> _requestNotificationPermission() async {
120-
bool granted = false;
121-
html.Notification.requestPermission().then((permission) => {
122-
if (permission == "granted") {granted = true}
123-
});
124-
125-
return granted;
123+
return html.Notification.requestPermission().then((permission) => permission == "granted");
126124
}
127125

128-
Future<bool> _requestLocationPermission(html.Geolocation geolocation) async {
126+
Future<bool> _requestLocationPermission() async {
129127
try {
130-
await geolocation.getCurrentPosition();
131-
return true;
128+
return await _geolocation?.getCurrentPosition().then((value) => true) ?? false;
132129
} on html.PositionError {
133130
return false;
134131
}
135132
}
136133

137-
Future<PermissionStatus> _requestSingularPermission(
138-
Permission permission) async {
139-
bool permissionGranted = false;
140-
141-
switch (permission) {
142-
case Permission.microphone:
143-
permissionGranted = await _requestMicrophonePermission(_devices!);
144-
break;
145-
case Permission.camera:
146-
permissionGranted = await _requestCameraPermission(_devices!);
147-
break;
148-
case Permission.notification:
149-
permissionGranted = await _requestNotificationPermission();
150-
break;
151-
case Permission.location:
152-
permissionGranted = await _requestLocationPermission(_geolocation!);
153-
break;
154-
default:
155-
throw UnsupportedError(
156-
'The ${permission.toString()} permission is currently not supported on web.',
157-
);
158-
}
134+
Future<PermissionStatus> _requestSingularPermission(Permission permission) async {
135+
bool permissionGranted = switch (permission) {
136+
Permission.microphone => await _requestMicrophonePermission(),
137+
Permission.camera => await _requestCameraPermission(),
138+
Permission.notification => await _requestNotificationPermission(),
139+
Permission.location => await _requestLocationPermission(),
140+
_ => throw UnsupportedError('The ${permission.toString()} permission is currently not supported on web.')
141+
};
159142

160143
if (!permissionGranted) {
161144
return PermissionStatus.permanentlyDenied;
@@ -167,14 +150,12 @@ class WebDelegate {
167150
/// they have not already been granted before.
168151
///
169152
/// Returns a [Map] containing the status per requested [Permission].
170-
Future<Map<Permission, PermissionStatus>> requestPermissions(
171-
List<Permission> permissions) async {
153+
Future<Map<Permission, PermissionStatus>> requestPermissions(List<Permission> permissions) async {
172154
final Map<Permission, PermissionStatus> permissionStatusMap = {};
173155

174156
for (final permission in permissions) {
175157
try {
176-
permissionStatusMap[permission] =
177-
await _requestSingularPermission(permission);
158+
permissionStatusMap[permission] = await _requestSingularPermission(permission);
178159
} on UnimplementedError {
179160
rethrow;
180161
}

permission_handler_html/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: permission_handler_html
22
description: Permission plugin for Flutter. This plugin provides the web API to request and check permissions.
3-
version: 0.1.0+1
3+
version: 0.1.1
44
homepage: https://github.com/baseflow/flutter-permission-handler
55

66
environment:

0 commit comments

Comments
 (0)