Bug 203287 - Gyroscope (DeviceMotion related) permission cannot be requested in WKWebView unless the client app sets a WKUIDelegate
Summary: Gyroscope (DeviceMotion related) permission cannot be requested in WKWebView ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit API (show other bugs)
Version: WebKit Local Build
Hardware: iPhone / iPad iOS 13
: P2 Major
Assignee: Chris Dumez
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-10-23 00:12 PDT by Mario González
Modified: 2020-06-22 10:14 PDT (History)
8 users (show)

See Also:


Attachments
Patch (2.66 KB, patch)
2019-12-09 13:39 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (10.97 KB, patch)
2019-12-09 19:58 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (11.04 KB, patch)
2019-12-10 08:22 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (12.16 KB, patch)
2019-12-10 10:42 PST, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mario González 2019-10-23 00:12:27 PDT
As per API, a permission should be requested appropriatelly on the site for the user to grant/deny access to the devicemotion info.

We have implemented this OK in our code and Safari works fine, but not when using a WebView embedded in an iOS app. This of course is the intented use and has unfortunatelly broken our build.

I did see this other post, but it seems it was closed assuming the API call was not implemented: https://bugs.webkit.org/show_bug.cgi?id=201676

Since in our case it's now a proven fact that even though we have implemented the call and the user gesture/action (swipe or button click), we are still not being requested for he permission and hence the webview fails to obtain the device data.

Please look into this, as this might be something relatively easy to fix and can then secure a better outcome for so many dependant projects.

Thanks in advance for any support. MG.
Comment 1 Chris Dumez 2019-10-23 08:43:41 PDT
The requestPermission() API is only exposed in MobileSafari, not WKWebView. The reason is not exposed in WKWebView is because you do not need to request permission there, you have directly access to the device orientation & motion. If DeviceOrientation.requestPermission is not defined, then you can listen for orientation events right away.

I have just verified in WKWebView using a device orientation API demo site that the site indeed has access to the device orientation / motion without requesting permission.
Comment 2 Mario González 2019-10-23 19:52:17 PDT
Hi Chris, thank for the reply.

Before we added the DeviceOrientation.requestPermission, it stopped working directly after the iOS 13 update, which states that the permissions should be requested.

If this is then not applicable to WKWebKit, I would like to explore the following:

1)What site did you use to test the events? We could run it from our WKWebView to ensure this is not a WKWebView implementation gap from our end.

If we are unsucesfull with 1), we can then explore:

2)We could expose our project (which requires gyroscope) to you for testing in the same enviornment you setup for your previous validation.

Hopefully we can replicate or further explore this before closing it as invalid. Determining the specific conditions we are working with in both scenarios can give further clarity of how to achieve sucessfull implementation for any other WKWebKit usage in other forums where people are also having this problem.

Thanks again in advance for the prompt reply, have a great day.

