request_permissions() undocumented side effects
Checklist
- [x ] the issue is indeed a bug and not a support request
- [x ] issue doesn't already exist: https://github.com/kivy/python-for-android/issues
- [x ] I have a short, runnable example that reproduces the issue
- [x ] I reproduced the problem with the latest development version (
p4a.branch = develop) - [ x] I used the grave accent (aka backticks) to format code or logs when appropriated
Versions
- Python: 3.8
- OS: Android 10
- Kivy: 1.11.1
- Cython: 29
- OpenJDK: 8
Description
Calling request_permissions() from on_start() generates extra on_pause() and on_resume() events.
This can lead to unexpected behavior.
- If on_pause() returns False, the app immediately stops with no user action
- If on_pause() returns True, the app executes the permission callback between an on_pause() and an on_resume(). So on_resume() cannot assume the on_pause() state is its entry state.
The test case:
from kivy.app import App
from kivy.uix.label import Label
from android.permissions import request_permissions,Permission
class MyApp(App):
def build(self):
print('========build')
return Label(text='Greetings Earthlings')
def on_start(self):
print('========start')
# Comment this next call for test A) only
request_permissions([Permission.ACCESS_FINE_LOCATION,
Permission.ACCESS_WIFI_STATE,
Permission.CHANGE_WIFI_STATE],
self.callback)
def callback(self,permissions,grants):
print('========callback')
def on_pause(self):
print('========pause')
# Change to False for test B) only
return True
def on_resume(self):
print('========resume')
def on_stop(self):
# See https://github.com/kivy/python-for-android/issues/2272
print('========stop')
MyApp().run()
Three cases illustrate the issue, at no time is pause initiated by the user:
A) Normal behavior: request_permissions() is commented, stop initiated with the back (<) button:
09-05 16:08:45.475 24087 24119 I python : ========build
09-05 16:08:45.615 24087 24119 I python : ========start
09-05 16:08:48.370 24087 24119 I python : ========stop
B) Case 1) above: request_permissions() is not commented, on_pause() returns False, stop is automatic and instantaneous.
09-05 16:10:43.832 24230 24260 I python : ========build
09-05 16:10:43.958 24230 24260 I python : ========start
09-05 16:10:44.002 24230 24230 I python : ========pause
09-05 16:10:44.030 24230 24260 I python : ========stop
C) Case 2) above request_permissions() is not commented, on_pause() returns True, the callback() can change app state between on_pause() and on_resume(), stop is initiated with the back (<) button.
09-05 16:13:10.734 24344 24376 I python : ========build
09-05 16:13:10.862 24344 24376 I python : ========start
09-05 16:13:10.906 24344 24344 I python : ========pause
09-05 16:13:10.950 24344 24344 I python : ========callback
09-05 16:13:10.953 24344 24344 I python : ========resume
09-05 16:13:15.443 24344 24376 I python : ========stop
Moving request_permissions to build() removes the extra pause/resume but results in variable behavior, which the user must explicitly code for.
First execution, when the dialog appears:
09-05 16:39:59.970 25253 25279 I python : ========build
09-05 16:40:00.155 25253 25279 I python : ========start
09-05 16:40:02.529 25253 25253 I python : ========callback
09-05 16:40:07.814 25253 25279 I python : ========stop
Subsequent executions:
09-05 16:34:27.596 24876 24907 I python : ========build
09-05 16:34:27.690 24876 24876 I python : ========callback
09-05 16:34:27.775 24876 24907 I python : ========start
09-05 16:34:33.171 24876 24907 I python : ========stop
Also anecdotally calling request_permissions outside of a class results in unexpected calls (by Android) at on_resume() and subsequent non-deterministic behavior.
At a minimum the safe usage of request_permissions() is undocumented, and the usage reminds me of a minefield.
A loosely related issue #2272 addresses the inconsistent behavior of on_stop()
buildozer.spec
Command:
buildozer android debug
Spec file:
default buildozer.spec except:
android.permissions = ACCESS_FINE_LOCATION, CHANGE_WIFI_STATE, ACCESS_WIFI_STATE
p4a.branch = develop
Logs
see tests above