Nitification store logging

This commit is contained in:
Milos Kozak 2021-02-20 19:34:19 +01:00
parent a025fc8ece
commit fe3c049999
5 changed files with 42 additions and 62 deletions

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.overview.notifications package info.nightscout.androidaps.plugins.general.overview.notifications
import android.annotation.SuppressLint
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
@ -11,14 +10,10 @@ import android.media.RingtoneManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.MainActivity
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.databinding.OverviewNotificationItemBinding
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -45,8 +40,7 @@ class NotificationStore @Inject constructor(
private val dateUtil: DateUtil private val dateUtil: DateUtil
) { ) {
var store: MutableList<Notification> = ArrayList() private var store: MutableList<Notification> = ArrayList()
private var usesChannels = false
companion object { companion object {
@ -71,33 +65,35 @@ class NotificationStore @Inject constructor(
} }
} }
store.add(n) store.add(n)
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction) { if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction)
raiseSystemNotification(n) raiseSystemNotification(n)
if (usesChannels && n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
} else {
if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId) if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId)
}
Collections.sort(store, NotificationComparator()) Collections.sort(store, NotificationComparator())
return true return true
} }
@Synchronized fun remove(id: Int): Boolean { @Synchronized
fun remove(id: Int): Boolean {
for (i in store.indices) { for (i in store.indices) {
if (store[i].id == id) { if (store[i].id == id) {
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context) if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context)
store.removeAt(i) store.removeAt(i)
aapsLogger.debug(LTag.NOTIFICATION, "Notification removed: " + store[i].text)
return true return true
} }
} }
return false return false
} }
@Synchronized private fun removeExpired() { @Synchronized
private fun removeExpired() {
var i = 0 var i = 0
while (i < store.size) { while (i < store.size) {
val n = store[i] val n = store[i]
if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) { if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) {
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context)
store.removeAt(i) store.removeAt(i)
aapsLogger.debug(LTag.NOTIFICATION, "Notification expired: " + store[i].text)
i-- i--
} }
i++ i++
@ -135,20 +131,17 @@ class NotificationStore @Inject constructor(
} }
fun createNotificationChannel() { fun createNotificationChannel() {
usesChannels = true
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
@SuppressLint("WrongConstant") val channel = NotificationChannel(CHANNEL_ID, val channel = NotificationChannel(CHANNEL_ID, CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH)
CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH)
mNotificationManager.createNotificationChannel(channel) mNotificationManager.createNotificationChannel(channel)
} }
@Synchronized @Synchronized
fun updateNotifications(notificationsView: RecyclerView) { fun updateNotifications(notificationsView: RecyclerView) {
removeExpired() removeExpired()
// unSnooze() val clonedStore = ArrayList(store)
if (store.size > 0) { if (clonedStore.isNotEmpty()) {
val adapter = NotificationRecyclerViewAdapter(cloneStore()) val adapter = NotificationRecyclerViewAdapter(clonedStore)
notificationsView.adapter = adapter notificationsView.adapter = adapter
notificationsView.visibility = View.VISIBLE notificationsView.visibility = View.VISIBLE
} else { } else {
@ -156,33 +149,24 @@ class NotificationStore @Inject constructor(
} }
} }
@Synchronized
private fun cloneStore(): List<Notification> {
val clone: MutableList<Notification> = ArrayList(store.size)
clone.addAll(store)
return clone
}
inner class NotificationRecyclerViewAdapter internal constructor(private val notificationsList: List<Notification>) : RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder>() { inner class NotificationRecyclerViewAdapter internal constructor(private val notificationsList: List<Notification>) : RecyclerView.Adapter<NotificationRecyclerViewAdapter.NotificationsViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NotificationsViewHolder { override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NotificationsViewHolder =
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.overview_notification_item, viewGroup, false) NotificationsViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.overview_notification_item, viewGroup, false))
return NotificationsViewHolder(v)
}
override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) { override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) {
val notification = notificationsList[position] val notification = notificationsList[position]
holder.dismiss.tag = notification holder.binding.dismiss.tag = notification
if (notification.buttonText != 0) holder.dismiss.setText(notification.buttonText) if (notification.buttonText != 0) holder.binding.dismiss.setText(notification.buttonText)
else holder.dismiss.setText(R.string.snooze) else holder.binding.dismiss.setText(R.string.snooze)
@Suppress("SetTextI18n") @Suppress("SetTextI18n")
holder.text.text = dateUtil.timeString(notification.date) + " " + notification.text holder.binding.text.text = dateUtil.timeString(notification.date) + " " + notification.text
when (notification.level) { when (notification.level) {
Notification.URGENT -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent)) Notification.URGENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
Notification.NORMAL -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal)) Notification.NORMAL -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
Notification.LOW -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow)) Notification.LOW -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
Notification.INFO -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo)) Notification.INFO -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
Notification.ANNOUNCEMENT -> holder.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement)) Notification.ANNOUNCEMENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement))
} }
} }
@ -192,12 +176,10 @@ class NotificationStore @Inject constructor(
inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var cv: CardView = itemView.findViewById(R.id.notification_cardview) val binding = OverviewNotificationItemBinding.bind(itemView)
var text: TextView = itemView.findViewById(R.id.notification_text)
var dismiss: Button = itemView.findViewById(R.id.notification_dismiss)
init { init {
dismiss.setOnClickListener { binding.dismiss.setOnClickListener {
val notification = it.tag as Notification val notification = it.tag as Notification
rxBus.send(EventDismissNotification(notification.id)) rxBus.send(EventDismissNotification(notification.id))
notification.action?.run() notification.action?.run()

View file

@ -4,9 +4,7 @@ import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder import android.os.IBinder
import androidx.annotation.RequiresApi
import info.nightscout.androidaps.interfaces.NotificationHolderInterface import info.nightscout.androidaps.interfaces.NotificationHolderInterface
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -14,14 +12,13 @@ import javax.inject.Singleton
/* /*
This code replaces following This code replaces following
val alarm = Intent(context, DummyService::class.java) val alarm = Intent(context, DummyService::class.java)
alarm.putExtra("soundid", n.soundId) alarm.putExtra("soundId", n.soundId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
it fails randomly with error it fails randomly with error
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.DummyService} Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.DummyService}
*/ */
@RequiresApi(Build.VERSION_CODES.O)
@Singleton @Singleton
class DummyServiceHelper @Inject constructor( class DummyServiceHelper @Inject constructor(
private val notificationHolder: NotificationHolderInterface private val notificationHolder: NotificationHolderInterface

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/notification_cardview" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cv"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -16,16 +17,17 @@
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:id="@+id/notification_text" android:id="@+id/text"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:layout_weight="1" android:layout_weight="1"
android:maxLines="4" android:maxLines="4"
android:text="Notification text. Notification text. Notification text. Notification text. Notification text. Notification text. " /> android:text="Notification text. Notification text. Notification text. Notification text. Notification text. Notification text. "
tools:ignore="HardcodedText" />
<Button <Button
android:id="@+id/notification_dismiss" android:id="@+id/dismiss"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="35dp" android:layout_height="35dp"
android:text="@string/dismiss" /> android:text="@string/dismiss" />

View file

@ -4,31 +4,32 @@ import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder import android.os.IBinder
import androidx.annotation.RequiresApi
import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.interfaces.NotificationHolderInterface import info.nightscout.androidaps.interfaces.NotificationHolderInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
/* /*
This code replaces following This code replaces following
val alarm = Intent(context, AlarmSoundService::class.java) val alarm = Intent(context, AlarmSoundService::class.java)
alarm.putExtra("soundid", n.soundId) alarm.putExtra("soundId", n.soundId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(alarm) else context.startService(alarm)
it fails randomly with error it fails randomly with error
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.AlarmSoundService} Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e317f7e u0 info.nightscout.nsclient/info.nightscout.androidaps.services.AlarmSoundService}
*/ */
@RequiresApi(Build.VERSION_CODES.O)
@Singleton @Singleton
class AlarmSoundServiceHelper @Inject constructor( class AlarmSoundServiceHelper @Inject constructor(
private val aapsLogger: AAPSLogger,
private val notificationHolder: NotificationHolderInterface private val notificationHolder: NotificationHolderInterface
) { ) {
fun startAlarm(context: Context, sound: Int) { fun startAlarm(context: Context, sound: Int) {
aapsLogger.debug(LTag.CORE, "Starting alarm")
val connection = object : ServiceConnection { val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// The binder of the service that returns the instance that is created. // The binder of the service that returns the instance that is created.
@ -62,6 +63,7 @@ class AlarmSoundServiceHelper @Inject constructor(
} }
fun stopService(context: Context) { fun stopService(context: Context) {
aapsLogger.debug(LTag.CORE, "Stopping alarm")
val alarm = Intent(context, AlarmSoundService::class.java) val alarm = Intent(context, AlarmSoundService::class.java)
context.stopService(alarm) context.stopService(alarm)
} }

View file

@ -2,12 +2,10 @@ package info.nightscout.androidaps.utils.protection
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.EditText import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes import androidx.annotation.StringRes
import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.utils.CryptoUtil import info.nightscout.androidaps.utils.CryptoUtil
@ -20,7 +18,6 @@ import javax.inject.Singleton
// since androidx.autofill.HintConstants are not available // since androidx.autofill.HintConstants are not available
const val AUTOFILL_HINT_NEW_PASSWORD = "newPassword" const val AUTOFILL_HINT_NEW_PASSWORD = "newPassword"
@RequiresApi(Build.VERSION_CODES.O)
@Singleton @Singleton
class PasswordCheck @Inject constructor( class PasswordCheck @Inject constructor(
val sp: SP, val sp: SP,