kivy / kivy/python-for-android

request_permissions() undocumented side effects

Abierto
#2,309 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug
Lenguaje dominante
Python
Estrellas
8.9k
Forks
2k
Merge medio
12 h 20 min
PR fusionados (30 d)
9

Descripción

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.

  1. If on_pause() returns False, the app immediately stops with no user action
  2. 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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con el ejemplo ejecutable proporcionado y el punto de entrada request_permissions(), y después reprodúcelo usando el buildozer.spec mostrado y el comando buildozer android debug. Rastrea las callbacks del ciclo de vida de Android alrededor de on_start(), on_pause(), on_resume() y la callback de permisos; se considera terminado cuando el comportamiento observado y el uso seguro se hayan corregido o documentado claramente.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
android, python
Área
mobile-dev
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.