annotate cagou/core/platform_/android.py @ 457:ec11a35dcf14

platform (android): open_url now tries to open the right activity for any URL: media type is guessed (by Python standard mimetypes lib then Android API) to try to open the right intent, before defaulting to generic open_url.
author Goffi <goffi@goffi.org>
date Wed, 01 Apr 2020 23:59:00 +0200
parents 85fc3da9560c
children 3c9ba4a694ef
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
378
4d660b252487 dates update
Goffi <goffi@goffi.org>
parents: 377
diff changeset
4 # Copyright (C) 2016-2020 Jérôme Poisson (goffi@goffi.org)
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import sys
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
20 import os
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
21 import socket
380
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
22 import json
377
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
23 from functools import partial
380
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
24 from urllib.parse import urlparse
381
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
25 from pathlib import Path
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
26 import shutil
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
27 import mimetypes
457
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
28 from jnius import autoclass, cast, JavaException
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from android import activity
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
30 from android.permissions import request_permissions, Permission
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
31 from kivy.clock import Clock
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
32 from kivy.uix.label import Label
377
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
33 from sat.core.i18n import _
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 from sat.core import log as logging
401
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
35 from sat.tools.common import data_format
380
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
36 from sat_frontends.tools import jid
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 from cagou.core.constants import Const as C
377
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
38 from cagou.core import dialog
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 from cagou import G
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
40 from .base import Platform as BasePlatform
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
42
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 log = logging.getLogger(__name__)
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
45 # permission that are necessary to have Cagou running properly
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
46 PERMISSION_MANDATORY = [
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
47 Permission.READ_EXTERNAL_STORAGE,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
48 Permission.WRITE_EXTERNAL_STORAGE,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
49 ]
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
50
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 service = autoclass('org.salutatoi.cagou.ServiceBackend')
357
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
52 PythonActivity = autoclass('org.kivy.android.PythonActivity')
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
53 mActivity = PythonActivity.mActivity
345
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
54 Intent = autoclass('android.content.Intent')
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
55 AndroidString = autoclass('java.lang.String')
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
56 Uri = autoclass('android.net.Uri')
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 ImagesMedia = autoclass('android.provider.MediaStore$Images$Media')
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 AudioMedia = autoclass('android.provider.MediaStore$Audio$Media')
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 VideoMedia = autoclass('android.provider.MediaStore$Video$Media')
457
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
60 URLConnection = autoclass('java.net.URLConnection')
345
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
61
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
62 DISPLAY_NAME = '_display_name'
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 DATA = '_data'
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
64
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
65
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 STATE_RUNNING = b"running"
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 STATE_PAUSED = b"paused"
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 STATE_STOPPED = b"stopped"
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 SOCKET_DIR = "/data/data/org.salutatoi.cagou/"
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 SOCKET_FILE = ".socket"
380
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
71 INTENT_EXTRA_ACTION = AndroidString("org.salut-a-toi.IntentAction")
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
72
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
73
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
74 class Platform(BasePlatform):
413
c466678c57b2 chat: control send button visibility in core.platform_, and show it when there are attachments
Goffi <goffi@goffi.org>
parents: 403
diff changeset
75 send_button_visible = True
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
76
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
77 def __init__(self):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
78 super().__init__()
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
79 # cache for callbacks to run when profile is plugged
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
80 self.cache = []
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
81
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
82 def init_platform(self):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
83 # sys.platform is "linux" on android by default
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
84 # so we change it to allow backend to detect android
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
85 sys.platform = "android"
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
86 C.PLUGIN_EXT = 'pyc'
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
87
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
88 def on_host_init(self, host):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
89 argument = ''
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
90 service.start(mActivity, argument)
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
91
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
92 activity.bind(on_new_intent=self.on_new_intent)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
93 self.cache.append((self.on_new_intent, mActivity.getIntent()))
401
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
94 self.last_selected_wid = None
403
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
95 self.restore_selected_wid = True
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
96 host.addListener('profilePlugged', self.onProfilePlugged)
401
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
97 host.addListener('selected', self.onSelectedWidget)
381
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
98 local_dir = Path(host.getConfig('', 'local_dir')).resolve()
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
99 self.tmp_dir = local_dir / 'tmp'
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
100 # we assert to avoid disaster if `/ 'tmp'` is removed by mistake on the line
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
101 # above
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
102 assert self.tmp_dir.resolve() != local_dir
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
103 # we reset tmp dir on each run, to be sure that there is no residual file
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
104 if self.tmp_dir.exists():
eb3f622d8791 android: create/clean a temporary directory on startup:
Goffi <goffi@goffi.org>
parents: 380
diff changeset
105 shutil.rmtree(self.tmp_dir)
398
a5457241c17f android: fixed tmp dir creation if parents don't exist, avoiding a crash.
Goffi <goffi@goffi.org>
parents: 382
diff changeset
106 self.tmp_dir.mkdir(0o700, parents=True)
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
107
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
108 def on_initFrontendState(self):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
109 # XXX: we use a separated socket instead of bridge because if we
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
110 # try to call a bridge method in on_pause method, the call data
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
111 # is not written before the actual pause
370
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
112 s = self._frontend_status_socket = socket.socket(
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
113 socket.AF_UNIX, socket.SOCK_STREAM)
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
114 s.connect(os.path.join(SOCKET_DIR, SOCKET_FILE))
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
115 s.sendall(STATE_RUNNING)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
116
370
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
117 def profileAutoconnectGetCb(self, profile=None):
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
118 if profile is not None:
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
119 G.host.options.profile = profile
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
120 G.host.postInit()
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
121
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
122 def profileAutoconnectGetEb(self, failure_):
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
123 log.error(f"Error while getting profile to autoconnect: {failure_}")
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
124 G.host.postInit()
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
125
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
126 def _show_perm_warning(self, permissions):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
127 root_wid = G.host.app.root
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
128 perm_warning = Label(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
129 size_hint=(1, 1),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
130 text_size=(root_wid.width, root_wid.height),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
131 font_size='22sp',
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
132 bold=True,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
133 color=(0.67, 0, 0, 1),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
134 halign='center',
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
135 valign='center',
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
136 text=_(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
137 "Requested permissions are mandatory to run Cagou, if you don't "
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
138 "accept them, Cagou can't run properly. Please accept following "
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
139 "permissions, or set them in Android settings for Cagou:\n"
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
140 "{permissions}\n\nCagou will be closed in 20 s").format(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
141 permissions='\n'.join(p.split('.')[-1] for p in permissions)))
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
142 root_wid.clear_widgets()
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
143 root_wid.add_widget(perm_warning)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
144 Clock.schedule_once(lambda *args: G.host.app.stop(), 20)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
145
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
146 def permission_cb(self, permissions, grant_results):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
147 if not all(grant_results):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
148 # we keep asking until they are accepted, as we can't run properly
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
149 # without them
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
150 # TODO: a message explaining why permission is needed should be printed
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
151 # TODO: the storage permission is mainly used to set download_dir, we should
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
152 # be able to run Cagou without it.
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
153 if not hasattr(self, 'perms_counter'):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
154 self.perms_counter = 0
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
155 self.perms_counter += 1
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
156 if self.perms_counter > 5:
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
157 Clock.schedule_once(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
158 lambda *args: self._show_perm_warning(permissions),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
159 0)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
160 return
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
161
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
162 perm_dict = dict(zip(permissions, grant_results))
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
163 log.warning(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
164 f"not all mandatory permissions are granted, requesting again: "
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
165 f"{perm_dict}")
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
166 request_permissions(PERMISSION_MANDATORY, callback=self.permission_cb)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
167 return
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
168
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
169 Clock.schedule_once(lambda *args: G.host.bridge.profileAutoconnectGet(
370
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
170 callback=self.profileAutoconnectGetCb,
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
171 errback=self.profileAutoconnectGetEb),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
172 0)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
173
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
174 def do_postInit(self):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
175 request_permissions(PERMISSION_MANDATORY, callback=self.permission_cb)
370
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
176 return False
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
177
401
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
178 def privateDataGetCb(self, data_s, profile):
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
179 data = data_format.deserialise(data_s, type_check=None)
403
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
180 if data is not None and self.restore_selected_wid:
401
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
181 log.debug(f"restoring previous widget {data}")
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
182 try:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
183 name = data['name']
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
184 target = data['target']
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
185 except KeyError as e:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
186 log.error(f"Bad data format for selected widget: {e}\ndata={data}")
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
187 return
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
188 if target:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
189 target = jid.JID(data['target'])
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
190 plugin_info = G.host.getPluginInfo(name=name)
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
191 if plugin_info is None:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
192 log.warning("Can't restore unknown plugin: {name}")
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
193 return
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
194 factory = plugin_info['factory']
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
195 G.host.switchWidget(
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
196 None,
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
197 factory(plugin_info, target=target, profiles=[profile])
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
198 )
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
199
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
200 def onProfilePlugged(self, profile):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
201 log.debug("ANDROID profilePlugged")
370
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
202 G.host.bridge.setParam(
1a12bbd80943 android: autoconnect profile using the new `profileAutoconnectGet` backend method:
Goffi <goffi@goffi.org>
parents: 357
diff changeset
203 "autoconnect_backend", C.BOOL_TRUE, "Connection", -1, profile,
377
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
204 callback=lambda: log.info(f"profile {profile} autoconnection set"),
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
205 errback=lambda: log.error(f"can't set {profile} autoconnection"))
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
206 for method, *args in self.cache:
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
207 method(*args)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
208 del self.cache
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
209 G.host.removeListener("profilePlugged", self.onProfilePlugged)
401
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
210 # we restore the stored widget if any
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
211 # user will then go back to where they was when the frontend was closed
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
212 G.host.bridge.privateDataGet(
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
213 "cagou", "selected_widget", profile,
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
214 callback=partial(self.privateDataGetCb, profile=profile),
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
215 errback=partial(
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
216 G.host.errback,
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
217 title=_("can't get selected widget"),
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
218 message=_("error while retrieving selected widget: {msg}"))
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
219 )
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
220
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
221 def onSelectedWidget(self, wid):
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
222 """Store selected widget in backend, to restore it on next startup"""
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
223 if self.last_selected_wid == None:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
224 self.last_selected_wid = wid
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
225 # we skip the first selected widget, as we'll restore stored one if possible
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
226 return
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
227
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
228 self.last_selected_wid = wid
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
229
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
230 try:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
231 plugin_info = wid.plugin_info
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
232 except AttributeError:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
233 log.warning(f"No plugin info found for {wid}, can't store selected widget")
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
234 return
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
235
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
236 try:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
237 profile = next(iter(wid.profiles))
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
238 except (AttributeError, StopIteration):
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
239 profile = None
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
240
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
241 if profile is None:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
242 try:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
243 profile = next(iter(G.host.profiles))
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
244 except StopIteration:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
245 log.debug("No profile plugged yet, can't store selected widget")
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
246 return
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
247 try:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
248 target = wid.target
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
249 except AttributeError:
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
250 target = None
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
251
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
252 data = {
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
253 "name": plugin_info["name"],
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
254 "target": target,
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
255 }
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
256
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
257 G.host.bridge.privateDataSet(
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
258 "cagou", "selected_widget", data_format.serialise(data), profile,
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
259 errback=partial(
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
260 G.host.errback,
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
261 title=_("can set selected widget"),
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
262 message=_("error while setting selected widget: {msg}"))
788e05d1e2bf android: store and restore last selected widget
Goffi <goffi@goffi.org>
parents: 400
diff changeset
263 )
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
264
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
265 def on_pause(self):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
266 G.host.sync = False
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
267 self._frontend_status_socket.sendall(STATE_PAUSED)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
268 return True
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
269
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
270 def on_resume(self):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
271 self._frontend_status_socket.sendall(STATE_RUNNING)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
272 G.host.sync = True
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
273
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
274 def on_stop(self):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
275 self._frontend_status_socket.sendall(STATE_STOPPED)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
276 self._frontend_status_socket.close()
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
277
357
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
278 def on_key_back_root(self):
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
279 PythonActivity.moveTaskToBack(True)
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
280 return True
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
281
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
282 def on_key_back_share(self, share_widget):
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
283 share_widget.close()
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
284 PythonActivity.moveTaskToBack(True)
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
285 return True
4d3a0c4f2430 core: better back key (ESC) management:
Goffi <goffi@goffi.org>
parents: 345
diff changeset
286
377
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
287 def _disconnect(self, profile):
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
288 G.host.bridge.setParam(
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
289 "autoconnect_backend", C.BOOL_FALSE, "Connection", -1, profile,
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
290 callback=lambda: log.info(f"profile {profile} autoconnection unset"),
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
291 errback=lambda: log.error(f"can't unset {profile} autoconnection"))
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
292 G.host.profiles.unplug(profile)
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
293 G.host.bridge.disconnect(profile)
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
294 G.host.app.showProfileManager()
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
295 G.host.closeUI()
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
296
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
297 def _on_disconnect(self):
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
298 current_profile = next(iter(G.host.profiles))
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
299 wid = dialog.ConfirmDialog(
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
300 title=_("Are you sure to disconnect?"),
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
301 message=_(
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
302 "If you disconnect the current user ({profile}), you won't receive "
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
303 "any notification until you connect it again, is this really what you "
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
304 "want?").format(profile=current_profile),
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
305 yes_cb=partial(self._disconnect, profile=current_profile),
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
306 no_cb=G.host.closeUI,
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
307 )
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
308 G.host.showExtraUI(wid)
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
309
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
310 def on_extra_menu_init(self, extra_menu):
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
311 extra_menu.addItem(_('disconnect'), self._on_disconnect)
b2a87239af25 android: platform specific menu to disconnect profile:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
312
372
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
313 def updateParamsExtra(self, extra):
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
314 # on Android, we handle autoconnection automatically,
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
315 # user must not modify those parameters
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
316 extra.update(
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
317 {
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
318 "ignore": [
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
319 ["Connection", "autoconnect_backend"],
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
320 ["Connection", "autoconnect"],
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
321 ["Connection", "autodisconnect"],
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
322 ],
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
323 }
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
324 )
1481f09c9175 settings (android): don't expose autoconnect parameters:
Goffi <goffi@goffi.org>
parents: 370
diff changeset
325
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
326 def getColDataFromUri(self, uri, col_name):
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
327 cursor = mActivity.getContentResolver().query(uri, None, None, None, None)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
328 if cursor is None:
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
329 return None
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
330 try:
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
331 cursor.moveToFirst()
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
332 col_idx = cursor.getColumnIndex(col_name);
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
333 if col_idx == -1:
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
334 return None
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
335 return cursor.getString(col_idx)
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
336 finally:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
337 cursor.close()
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
338
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
339 def getFilenameFromUri(self, uri, media_type):
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
340 filename = self.getColDataFromUri(uri, DISPLAY_NAME)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
341 if filename is None:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
342 uri_p = Path(uri.toString())
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
343 filename = uri_p.name or "unnamed"
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
344 if not uri_p.suffix and media_type:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
345 suffix = mimetypes.guess_extension(media_type, strict=False)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
346 if suffix:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
347 filename = filename + suffix
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
348 return filename
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
349
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
350 def getPathFromUri(self, uri):
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
351 # FIXME: using DATA is not recommended (and DATA is deprecated)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
352 # we should read directly the file with
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
353 # ContentResolver#openFileDescriptor(Uri, String)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
354 path = self.getColDataFromUri(uri, DATA)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
355 return uri.getPath() if path is None else path
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
356
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
357 def on_new_intent(self, intent):
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
358 log.debug("on_new_intent")
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
359 action = intent.getAction();
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
360 intent_type = intent.getType();
380
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
361 if action == Intent.ACTION_MAIN:
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
362 action_str = intent.getStringExtra(INTENT_EXTRA_ACTION)
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
363 if action_str is not None:
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
364 action = json.loads(action_str)
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
365 log.debug(f"Extra action found: {action}")
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
366 action_type = action.get('type')
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
367 if action_type == "open":
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
368 try:
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
369 widget = action['widget']
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
370 target = action['target']
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
371 except KeyError as e:
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
372 log.warning(f"incomplete action {action}: {e}")
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
373 else:
403
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
374 # we don't want stored selected widget to be displayed after this
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
375 # one
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
376 log.debug("cancelling restoration of previous widget")
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
377 self.restore_selected_wid = False
b0af45a92055 android: do not restore previously selected widget if an intent contains a widget to create.
Goffi <goffi@goffi.org>
parents: 401
diff changeset
378 # and now we open the widget linked to the intent
380
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
379 current_profile = next(iter(G.host.profiles))
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
380 Clock.schedule_once(
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
381 lambda *args: G.host.doAction(
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
382 widget, jid.JID(target), [current_profile]),
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
383 0)
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
384 else:
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
385 log.warning(f"unexpected action: {action}")
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
386
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
387 text = None
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
388 uri = None
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
389 path = None
9d3481663964 android: handle new SàT specific "action" dict which may be attach to an intent:
Goffi <goffi@goffi.org>
parents: 378
diff changeset
390 elif action == Intent.ACTION_SEND:
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
391 # we have receiving data to share, we parse the intent data
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
392 # and show the share widget
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
393 data = {}
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
394 text = intent.getStringExtra(Intent.EXTRA_TEXT)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
395 if text is not None:
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
396 data['text'] = text
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
397
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
398 item = intent.getParcelableExtra(Intent.EXTRA_STREAM)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
399 if item is not None:
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
400 uri = cast('android.net.Uri', item)
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
401 if uri.getScheme() == 'content':
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
402 # Android content, we'll dump it to a temporary file
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
403 filename = self.getFilenameFromUri(uri, intent_type)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
404 filepath = self.tmp_dir / filename
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
405 input_stream = mActivity.getContentResolver().openInputStream(uri)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
406 buff = bytearray(4096)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
407 with open(filepath, 'wb') as f:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
408 while True:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
409 ret = input_stream.read(buff, 0, 4096)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
410 if ret != -1:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
411 f.write(buff[:ret])
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
412 else:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
413 break
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
414 input_stream.close()
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
415 data['path'] = path = str(filepath)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
416 else:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
417 data['uri'] = uri.toString()
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
418 path = self.getPathFromUri(uri)
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
419 if path is not None and path not in data:
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
420 data['path'] = path
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
421 else:
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
422 uri = None
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
423 path = None
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
424
382
c7f1176cd2a9 android: handle Android specific content (wich `content:` scheme) in intent manager:
Goffi <goffi@goffi.org>
parents: 381
diff changeset
425
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
426 Clock.schedule_once(lambda *args: G.host.share(intent_type, data), 0)
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
427 else:
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
428 text = None
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
429 uri = None
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
430 path = None
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
431
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
432 msg = (f"NEW INTENT RECEIVED\n"
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
433 f"type: {intent_type}\n"
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
434 f"action: {action}\n"
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
435 f"text: {text}\n"
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
436 f"uri: {uri}\n"
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
437 f"path: {path}")
322
e2b51663d8b8 core, android: new share widget + added Cagou to "share" menu:
Goffi <goffi@goffi.org>
parents:
diff changeset
438
342
89799148f894 core: use classes and factory to handle platform specific behaviours in a generic way
Goffi <goffi@goffi.org>
parents: 322
diff changeset
439 log.debug(msg)
345
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
440
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
441 def check_plugin_permissions(self, plug_info, callback, errback):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
442 perms = plug_info.get("android_permissons")
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
443 if not perms:
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
444 callback()
427
b51c10cc7325 android: fixed "check_plugin_permissions" when no permission is requested
Goffi <goffi@goffi.org>
parents: 413
diff changeset
445 return
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
446 perms = [f"android.permission.{p}" if '.' not in p else p for p in perms]
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
447
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
448 def request_permissions_cb(permissions, granted):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
449 if all(granted):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
450 Clock.schedule_once(lambda *args: callback())
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
451 else:
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
452 Clock.schedule_once(lambda *args: errback())
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
453
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
454 request_permissions(perms, callback=request_permissions_cb)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 398
diff changeset
455
345
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
456 def open_url(self, url, wid=None):
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
457 parsed_url = urlparse(url)
457
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
458 if parsed_url.scheme == "aesgcm":
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
459 return super().open_url(url, wid)
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
460 else:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
461 media_type = mimetypes.guess_type(url, strict=False)[0]
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
462 if media_type is None:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
463 log.debug(
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
464 f"media_type for {url!r} not found with python mimetypes, trying "
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
465 f"guessContentTypeFromName")
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
466 media_type = URLConnection.guessContentTypeFromName(url)
345
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
467 intent = Intent(Intent.ACTION_VIEW)
457
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
468 if media_type is not None:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
469 log.debug(f"file {url!r} is of type {media_type}")
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
470 intent.setDataAndType(Uri.parse(url), media_type)
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
471 else:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
472 log.debug(f"can't guess media type for {url!r}")
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
473 intent.setData(Uri.parse(url))
345
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
474 if mActivity.getPackageManager() is not None:
a3cefa7158dc android: open "geo:" URL using an Intent
Goffi <goffi@goffi.org>
parents: 342
diff changeset
475 activity = cast('android.app.Activity', mActivity)
457
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
476 try:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
477 activity.startActivity(intent)
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
478 except JavaException as e:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
479 if e.classname != "android.content.ActivityNotFoundException":
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
480 raise e
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
481 log.debug(
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
482 f"activity not found for url {url!r}, we'll try generic opener")
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
483 else:
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
484 return
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
485
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
486 # if nothing else worked, we default to base open_url
ec11a35dcf14 platform (android): open_url now tries to open the right activity for any URL:
Goffi <goffi@goffi.org>
parents: 428
diff changeset
487 super().open_url(url, wid)