MG
Comment 4 Chris Dumez 2019-10-23 20:13:04 PDT
(In reply to Chris Dumez from comment #3)
> For e.g. this works fine in a WKWebView:
> https://googlesamples.github.io/web-fundamentals/fundamentals/native-
> hardware/device-orientation/dev-orientation.html

Also:
https://www.audero.it/demo/device-orientation-api-demo.html

I used the “WebView” app on the App Store to test.
Comment 5 Chris Dumez 2019-10-23 20:24:28 PDT
Maybe you are serving content over HTTP? I think also changed behavior in iOS 13 to require a secure context (file protocol, https or loopback), no HTTP. Note that if you connect to your WebView via Web Inspector, you would see JS logging and it would hopefully tell you why it is not working.
Comment 6 Mario González 2019-10-23 21:35:32 PDT
Thanks for the prompt reply!

We are serving through HTTPS, as it is required for the standard of using these events.

The team and I will do tests using these and I will get back with the results.
Comment 7 Mario González 2019-11-01 10:23:47 PDT
Hi everyone, sorry I took some time to get back on this. I need to explain the setup we have and how it is working:

We are doing Flutter projects, to attack both Android & iOS. There is a plugin that works with a webview implementation for Android, and a WkWebview for iOS. This plug in is hosted here: https://pub.dev/packages/webview_flutter

Our app will run HTTPS hosted games, running in the WebView implementations for each OS.

For Android, we noticed no special permissions need to be added to get it working with sensor access. The HTTPS hosted games handle the request to sensors directly. We have ensured anyway to add permissions in our manifest to access gyroscope & accelerometer, for documentaton purposes.

For iOS, we have added a requirement in our Info.plist to give the app access to enable WebViews and we have also stated the app needs device capabilities of gyroscope and accelerometer. We have even made a special call to sensor activities before openening the webview to ensure they are active. From 0 to 100 on the steps above, in any scenario have we gotten it to work.

We are now looking at creating a plugin from scratch just to see if it might be a bad implementation of the plugin specifically for gyroscope and accelerometer access. The original plugin code does not suggest any access to sensors or permissions in iOS, so we will test the implementation specifically here and then get back to see the results.

I will post our progress next week, as I will be out some days.
Comment 8 Mario González 2019-11-13 22:24:11 PST
Hi everyone, some developments.

We have tried implementing WkWebKit on the Flutter app, and so far no luck. We don't have any other devices using iOS lower than 13.0, so we can do back testing to see if this has broken since.

We have downloaded the app you suggested Cris, and it works OK there but my assumption is that it's a native development using w¿either Swift or Objective-C.

So this might be a Flutter related issue and potentially related to the plugin; but so far I can't see any issues open in their GitHub. I migh as well open a thread and star linking to this conversation.

As suggested by https://github.com/solarsu - we will try moving from using WkWebKit in our test plugin to see if we have any other results.

If this approach ends in sucess, then it's definetelly something with WkWebKit and Flutter that is not working.

I will be off for the next week too, but my team will be making progress on the tests and identifing potential issues. I will also link back to the issue I will open in Flutter, to see if the Flutter team and also look at this.

Sincerely,

Mario González
Comment 9 distinctdan 2019-11-14 23:25:23 PST
Hi all, I'm having this issue too with my app. I'm running a tilt-controlled game that runs in a wkwebview using cordova. Cordova serves over the file:// protocol, which from the comments here sounds like it should work. However, I get the error:

No device motion or orientation events will be fired until permission has been requested and granted.

I can request permission, which does work, but it's a terrible user experience for me to have to prompt my users every time they open the app.
Comment 10 Chris Dumez 2019-11-30 13:10:41 PST
(In reply to distinctdan from comment #9)
> Hi all, I'm having this issue too with my app. I'm running a tilt-controlled
> game that runs in a wkwebview using cordova. Cordova serves over the file://
> protocol, which from the comments here sounds like it should work. However,
> I get the error:
> 
> No device motion or orientation events will be fired until permission has
> been requested and granted.
> 
> I can request permission, which does work, but it's a terrible user
> experience for me to have to prompt my users every time they open the app.

If you are seeing a need for permission then you are likely using SafariViewController (SVC), not WKWebView. The need for permission in SVC is intended, for consistency with Safari. Only WKWebView is exempt at the moment.
Comment 11 Mario González 2019-11-30 13:34:00 PST
As teams facing this issue, we have been guided in the internet to request permissions as stated in links like: 

https://medium.com/flawless-app-stories/how-to-request-device-motion-and-orientation-permission-in-ios-13-74fc9d6cd140

However, it is now more clarea Safari VC is one thing and WkWebView is another.

In my case, we are using the flutter plugins and this is where our approach might be failing; we are investigating as this is breaking our main solution for an app and is critical for it to work.

So far other than the WebView app in the AppStore, there is no one else that can sucessfully replicate this without asking for permissions.

Hopefully our reserch ends with some light into why WkWebView is not working unders certain scenarios.
Comment 12 Chris Dumez 2019-12-09 13:39:39 PST
Created attachment 385183 [details]
Patch
Comment 13 Chris Dumez 2019-12-09 13:40:31 PST
Temporary workaround for WKWebView apps is to set a WKUIDelegate on the WKWebView. Sorry about that.
Comment 14 Mario González 2019-12-09 14:00:25 PST
Great, thanks Cris! We will test it out between today and tomorrow and get back. Hopefully it works in the meantime =)
Comment 15 Chris Dumez 2019-12-09 14:02:21 PST
(In reply to Mario González from comment #14)
> Great, thanks Cris! We will test it out between today and tomorrow and get
> back. Hopefully it works in the meantime =)

Credits to Max Musiienko (@xkampotx) on Twitter for pointing this out to me.
Comment 16 Chris Dumez 2019-12-09 19:58:57 PST
Created attachment 385230 [details]
Patch
Comment 17 Chris Dumez 2019-12-10 08:22:36 PST
Created attachment 385264 [details]
Patch
Comment 18 Alex Christensen 2019-12-10 09:52:59 PST
Comment on attachment 385264 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=385264&action=review

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:405
> +    BlockPtr<BOOL ()> _deviceOrientationUserPermissionHandler;

I don't think we should be adding more ivars to WKWebView.  Instead, we should add this to a c++ object like WebPageProxy.
Also, this seems like it's just for testing.  Could it be named to indicate that?
Comment 19 Chris Dumez 2019-12-10 10:42:37 PST
Created attachment 385283 [details]
Patch
Comment 20 Chris Dumez 2019-12-10 11:09:19 PST
(In reply to Alex Christensen from comment #18)
> Comment on attachment 385264 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=385264&action=review
> 
> > Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:405
> > +    BlockPtr<BOOL ()> _deviceOrientationUserPermissionHandler;
> 
> I don't think we should be adding more ivars to WKWebView.  Instead, we
> should add this to a c++ object like WebPageProxy.
> Also, this seems like it's just for testing.  Could it be named to indicate
> that?

Fixed.
Comment 21 WebKit Commit Bot 2019-12-10 13:27:29 PST
Comment on attachment 385283 [details]
Patch

Clearing flags on attachment: 385283

Committed r253343: <https://trac.webkit.org/changeset/253343>
Comment 22 WebKit Commit Bot 2019-12-10 13:27:30 PST
All reviewed patches have been landed.  Closing bug.
Comment 23 Radar WebKit Bug Importer 2019-12-10 13:29:25 PST
<rdar://problem/57806114>
Comment 24 jcesarmobile 2020-06-22 10:14:36 PDT
I'm on iPadOS 13.6 (beta 2 I think, latest at the moment) and I still don't see the permission prompt unless I set a WKUIDelegate, which is not a problem for me because I need the WKUIDelegate delegate anyway, but the shown prompt has a few issues like not showing usage description, not showing app name and permission requested every time instead of remembering the user's choice.

Is there some method that needs to be implemented? one of the patches has a shouldAllowDeviceOrientationAndMotionAccess method, but I don't see that in the WKUIDelegate.

Reported the mentioned bugs in:  
https://bugs.webkit.org/show_bug.cgi?id=213467
https://bugs.webkit.org/show_bug.cgi?id=213468
https://bugs.webkit.org/show_bug.cgi?id=213469