borismus / webvr-boilerplate

A starting point for web-based VR experiences that work on all VR headsets.
Apache License 2.0
1.8k stars 451 forks source link

DeviceInfo not detecting iPhone 6S Plus #102

Closed brianchirls closed 8 years ago

brianchirls commented 8 years ago

I'm testing with both an actual iPhone and the iOS Simulator. Everything works fine on the simulator, but not on the real device. The failure to detect is happening in DeviceInfo.prototype.determineIPhone_.

In the simulator, screen.availWidth is 414, which multiplied by dpr of 3 is 1242, which matches the hard-coded iPhone6Plus data. However, on the real iPhone, screen.availWidth is 375, so pixelWidth is 1125 and doesn't match anything.

I don't know why the two devices don't match, but I did find one reference online to someone else who's seen the same value. I've confirmed that both the simulated device and the real one are actually iPhone 6S Plus, which incidentally has the same screen specs as the iPhone 6 Plus (according to Apple's site). I also don't really follow why these values to the specs listed on Apple's site.

Maybe there need to be multiple values per device, or maybe someone who knows more about this can suggest an alternative approach.

pindiespace commented 8 years ago

A good alternative is checking the WebGL version script. iOS puts the name of the hardware chip into the GL string, allowing differentiating different iPhone and iPad models (a true feature test, rather than user-agent sniffing). Unfortunately, Android phones don't seem to help in this way...

I have a draft detector up on my github: https://github.com/pindiespace/webvr-detector/blob/master/src/webvr-detector.js

iOs Detects originally from: https://github.com/uupaa/UserAgent.js/wiki/UserAgent

brianchirls commented 8 years ago

While we're at it, DeviceInfo.prototype.getDistortedFieldOfViewLeftEye throws an error if no device is provided. For Android, there is AVERAGE_ANDROID as a fallback. It may not be a bad idea to have a similar backup for iOS for when future devices are released before someone has time to update this code.

Also, I haven't tested this on iPad, but I imagine it will fail.

brianchirls commented 8 years ago

@pindiespace, that's an interesting idea, though I wouldn't call it a feature test - it's still string sniffing. Seems like it doesn't really help here though, because for iPhone 6S+, it reports A9 which could just as easily be an iPad or a 6S.

pindiespace commented 8 years ago

But the combination of UA sniffing for "ipad" (which is always present) and the GL version allows you to differentiate them.

So, use a combo of searching "iphone", "ipad", "ipod" + GL Version. The only problem is with the iPad 1. It can be ruled out by checking for motion detect (the iPad 2 was the first with accelerometer).

Also, the GL string presumably reflects the actual hardware chip, which was specific to each iOS device. It seems unlikely that it would be overwritten even if the OS is upgraded (unlike the user-agent, which is easily changed).

On Fri, Jan 8, 2016 at 12:26 PM, Brian Chirls notifications@github.com wrote:

@pindiespace https://github.com/pindiespace, that's an interesting idea, though I wouldn't call it a feature test - it's still string sniffing. Seems like it doesn't really help here though, because for iPhone 6S+, it reports A9 which could just as easily be an iPad or a 6S.

— Reply to this email directly or view it on GitHub https://github.com/borismus/webvr-boilerplate/issues/102#issuecomment-170114307 .

Dr. Pete Markiewicz Email: pindiespace@gmail.com Sustainable virtual design blog: http://sustainablevirtualdesign.wordpress.com Sustainability template: http://greenboilerplate.com Teaching site: http://plyojump.com http://www.plyojump.com/ Buy my book! - Millennials and the Popular Culture Lifecourse: http://www.lifecourse.com/store/catalog/lca/mpc.html

brianchirls commented 8 years ago

That sounds pretty complicated, but if it ends up being the only way then I'm for it. However, I'd still love to know why this particular iPhone returns two different values for screen.availWidth and see if that approach can't still work.

There's something to be aware of when making temporary WebGL contexts for feature detection...if you're not gonna use the existing one created by three.js. I ran into these problems with Seriously.js. It's possible (especially if you make too many of them) that you'll run out of GL contexts on the page (I think the limit is 16 in Chrome on OSX, for example), in which case the browser will throw a bit of a fit. At best, the browser will kill one of the contexts so you can create a new one, and that may be the one you're drawing with. So you gotta make sure you share one for all the tests and then prevent default if a "losecontext" event fires.

Here's how I handled it in Seriously.js, which seems pretty reliable.

pindiespace commented 8 years ago

Is there a reason for using undefined instead of null?

I've been using a separate detector is to check for Promise and Fullscreen API support.

On Fri, Jan 8, 2016 at 12:53 PM, Brian Chirls notifications@github.com wrote:

That sounds pretty complicated, but if it ends up being the only way then I'm for it. However, I'd still love to know why this particular iPhone returns two different values for screen.availWidth and see if that approach can't still work.

There's something to be aware of when making temporary WebGL contexts for feature detection...if you're not gonna use the existing one created by three.js. I ran into these problems with Seriously.js. It's possible (especially if you make too many of them) that you'll run out of GL contexts on the page (I think the limit is 16 in Chrome on OSX, for example), in which case the browser will throw a bit of a fit. At best, the browser will kill one of the contexts so you can create a new one, and that may be the one you're drawing with. So you gotta make sure you share one for all the tests and then prevent default if a "losecontext" event fires.

Here's how I handled it https://github.com/brianchirls/Seriously.js/blob/master/seriously.js#L559-L594 in Seriously.js, which seems pretty reliable.

— Reply to this email directly or view it on GitHub https://github.com/borismus/webvr-boilerplate/issues/102#issuecomment-170120996 .

Dr. Pete Markiewicz Email: pindiespace@gmail.com Sustainable virtual design blog: http://sustainablevirtualdesign.wordpress.com Sustainability template: http://greenboilerplate.com Teaching site: http://plyojump.com http://www.plyojump.com/ Buy my book! - Millennials and the Popular Culture Lifecourse: http://www.lifecourse.com/store/catalog/lca/mpc.html

borismus commented 8 years ago

Thanks for flagging this. I don't have a 6S Plus to try on. If it's impossible to detect using the current iOS specific resolution scheme, maybe we consider moving to UA sniffing, but it seems uglier.

Maybe we should have a generic smartphone instead of the Android one. But this is a bad state to be in.

brianchirls commented 8 years ago

Yeah, one of my partners has an 6S+, so I can test it when she's around. I've been digging all over the interwebs and haven't found any other reference to it. I've gone through as many settings as I can find and nothing makes a difference. I'll keep an eye out for anyone who might have another one so I can compare further.

Yes, I think a generic phone as a fallback is necessary. Better to have the distortion be slightly off than to just crash. Maybe we can get that going first? And then if I or anyone else discovers WTF is up with the 6S+, we can add that model specifically.

Also, I looked into the UA, and it doesn't seem to indicate the exact model of iPhone, so I think that's a bust.

brianchirls commented 8 years ago

@borismus I figured it out! iPhone 6 (S)? (Plus)? has this thing called Display Zoom that changes the reported screen dimensions. This has been tricky to debug, since the xcode simulator doesn't have this feature at all. It's only on the real phones.

Since there's no way to predict or detect whether this feature is enabled, we need to have a second instance of both the 6 and 6+. Screen resolutions are listed here: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

brianchirls commented 8 years ago

This doesn't appear to account for the 20 pixel differential observed in #105, so we'll have to keep digging on that one.

brianchirls commented 8 years ago

According to the iPhone resolution guide, iPhone 6 with display zoom will have exactly the same pixel dimensions as iPhone 5. So the only way to tell the difference will be to do as @pindiespace suggests and check for the different GPU chipsets: A8 for iPhone 6/6S, SGX543 or A7 for iPhone 5/5c/5s.

pindiespace commented 8 years ago

Are there any other APIs that spit out the equivalent of a vendor string tied to hardware (e.g. media or audio synth api)?

On Wed, Jan 20, 2016 at 1:28 PM, Brian Chirls notifications@github.com wrote:

According to the iPhone resolution guide http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions, iPhone 6 with display zoom will have exactly the same pixel dimensions as iPhone 5. So the only way to tell the difference will be to do as @pindiespace https://github.com/pindiespace suggests and check for the different GPU chipsets: A8 for iPhone 6/6S, SGX543 or A7 for iPhone 5/5c/5s.

— Reply to this email directly or view it on GitHub https://github.com/borismus/webvr-boilerplate/issues/102#issuecomment-173364502 .

Dr. Pete Markiewicz Email: pindiespace@gmail.com Sustainable virtual design blog: http://sustainablevirtualdesign.wordpress.com Sustainability template: http://greenboilerplate.com Teaching site: http://plyojump.com http://www.plyojump.com/ Buy my book! - Millennials and the Popular Culture Lifecourse: http://www.lifecourse.com/store/catalog/lca/mpc.html

brianchirls commented 8 years ago

@pindiespace I honestly don't think so, but maybe poke around here: https://www.browserleaks.com/

brianchirls commented 8 years ago

Okay, I tested this on iPhone 6S+ with Display Zoom and can confirm that #103 does not fix this issue. The new code does avoid the thrown error, but the distortion/alignment is wrong, so the 3D doesn't work.

btco commented 8 years ago

Hey brian, could you please visit this page using the device and post the output?

http://goo.gl/OMe7mW

brianchirls commented 8 years ago

@btco: Sure thing.

Here's the output from the real iPhone 6S+ with Display Zoom turned on:

UA: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13D15 Safari/601.1
computed resolution: 2001 x 1125
screen.width: 375
screen.height: 667
screen.availWidth: 375
screen.availHeight: 667
window.devicePixelRatio: 3

For comparison, here's the output from the comparable model iPhone on the xcode simulator, with no Display Zoom:

UA: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H141 Safari/600.1.4
computed resolution: 2208 x 1242
screen.width: 414
screen.height: 736
screen.availWidth: 414
screen.availHeight: 736
window.devicePixelRatio: 3
btco commented 8 years ago

Cool! Thanks! Could you please add this device definition to src/dpdb-cache.js in your working copy and see if that fixes the distortion? (Remember to call make after you do that so the JS gets recompiled).

{
    "type": "ios",
    "rules": [ { "res": [ 1125, 2001 ] } ],
    "dpi": [ 410.9, 415.4 ],
    "bw": 4,
    "ac": 1000
},

(add this to src/dpdb-cache.js, at the end of the "devices" list).

brianchirls commented 8 years ago

@btco: I'll check in the morning when I get access to that phone again. I'm still not sure what we're gonna do about the iPhone 6 w/ display zoom looking like the iPhone 5.

Also, @petersgrandadventure reported in the webvr Slack that it's not recognizing the Samsung Galaxy S6 edge+. Details below:

UA: Mozilla/5.0 (Linux; Android 5.1.1; SM-G928T Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.15 Mobile Safari/537.36 
computed resolution: 2562 x 1442 
screen.width: 412 
screen.height: 732 
screen.availWidth: 412 
screen.availHeight: 732 
window.devicePixelRatio: 3.5

Is there a place for requesting updates to dpdb somewhere?

brianchirls commented 8 years ago

@btco Yup, that matched the iPhone and fixed the problem.

btco commented 8 years ago

Ok! I'm including that in the DPDB then. Thanks for testing!

As for your other question about where to request dpdb updates: we're still figuring it out. I'll update README.md with instructions once we establish a process.

btco commented 8 years ago

DPDB updated.

borismus commented 8 years ago

@brianchirls Please reopen if you're still seeing this.

brianchirls commented 8 years ago

My colleague with the iPhone just walked out, but I have no reason to believe this would have been fixed. Will check for sure tomorrow.

devasur commented 8 years ago

{ "type": "ios", "rules": [ { "res": [ 1125, 2001 ] } ], "dpi": [ 410.9, 415.4 ], "bw": 4, "ac": 1000 }

is not part of /webvr-polyfill/build/webvr-polyfill.js here. Was there any reason why it was omitted. I just got an ugly looking screenshot from an iPhone 6S+ with wplit screen line almost at +80% mark.

Screen Param Test returned

UA: Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13F69 Safari/601.1 computed resolution: 2208 x 1242 screen.width: 414 screen.height: 736 screen.availWidth: 414 screen.availHeight: 736 window.devicePixelRatio: 3

devasur commented 8 years ago

@btco could you please take a look @ #146