annotate cagou/core/platform_/android.py @ 488:beedff600d2b

blog: blog widget implementation: this patch implements a basic blog widget. The search bare can be used to change node (only node for now, will be improved to do search and all). Publication on current node can be done by pressing the pencil icon. A checkbox can be activated to use end-to-end encryption. No pagination or comments are supported for now. Due to lack of HTML rendering in Kivy, only simple formatting is supported. If item is end-2-end encrypted, a green closed locker is shown next to publication date. rel 380
author Goffi <goffi@goffi.org>
date Sat, 15 Oct 2022 20:20:10 +0200
parents 83c67b093350
children 203755bbe0fe
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
461
3c9ba4a694ef dates update
Goffi <goffi@goffi.org>
parents: 457
diff changeset
4 # Copyright (C) 2016-2021 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
462
83c67b093350 android: renamed package from org.salutatoi.cagou to org.libervia.cagou
Goffi <goffi@goffi.org>
parents: 461
diff changeset
51 service = autoclass('org.libervia.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"
462
83c67b093350 android: renamed package from org.salutatoi.cagou to org.libervia.cagou
Goffi <goffi@goffi.org>
parents: 461
diff changeset
69 SOCKET_DIR = "/data/data/org.libervia.cagou/"
322
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)