Skip to content

Device motion permission#4303

Merged
dmarcos merged 1 commit intoaframevr:masterfrom
KevinEverywhere:device-motion-permission
Nov 19, 2019
Merged

Device motion permission#4303
dmarcos merged 1 commit intoaframevr:masterfrom
KevinEverywhere:device-motion-permission

Conversation

@KevinEverywhere
Copy link
Contributor

@KevinEverywhere KevinEverywhere commented Nov 4, 2019

Description:
iOS 13 introduced new permissions requirements for device motion and orientation. This PR enables iOS 13 Safari users to use device motion.

Changes proposed:

  • A Scene Component addition (device-motion-permission-ui)
  • CSS for screen visible selector to acquire permision
  • Updated package.json file was required to build aframe

Recommended Todo

  • Ensure that iPad 13 browsers also work (only Chrome does now)
  • Always display this graphic for content that requires device motion

The second recommended todo is to proactively give user feedback that their device motion will be part of their experience. Depending on its function, this could have different opacity or color.

package.json Outdated
],
"dependencies": {
"custom-event-polyfill": "^1.0.6",
"custom-event-polyfill": "^1.0.7",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to not touch dependencies. Only upgrade when necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree; and also, if package.json is updated, it will likely require moving forward the aframe version number. That said, if you use a clean machine and git clone the repo, you will find a number of issues with the current package.json file that makes updating pieces of it problematic. Can anyone else verify with a clean machine that package.json is stable? Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis (our CI) machine does that per commit and haven't heard of any issues. Better to revert the package.json file to the original version and address any issues in a seperate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reverted the package.json and resolved all the other issues described. The big remaining question is, do we want to have a temporary or permanent visible icon on the bottom left, the way it is now; or, do we want to have a full screen interrupt, similar to 8thwall or vr-mode-ui when you are in portrait mode, to question device-motion-permission? I believe it is ready to be checked in.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hard work. I would say we want a modal dialog similar to 8thwall or vr-mode-ui. Button is easy to miss and hard to understand what it's for. We can apply and reuse vr-mode-ui style for consistency.


schema: {
enabled: {default: true},
enableFunc: {default:''}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are in flux and are not yet implemented. They may not belong in the final PR on this. I will revisit before resubmitting.

*/
module.exports.Component = registerComponent('device-motion-permission', {

dependencies: ['canvas'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency might not be necessary for this component

@dmarcos
Copy link
Member

dmarcos commented Nov 5, 2019

Thanks for doing this.. So far the code approach looks sensible. I haven't been able to test it on device yet.

KevinEverywhere added a commit to KevinEverywhere/aframe that referenced this pull request Nov 5, 2019
KevinEverywhere added a commit to KevinEverywhere/aframe that referenced this pull request Nov 5, 2019
@KevinEverywhere
Copy link
Contributor Author

Update on this: I found that iPad works for Firefox and Safari: in both cases, the applications had Desktop Version Requested. You either needed to set the preference in your preferences, or select the aA icon in the left of the location for Safari; or the three dots on the right side of Firefox, to Request Mobile Site. That means that what I have done is working across the target browsers on iOS and iPad browsers; I believe that it will also work on Android devices as well (not tested on many). The controller is in the bottom left of the screen to ask permission. For android devices, you will not need to select it.

https://planetkevin.com/aframe/examples/showcase/device-motion-permission/a.html

@KevinEverywhere
Copy link
Contributor Author

The last thing remaining from development perspective is getting past Travis. It is erring out on code that was written before me which I do not believe my code impacts. Is there something I am not understanding on this?

@KevinEverywhere
Copy link
Contributor Author

Matching Travis requirements, pulling out identified linting errors. Last big remaining item, making the modal screen attractive. Currently, Cancel and Continue buttons are functional. My idea: a Built with Aframe logo and wording that tells users that permission is required for device motion. I can continue with this, or if anyone else has an idea of what can be included here graphically, that could also be helpful.

@dmarcos
Copy link
Member

dmarcos commented Nov 11, 2019

Thanks for all the hard work! It's coming along pretty well. I made a few style changes to match linter style, eslint-disable should not be necessary. As mentioned the only remaining work is styling the dialog. I would keep it as unbranded as possible. We can reuse the rotation modal dialog gray background add cancel, accept buttons and some text: This VR site requires access to your sensors. Press accept to allow

Image from iOS


function createDeviceMotionPermissionWindow (onClick, obj) {
var wrapper, innerWrapper, aframeBuilt;
var cancelBtn, continueBtn;
Copy link
Member

@dmarcos dmarcos Nov 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do one variable declaration per line and we avoid abbreviations: cancelButton and continueButton

module.exports.Component = registerComponent('device-motion-permission-ui', {
schema: {
enabled: { default: true },
request: {default: {orientationChange:null, deviceOrientation:null}},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be configurable via schema? Do we need to handle deviceOrientation events explicitly or we can just rely on CSS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that was inadvertently left in from something earlier. What is now in place is the single component with the potential for one or both orientation events (device orientation and orientation change). The example on my site has two simple functions attached through the attributes, orientation-change and device-orientation. The drawback that I have on their usage at this point is that they use the window object to reference the functions. I'll hopefully get this done tomorrow with your edits. Thanks for your attention.

https://planetkevin.com/aframe/examples/showcase/device-motion-permission/a.html

@KevinEverywhere
Copy link
Contributor Author

Just about complete. Has new modal screen; will add clickable to it later today (November 14th)

this.onDeviceMotionClick = bind(this.onDeviceMotionClick, this);
this.onOrientationChangeClick = bind(this.onOrientationChangeClick, this);
this.grantedDeviceMotion = bind(this.grantedDeviceMotion, this);
if (typeof window.orientation !== 'undefined') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if statement can be simplified to:

if (DeviceOrientationEvent && DeviceOrientationEvent.requestPermission) {
      this.deviceMotionEl = createDeviceMotionPermissionDialog(this.onDeviceMotionClick, this);
      this.el.appendChild(this.deviceMotionEl);
}

See suggested edits

Copy link
Contributor Author

@KevinEverywhere KevinEverywhere Nov 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reasons for the structure here follow. I have tried these in different browsers and devices, including multiple iOS versions. There are other ways to do this, but going too simple or too complex will lead to similar outcomes. Thoughts?

iOS13

  • DeviceOrientationEvent.requestPermission needs to be called, not only tested to exist;

iOS and Android

  • grantedDeviceMotion is called by mobile devices (window.orientation)

Desktop Browsers

  • Do not call grantedDeviceMotion

Copy link
Member

@dmarcos dmarcos Nov 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeviceOrientationEvent.requestPermission is already called when the user clicks on the allow button in the onDeviceMotionClick method

Do we need to call it twice?

lf think if DeviceOrientationEvent.requestPermission is not available we don't need to call any additional methods or initialize the dialog. Everything should work as before. iOS 12 requires user to enable DeviceMotion manually in settings, iOS < 12 will work as it used to.

@dmarcos
Copy link
Member

dmarcos commented Nov 14, 2019

Great job! Thanks for sticking with it. I made a few change suggestions. This is getting really close.

@KevinEverywhere
Copy link
Contributor Author

Just pushed latest updates; with comments and most all critiques included.

@subelsky
Copy link
Contributor

thanks @KevinEverywhere! FYI I tested out your demo on Android 9 Chrome browser (& also on iOS 13 Safari), works well!

@dmarcos
Copy link
Member

dmarcos commented Nov 15, 2019

Thanks a lot everybody for the hard work and the testing. I adjusted a bit the code style to the rest of A-Frame, removed some redundant logic and tweaked the visual style of the modal dialog. I tested on iOS 13.2 on iPhone X and Chrome m78 on a Pixel 3 with Android 10. I don't have an iPad handy at the moment to test with. If you can let me know if it works and what you think about the dialog it'll be appreciated. The PR is almost ready. We only need docs for the device-motion-permission-ui component and some basic test coverage.

dialog

@KevinEverywhere
Copy link
Contributor Author

@dmarcos , will you want me to complete this: the readme, for instance. Also, I had one last test that is not included here. iPad OS 13 defaults to Request Desktop Website. A person with an iPad would not know that this fails without having feedback. my solution is below. I tested on a number of devices and operating systems, desktop and mobile. This took over 40 hours of time to resolve something that kept aframe content from being functional on iOS/iPad 13 devices. Thanks.

isMobile: function() {
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
},
grantedDeviceMotion: function () {
if (!this.isMobile()) {
alert('You appear to have a mobile device, but you may have requested a Desktop Website. Check the location bar of your browser and ensure you are requesting the Mobile Website.');
} else {
...
}

The other place this would be used is after the window.orientation check:

  // This is for desktop browsers and those who cancel or reject
  if( this.isMobile() ){
    alert('You appear to have a mobile device, but you may have requested a Desktop Website. Check the location bar of your browser and ensure you are requesting the Mobile Website.');
  } else {
    this.remove();
  }

@dmarcos
Copy link
Member

dmarcos commented Nov 18, 2019

Adding iPad to isMobile function I think will result in tablets entering stereo cardboard mode vs. full screen that I don't think we want. Mobile devices requesting desktop websites make things messier than they were 😄 Trying to find the simpler set of conditions that also preserve previous functionality while also avoiding isMobile duplicated logic. I'll get a hold of an iPad with iOS 13 later in the day and test the PR. Thanks for the help.

@subelsky
Copy link
Contributor

@dmarcos am grabbing my iPad now and cloning the PR to test

@KevinEverywhere
Copy link
Contributor Author

@subelsky and @dmarcos; if anyone can post the output file for testing, that would be great. If either you or anyone else can compare what already is up at the URL below to work on all target browser/devices; I think that the cardboard/fullscreen worry will be mooted. Also, you can test your iPhone against this. Currently, if your iPhone is set to Desktop Website Requested, you do not have feedback to let you know. What I have is reverse compatible and covers iOS/iPad and Android.

https://planetkevin.com/aframe/examples/showcase/device-motion-permission/b.html

@subelsky
Copy link
Contributor

subelsky commented Nov 18, 2019

@KevinEverywhere here's what I did:

HOST=0.0.0.0 npm run dev
ngrok http 9000

that gave me an SSL URL like https://xxxx446f.ngrok.io/ which I visited on the iPad. Still testing

@subelsky
Copy link
Contributor

attached is the build file which I produced via: npm run build:
aframe.js.gz

hope that helps! this feature is going to be awesome for a couple of projects, PSYCHED

@dmarcos
Copy link
Member

dmarcos commented Nov 18, 2019

I changed the mobile device requesting desktop site condition to what @KevinEverywhere suggested and It works on an iPhone X with iOS 13 when requesting a desktop site. Also works on Android m78 / Pixel 3 / Android 10 when requesting mobile and desktop sites. All looks good. I'm going to write some tests and docs and I'll merge later in the day. We can adjust edge cases later if needed. Thanks all for your help.

@KevinEverywhere
Copy link
Contributor Author

KevinEverywhere commented Nov 18, 2019

Looks great, @dmarcos; checked it on iPad Pro with iPad 13 installed with Mobile and Desktop Website Request and it worked as expected on both. The build from 71009c4 is the aframe-aframe.js file used here:

https://planetkevin.com/aframe/examples/showcase/device-motion-permission/c.html

@dmarcos dmarcos force-pushed the device-motion-permission branch 5 times, most recently from 5549a62 to 0aa50be Compare November 19, 2019 03:54
…ents.

Co-authored-by: Kevin Ready <kevin.ready@gmail.com>
Co-authored-by: Diego Marcos <diego.marcos@gmail.com>
@dmarcos dmarcos force-pushed the device-motion-permission branch from 0aa50be to 540b7e1 Compare November 19, 2019 03:55
@dmarcos
Copy link
Member

dmarcos commented Nov 19, 2019

Documented and tested! Shipping 🚢 Thanks everybody for the hard work.

@Dirk-27
Copy link

Dirk-27 commented Nov 21, 2019

@dmarcos : Is this feature coming with 0.9.3 on 6th december?

@dmarcos
Copy link
Member

dmarcos commented Nov 21, 2019

Yes but you can use it today via master builds: https://cdn.jsdelivr.net/gh/aframevr/aframe@934b8d358a2c458efdc8d65fcb6946f7303f0b51/dist/aframe-master.min.js

Let us know if you have any issues

@tommensink
Copy link

tommensink commented Nov 23, 2019

Works very well! Is there any chance this will be included in Aframe 0.8.2? Since the breaking change of a-animation in V0.9.2 my code does not work in that version, and I see no real possiblity to upgrade it in the near future. I suspect a lot of people will stay with 0.8.2 for the coming months/years because of this breaking chance

@dmarcos
Copy link
Member

dmarcos commented Nov 23, 2019

@tommensink Unfortunately, We don’t patch previous releases. It’s not sustainable to maintain multiple versions. Can you elaborate on the breaking change that it’s preventing to upgrade to 0.9.2? a-animation got replaced by the animation component but the API is the same. It should be easy to upgrade. I recommend testing master now in anticipation of 0.9.3. Browsers are deprecating WebVR in favor of WebXR and outdated experiences will stop working in VR mode.

@tommensink
Copy link

tommensink commented Nov 23, 2019

Thanks, and I understand. It is just that I use a-animation a lot and would not know where to begin to replace it in my code, since I use a nested structure with some sort of animation sequencer that I made. You can see it in https://hh-webar.firebaseapp.com/Presentation_2019-01-26/. (Just let the head rotate on your screen to see the different transparancy sequences kicking in).

@tommensink
Copy link

tommensink commented Nov 23, 2019

My personal opinion is that moves from Apple like this motion-issue (which of course also can be understood, but nevertheless) and breaking Aframe changes will throw it back for some years to be adopted by the professional market. I for one will do the major serious AR/VR projects in Unity and use Aframe only for gadgets like dancing business cards

@KevinEverywhere
Copy link
Contributor Author

KevinEverywhere commented Nov 24, 2019 via email

@tommensink
Copy link

tommensink commented Nov 24, 2019

I hope I don't hijack this thread for this discussion too much, but one last thing then: You should hear me about breaking changes in Unity or their horrific tight integration of libraries like Vuforia (who break the API every release). But having said that, I am a full time AR developer, make dozens of apps as lead developer in four AR startups, including one of the first to do actual brain surgery with a HoloLens. So I have to choose the most appropriate and stable Entity Component Framework regularly. Funny moves like this one from Apple (and we had something similar on Android beginning of the year which requires the user to change a setting jeromeetienne/AR.js#369 (comment)) is one reason to choose another platform that will keep running no matter the OS change. An issue like this means that I will judge again in one or two years for Aframe in critical apps, hence my "Aframe is thrown back years" by this. Also if the Aframe community decides they should make breaking changes to the API like a-animation, then this does not work in favour of this decision. Just my opinion, do think the major companies have similar considerations, but cannot speak for them.

The actual main issue here I think is that Apple and Google will never break their normal apps, or they issue warnings in ample time for developers to change their code, yet they make WebXR changes to their browsers without any warning. This is a vicious circle: when AFrame and WebXR become more important, they will be more cautious too. But for this we have to make more apps in AFrame and WebXR.

But I think you guys are awesome, this solution is great Kevin (I applied your first one which works with V0.8.2) and I always support AFrame in discussions and presentations as THE best open platform.

Squareys added a commit to VhiteRabbit/aframe that referenced this pull request Dec 8, 2019
…ation events. (aframevr#4303)"

This reverts commit 2124261.

# Conflicts:
#	docs/components/device-orientation-permission-ui.md
#	src/components/scene/device-orientation-permission-ui.js
Squareys added a commit to VhiteRabbit/aframe that referenced this pull request Dec 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants