Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird getMotionAuthorizationStatus() behaviour on iPad #372

Closed
1 of 3 tasks
fcamblor opened this issue Sep 29, 2019 · 14 comments
Closed
1 of 3 tasks

Weird getMotionAuthorizationStatus() behaviour on iPad #372

fcamblor opened this issue Sep 29, 2019 · 14 comments
Labels
bug Something isn't working properly ios relates to iOS platform runtime issue An issue related to app runtime

Comments

@fcamblor
Copy link

I'm submitting a ... (check one with "x"):

  • bug report
  • feature request
  • documentation issue

Bug report

Current behavior:
On iPad Mini 4, when I call getMotionAuthorizationStatus(), I always get a not_requested outcome, even when I call requestMotionAuthorization() prior to it (no matter what I respond to the motion authorization request popup).

eg :

cordova.plugins.diagnostic.getMotionAuthorizationStatus(motionStatus => {
    console.log("fist motion authorization status : "+JSON.stringify(motionStatus));
    cordova.plugins.diagnostic.requestMotionAuthorization(requestedMotionStatus => {
        console.log("first request motion authorization outcome : "+JSON.stringify(requestedMotionStatus));
        cordova.plugins.diagnostic.getMotionAuthorizationStatus(motionStatus2 => {
            console.log("second motion authorization status : "+JSON.stringify(motionStatus2));
            cordova.plugins.diagnostic.requestMotionAuthorization(requestedMotionStatus2 => {
                console.log("second request motion authorization outcome : "+JSON.stringify(requestedMotionStatus2));
			}, console.error);
		}, console.error);
	}, console.error);
}, console.error);

outputs :

[Log] fist motion authorization status : "not_requested" (t.js, line 13)
// Motion authorization request popup opened ... same logs below wether I allow or deny the motion authorization...
[Log] first request motion authorization outcome : "not_determined" (t.js, line 13)
[Log] second motion authorization status : "not_requested" (t.js, line 13)
[Log] second request motion authorization outcome : "not_determined" (t.js, line 13)

Expected behavior:

I understand that iPad motion is half available (we can request it, but since we don't have Pedometer events on iPads, it cannot be determined)

However, I would have expected that a second call (after requestMotionAuthorization() call) to getMotionAuthorizationStatus() would return not_determined instead of not_requested

WDYT about my assumption ?

Current behaviour is annoying because I need to always rely on requestMotionAuthorization() to have a "true" status, since getMotionAuthorizationStatus() doesn't give me the true status on iPad.

Steps to reproduce:

Execute following code :

cordova.plugins.diagnostic.getMotionAuthorizationStatus(motionStatus => {
    console.log("fist motion authorization status : "+JSON.stringify(motionStatus));
    cordova.plugins.diagnostic.requestMotionAuthorization(requestedMotionStatus => {
        console.log("first request motion authorization outcome : "+JSON.stringify(requestedMotionStatus));
        cordova.plugins.diagnostic.getMotionAuthorizationStatus(motionStatus2 => {
            console.log("second motion authorization status : "+JSON.stringify(motionStatus2));
            cordova.plugins.diagnostic.requestMotionAuthorization(requestedMotionStatus2 => {
                console.log("second request motion authorization outcome : "+JSON.stringify(requestedMotionStatus2));
			}, console.error);
		}, console.error);
	}, console.error);
}, console.error);

My assumption would be to have this output :

[Log] fist motion authorization status : "not_requested" (t.js, line 13)
// Motion authorization request popup opened ... same logs below wether I allow or deny the motion authorization...
[Log] first request motion authorization outcome : "not_determined" (t.js, line 13)
[Log] second motion authorization status : "not_determined" (t.js, line 13)
[Log] second request motion authorization outcome : "not_determined" (t.js, line 13)

Environment information

  android 8.1.0
  browser 6.0.0
  ios 5.0.1
Available platforms: 
  electron ^1.0.0
  osx ^5.0.0
  windows ^7.0.0
  • Plugins & versions installed in project (including this plugin)
cordova-android-firebase-gradle-release 4.0.0 "cordova-android-firebase-gradle-release"
cordova-background-geolocation 3.2.2 "BackgroundGeolocation"
cordova-plugin-androidx 1.0.2 "cordova-plugin-androidx"
cordova-plugin-androidx-adapter 1.1.0 "cordova-plugin-androidx-adapter"
cordova-plugin-background-fetch 5.6.0 "CDVBackgroundFetch"
cordova-plugin-cocoalumberjack 0.0.4 "CocoaLumberjack"
cordova-plugin-device 2.0.3 "Device"
cordova-plugin-file 6.0.2 "File"
cordova-plugin-file-transfer 1.7.1 "File Transfer"
cordova-plugin-firebasex 6.1.0 "Google Firebase Plugin"
cordova-plugin-whitelist 1.3.4 "Whitelist"
cordova.plugins.diagnostic 4.0.12 "Diagnostic"
  • Dev machine OS and version, e.g.
ProductVersion: 10.14.5
BuildVersion:   18F203

Runtime issue

  • Device details : IPad Mini 4
  • OS details
    • iOS 10.3.3

Related code:

cordova.plugins.diagnostic.getMotionAuthorizationStatus(motionStatus => {
    console.log("fist motion authorization status : "+JSON.stringify(motionStatus));
    cordova.plugins.diagnostic.requestMotionAuthorization(requestedMotionStatus => {
        console.log("first request motion authorization outcome : "+JSON.stringify(requestedMotionStatus));
        cordova.plugins.diagnostic.getMotionAuthorizationStatus(motionStatus2 => {
            console.log("second motion authorization status : "+JSON.stringify(motionStatus2));
            cordova.plugins.diagnostic.requestMotionAuthorization(requestedMotionStatus2 => {
                console.log("second request motion authorization outcome : "+JSON.stringify(requestedMotionStatus2));
			}, console.error);
		}, console.error);
	}, console.error);
}, console.error);

Kind regards,

@dpa99c dpa99c added bug Something isn't working properly ios relates to iOS platform runtime issue An issue related to app runtime labels Sep 30, 2019
@dpa99c dpa99c closed this as completed in 70a4db6 Sep 30, 2019
@dpa99c
Copy link
Owner

dpa99c commented Sep 30, 2019

This has been fixed in v5.0.1

@fcamblor
Copy link
Author

fcamblor commented Oct 1, 2019

@dpa99c for my knowledge, can you confirm you just disabled availability of motion permission on the iPad mini 4 model device prior to v5.0.1 ?

WARNING : message below is not right as I was testing on an iPad Mini 1 instead of an iPad mini 4 (see #372 (comment))

As I can see changes in behaviour between 4.0.12 and 5.0.1 for the iPad Mini 4 :

Version isMotionRequestOutcomeAvailable() requestMotionAuthorization() behaviour requestMotionAuthorization() outcome getMotionAuthorizationStatus() outcome
v4.0.12 true shows permission popup once always not_determined even when choice has been made in the permission popup always not_requested, even after permission popup being shown
v5.0.1 false nothing always not_available always not_requested

(note that I'm not against this change, but I'm trying to understand the implications of this change here :-) )

@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

I'm testing v5.0.1 on an iPad Air 2 running iOS 12.4 using the example project (by inserting plugin calls directly into the Webview via Safari Web Inspector) and the results I see are this:

  1. cordova.plugins.diagnostic.isMotionRequestOutcomeAvailable(result => console.log(result))
    => false
  2. cordova.plugins.diagnostic.getMotionAuthorizationStatus(result => console.log(result))
    => not_requested
  3. cordova.plugins.diagnostic.requestMotionAuthorization(result => console.log(result))
    => (shows permission dialog)
    => press "OK" or "Don't Allow"
    => not_determined
  4. cordova.plugins.diagnostic.getMotionAuthorizationStatus(result => console.log(result))
    => not_determined

These are the results I would expect.

Can you try the same set of commands on your iPad Mini 4 and see if you get the same results?

@fcamblor
Copy link
Author

fcamblor commented Oct 1, 2019

Hi @dpa99c,

You can see the outcome of those in my table previously.

Anyway, it was not on your sample app, so just in case I tried with your sample app but had exactly the same results as those described in the table above (not permission popup when calling requeastMotionAuthorization()) :
Cordova_diagnostic_issue_on_iPad_Mini_4

@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

The results on your iPad Mini 4 indicate that the CoreMotion APIs are responding differently than to my iPad Air 2.
Unfortunately I don't have a physical iPad running iOS 10 so I can't debug this in Xcode to explain why this is (iOS Simulator doesn't support CoreMotion APIs).

Therefore, if you want to investigate this further, you'll need to debug on the device in Xcode yourself. I suggest setting breakpoints in Diagnostic_Motion.m at line 92, and line 96 when calling requestMotionAuthorization() to see if iOS enters that completion block with no permission popup.

And also at line 51 to check if the motion_permission_requested flag is nil when subsequently calling getMotionAuthorizationStatus().

If you have an iPad running a newer version of iOS, you can repeat the tests to see if the results are different.

@fcamblor
Copy link
Author

fcamblor commented Oct 1, 2019

And also at line 51 to check if the motion_permission_requested flag is nil when subsequently calling getMotionAuthorizationStatus().

Yes, motion_permission_requested is nil
Diagnostic_-_Motion_permission_requested_being_nil

Therefore, if you want to investigate this further, you'll need to debug on the device in Xcode yourself. I suggest setting breakpoints in Diagnostic_Motion.m at line 92, and line 96 when calling requestMotionAuthorization() to see if iOS enters that completion block with no permission popup.

As stated above, isMotionRequestOutcomeAvailable() is returning false
And while in debug, I never stop at lines 92 & 96 because [self isMotionAvailable] statement returns nil

@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

OK, now I see what's going on: CoreMotion is not available on your iPad Mini 4 (there must be no motion co-processor onboard) so isMotionAvailable is false.
Therefore, the motion_permission_requested flag is never set so getMotionAuthorizationStatus always returns not_requested.

I can fix this by adding a check for isMotionAvailable in getMotionAuthorizationStatus and if false then return not_available instead of checking the motion_permission_requested flag.

However, I'd recommend anyway that you call cordova.plugins.diagnostic.isMotionAvailable() before any other motion operations and if this returns false, then omit calls to the other operations since motion tracking is unavailable on the device.

dpa99c pushed a commit that referenced this issue Oct 1, 2019
… available" when calling getMotionAuthorizationStatus(). Further resolves #372.
@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

The above commit should ensure that getMotionAuthorizationStatus returns not_available if activity tracking is not available on the device.

@fcamblor
Copy link
Author

fcamblor commented Oct 1, 2019

Yes, that's what I am (and was) doing.

But I can recall that the change you made on 5.0.1 changed the behaviour.
I do think that there is some Motion permission existing on this device ... prior to 5.0.1, when I was calling requestMotionAuthorization I think it was asking for the motion permission.

I'm not 💯 about that, let me check this again with a previous version of the plugin to be sure of myself :-)

@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

Looking at the iPad Mini 4 specs it does seem it has a motion coprocessor.
But CMMotionActivityManager isActivityAvailable is returning false indicating that activity tracking is unavailable.

@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

Interestingly, looking at the motion coprocessors, you iPad Mini 4 has the A8 whereas my iPad Air (ME913B/A) has the A7 so yours has a new coprocessor, so I wonder why it says activity tracking is unavailable since it's my understanding that it is supported on the A7 and upwards?
Maybe the iOS version 10 vs 12?

@fcamblor
Copy link
Author

fcamblor commented Oct 1, 2019

@dpa99c Apologies, I was just checking and ... I'm testing with an iPad Mini 1 since this morning, not the iPad Mini 4 (they are very close in terms of design)

I'm going to unroll this thread and test everything again with the iPad Mini 4 this time, will keep you posted

I'm really sorry to waste your time :(

@dpa99c
Copy link
Owner

dpa99c commented Oct 1, 2019

aha! iPad Mini 1 does not have a motion coprocessor so that explains why isMotionAvailable is false!

I'm really sorry to waste your time :(

You really haven't wasted my time as you did find an actual bug which is fixed by the commit above!

@fcamblor
Copy link
Author

fcamblor commented Oct 1, 2019

OK, ran the tests and it looks good with a proper iPad Mini 4 : I now have the not_determined status after the requestMotionAuthorization() call (and cannot call requestMotionAuthorization() twice, which is something expected when I have an option to skip this call by checking getMotionAuthorizationStatus() == "not_requested")

Diagnostic_plugin_ok_on_ipad_mini_4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working properly ios relates to iOS platform runtime issue An issue related to app runtime
Projects
None yet
Development

No branches or pull requests

2 participants