plugin android: sound notification + change settings:

- new notification sound
- vibration and notification sound are now activated depending on ringer mode (normal,
  vibrate or silent)
- notification sound/vibration can be configured in settings.
This commit is contained in:
Goffi 2020-01-03 13:21:27 +01:00
commit 2555649dfb

View file

@ -20,15 +20,15 @@
import sys
import os
import os.path
import tempfile
from pathlib import Path
from sat.core.i18n import _, D_
from sat.core.constants import Const as C
from sat.core.log import getLogger
from sat.core import exceptions
from sat.memory import params
from twisted.internet import reactor
from twisted.internet import protocol
from twisted.internet import error as int_error
from twisted.web import client as web_client
log = getLogger(__name__)
@ -58,9 +58,21 @@ from android.broadcast import BroadcastReceiver
#: quickly on an other app.
CSI_DELAY = 30
PARAM_RING_CATEGORY = "Notifications"
PARAM_RING_NAME = "sound"
PARAM_RING_LABEL = D_("sound on notifications")
RING_OPTS = {
"normal": D_("Normal"),
"never": D_("Never"),
}
PARAM_VIBRATE_CATEGORY = "Notifications"
PARAM_VIBRATE_NAME = "vibrate"
PARAM_VIBRATE_LABEL = D_("Vibrate on notifications")
VIBRATION_OPTS = {
"always": D_("Always"),
"vibrate": D_("In vibrate mode"),
"never": D_("Never"),
}
SOCKET_DIR = "/data/data/org.salutatoi.cagou/"
SOCKET_FILE = ".socket"
STATE_RUNNING = b"running"
@ -75,38 +87,8 @@ NET_TYPE_OTHER = "other"
Context = autoclass('android.content.Context')
ConnectivityManager = autoclass('android.net.ConnectivityManager')
def determineLength_workaround(self, fObj):
"""Method working around seek() bug on Android"""
try:
seek = fObj.seek
tell = fObj.tell
except AttributeError:
return web_client.UNKNOWN_LENGTH
originalPosition = tell()
seek(os.SEEK_END)
end = tell()
seek(os.SEEK_SET, originalPosition)
return end - originalPosition
def patch_seek_bug():
"""Check seek bug and apply a workaround if still here
cf. https://github.com/kivy/python-for-android/issues/1768
"""
with tempfile.TemporaryFile() as f:
f.write(b'1234567890')
f.seek(0, os.SEEK_END)
size = f.tell()
if size == 10:
log.info("seek() bug not present anymore, workaround code can be removed")
else:
log.warning("seek() bug detected, applying a workaround")
web_client.FileBodyProducer._determineLength = determineLength_workaround
patch_seek_bug()
MediaPlayer = autoclass('android.media.MediaPlayer')
AudioManager = autoclass('android.media.AudioManager')
class FrontendStateProtocol(protocol.Protocol):
@ -137,15 +119,24 @@ class AndroidPlugin(object):
<params>
<individual>
<category name="{category_name}" label="{category_label}">
<param name="{param_name}" label="{param_label}" value="true" type="bool" security="0" />
<param name="{ring_param_name}" label="{ring_param_label}" type="list" security="0">
{ring_options}
</param>
<param name="{vibrate_param_name}" label="{vibrate_param_label}" type="list" security="0">
{vibrate_options}
</param>
</category>
</individual>
</params>
""".format(
category_name=PARAM_VIBRATE_CATEGORY,
category_label=D_(PARAM_VIBRATE_CATEGORY),
param_name=PARAM_VIBRATE_NAME,
param_label=PARAM_VIBRATE_LABEL,
vibrate_param_name=PARAM_VIBRATE_NAME,
vibrate_param_label=PARAM_VIBRATE_LABEL,
vibrate_options=params.makeOptions(VIBRATION_OPTS, "always"),
ring_param_name=PARAM_RING_NAME,
ring_param_label=PARAM_RING_LABEL,
ring_options=params.makeOptions(RING_OPTS, "normal"),
)
def __init__(self, host):
@ -178,6 +169,18 @@ class AndroidPlugin(object):
# plugins have done their job
host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=-1000)
# audio manager, to get ring status
self.am = activity.getSystemService(Context.AUDIO_SERVICE)
# sound notification
media_dir = Path(host.memory.getConfig("", "media_dir"))
assert media_dir is not None
notif_path = media_dir / "sounds" / "notifications" / "music-box.mp3"
self.notif_player = MediaPlayer()
self.notif_player.setDataSource(str(notif_path))
self.notif_player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION)
self.notif_player.prepare()
# Connectivity handling
self.cm = activity.getSystemService(Context.CONNECTIVITY_SERVICE)
self._net_type = None
@ -240,13 +243,30 @@ class AndroidPlugin(object):
subject = "Cagou new message"
notification.notify(title=subject, message=message)
if self.host.memory.getParamA(
PARAM_VIBRATE_NAME, PARAM_VIBRATE_CATEGORY, profile_key=client.profile
):
try:
vibrator.vibrate()
except Exception as e:
log.warning("Can't use vibrator: {e}".format(e=e))
ringer_mode = self.am.getRingerMode()
vibrate_mode = ringer_mode == AudioManager.RINGER_MODE_VIBRATE
ring_setting = self.host.memory.getParamA(
PARAM_RING_NAME,
PARAM_RING_CATEGORY,
profile_key=client.profile
)
if ring_setting != 'never' and ringer_mode == AudioManager.RINGER_MODE_NORMAL:
self.notif_player.start()
vibration_setting = self.host.memory.getParamA(
PARAM_VIBRATE_NAME,
PARAM_VIBRATE_CATEGORY,
profile_key=client.profile
)
if (vibration_setting == 'always'
or vibration_setting == 'vibrate' and vibrate_mode):
try:
vibrator.vibrate()
except Exception as e:
log.warning("Can't use vibrator: {e}".format(e=e))
return mess_data
def messageReceivedTrigger(self, client, message_elt, post_treat):