plugin android: attach an action dict to notification:

instead of calling plyer's generic notify, AndroidNotification is now inherited to add a
SàT specific behaviour: a "sat_action" dictionary is now attached, to indicate to the
frontend what to do when the notification is opened.
This commit is contained in:
Goffi 2020-02-03 13:49:45 +01:00
commit 120289f08f

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python3
# SAT plugin for file tansfer
# Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
@ -20,6 +19,7 @@
import sys
import os
import os.path
import json
from pathlib import Path
from sat.core.i18n import _, D_
from sat.core.constants import Const as C
@ -49,10 +49,23 @@ if sys.platform != "android":
raise exceptions.CancelError("this module is not needed on this platform")
from plyer import notification, vibrator
from plyer import vibrator
from plyer.platforms.android import activity
from plyer.platforms.android.notification import AndroidNotification
from jnius import autoclass
from android.broadcast import BroadcastReceiver
from android import python_act
Context = autoclass('android.content.Context')
ConnectivityManager = autoclass('android.net.ConnectivityManager')
MediaPlayer = autoclass('android.media.MediaPlayer')
AudioManager = autoclass('android.media.AudioManager')
# notifications
AndroidString = autoclass('java.lang.String')
PendingIntent = autoclass('android.app.PendingIntent')
Intent = autoclass('android.content.Intent')
#: delay between a pause event and sending the inactive indication to server, in seconds
#: we don't send the indication immediately because user can be just checking something
@ -84,12 +97,70 @@ NET_TYPE_NONE = "no network"
NET_TYPE_WIFI = "wifi"
NET_TYPE_MOBILE = "mobile"
NET_TYPE_OTHER = "other"
INTENT_EXTRA_ACTION = AndroidString("org.salut-a-toi.IntentAction")
Context = autoclass('android.content.Context')
ConnectivityManager = autoclass('android.net.ConnectivityManager')
MediaPlayer = autoclass('android.media.MediaPlayer')
AudioManager = autoclass('android.media.AudioManager')
class Notification(AndroidNotification):
# We extend plyer's AndroidNotification instead of creating directly with jnius
# because it already handles issues like backward compatibility, and we just want to
# slightly modify the behaviour.
@staticmethod
def _set_open_behavior(notification, sat_action):
# we reproduce plyer's AndroidNotification._set_open_behavior
# bu we add SàT specific extra action data
app_context = activity.getApplication().getApplicationContext()
notification_intent = Intent(app_context, python_act)
notification_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
notification_intent.setAction(Intent.ACTION_MAIN)
notification_intent.addCategory(Intent.CATEGORY_LAUNCHER)
if sat_action is not None:
action_data = AndroidString(json.dumps(sat_action).encode())
log.debug(f"adding extra {INTENT_EXTRA_ACTION} ==> {action_data}")
notification_intent = notification_intent.putExtra(
INTENT_EXTRA_ACTION, action_data)
# we use PendingIntent.FLAG_UPDATE_CURRENT here, otherwise extra won't be set
# in the new intent (the old ACTION_MAIN intent will be reused). This differs
# from plyers original behaviour which set no flag here
pending_intent = PendingIntent.getActivity(
app_context, 0, notification_intent, PendingIntent.FLAG_UPDATE_CURRENT
)
notification.setContentIntent(pending_intent)
notification.setAutoCancel(True)
def _notify(self, **kwargs):
# we reproduce plyer's AndroidNotification._notify behaviour here
# and we add handling of "sat_action" attribute (SàT specific).
# we also set, where suitable, default values to empty string instead of
# original None, as a string is expected (in plyer the empty string is used
# in the generic "notify" method).
sat_action = kwargs.pop("sat_action", None)
noti = None
message = kwargs.get('message', '').encode('utf-8')
ticker = kwargs.get('ticker', '').encode('utf-8')
title = AndroidString(
kwargs.get('title', '').encode('utf-8')
)
icon = kwargs.get('app_icon', '')
if kwargs.get('toast', False):
self._toast(message)
return
else:
noti = self._build_notification(title)
noti.setContentTitle(title)
noti.setContentText(AndroidString(message))
noti.setTicker(AndroidString(ticker))
self._set_icons(noti, icon=icon)
self._set_open_behavior(noti, sat_action)
self._open_notification(noti)
class FrontendStateProtocol(protocol.Protocol):
@ -252,9 +323,19 @@ class AndroidPlugin(object):
try:
subject = next(iter(mess_data["subject"].values()))
except StopIteration:
subject = "Cagou new message"
subject = D_("new message from {contact}").format(
contact = mess_data['from'])
notification.notify(title=subject, message=message)
notification = Notification()
notification._notify(
title=subject,
message=message,
sat_action={
"type": "open",
"widget": "chat",
"target": mess_data["from"].userhost(),
},
)
ringer_mode = self.am.getRingerMode()
vibrate_mode = ringer_mode == AudioManager.RINGER_MODE_VIBRATE