Skip to content

Commit

Permalink
fix: Notifications not being delivered
Browse files Browse the repository at this point in the history
Some notifications were not delivered since the main activity was not
alive listening to the broadcast signal. The worker now creates the
notifications once the polling has concluded so they are never missed.
  • Loading branch information
LeanderBB committed Aug 5, 2024
1 parent b7ecd3c commit 88d429a
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 67 deletions.
4 changes: 4 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/35.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Fixed

* Some notifications not being delivered
* Do not cancel work on startup if no change has been made to poll interval
4 changes: 2 additions & 2 deletions you-have-mail-android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ android {
applicationId "dev.lbeernaert.youhavemail"
minSdk 29
targetSdk 33
versionCode 34
versionName "0.16.2"
versionCode 35
versionName "0.16.3"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import androidx.work.hasKeyWithValueOfType
import dev.lbeernaert.youhavemail.Event
import dev.lbeernaert.youhavemail.Yhm
import dev.lbeernaert.youhavemail.YhmException
import dev.lbeernaert.youhavemail.initLog
import java.util.concurrent.TimeUnit

private const val TAG = "PollWorker"
Expand Down Expand Up @@ -86,8 +88,44 @@ private fun poll(context: Context) {
var error: String? = null
try {
yhm.poll()
try {
val events = yhm.lastEvents()
for (event in events) {
when (event) {
is Event.Email -> {
for (email in event.emails) {
NOTIFICATION_STATE.onNewEmail(
context,
event.email,
event.backend,
email.sender,
email.subject
)
}
}

is Event.Error -> {
NOTIFICATION_STATE.onError(context, event.v1, event.v2)
}

is Event.LoggedOut -> {
NOTIFICATION_STATE.onLoggedOut(
context,
event.v1,
)
}

is Event.Offline -> {
// Do nothing.
}
}
}
} catch (e: Exception) {
createServiceErrorNotification(context, "Failed to retrieve events: $e")
}
} catch (e: YhmException) {
error = e.toString()
createServiceErrorNotification(context, error)
} finally {
yhm.close()
}
Expand All @@ -110,6 +148,7 @@ private fun constraints(): Constraints {
}

fun registerWorker(ctx: Context, minutes: Long, cancel: Boolean) {
initLog(getLogPath(ctx).path);
val inputData = Data.Builder().putLong("INTERVAL", minutes).build()
val constraints = constraints()
val wm = WorkManager.getInstance(ctx)
Expand All @@ -130,7 +169,7 @@ fun registerWorker(ctx: Context, minutes: Long, cancel: Boolean) {
wm
.enqueueUniquePeriodicWork(
POLL_WORKER_JOB_NAME,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
ExistingPeriodicWorkPolicy.KEEP,
work
)
} else {
Expand All @@ -142,7 +181,7 @@ fun registerWorker(ctx: Context, minutes: Long, cancel: Boolean) {

wm.enqueueUniqueWork(
POLL_WORKER_JOB_NAME,
ExistingWorkPolicy.REPLACE,
ExistingWorkPolicy.KEEP,
work
)
}
Expand All @@ -158,5 +197,5 @@ fun oneshotWorker(ctx: Context) {
.build()

val wm = WorkManager.getInstance(ctx)
wm.enqueueUniqueWork(ONE_SHOT_WORKER_JOB_NAME, ExistingWorkPolicy.REPLACE, work)
wm.enqueueUniqueWork(ONE_SHOT_WORKER_JOB_NAME, ExistingWorkPolicy.KEEP, work)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ class ObserverServiceState {

const val STATE_LOG_TAG = "state"

// Has to be global singleton for now so that the ids are accessible for the worker
// and the system. Could be moved to a shared preferences setup for persistent
// changes.
var NOTIFICATION_STATE = NotificationState()

class State(context: Context) : BroadcastReceiver() {
private var mPollInterval = MutableStateFlow(15UL)
private var mYhm: Yhm
private var mAccounts: MutableStateFlow<List<Account>>
private var mOpenAccount: MutableStateFlow<Account?> = MutableStateFlow(null)
private var mNotificationState = NotificationState()
var mLoginSequence: LoginSequence? = null

init {
Expand All @@ -53,7 +57,7 @@ class State(context: Context) : BroadcastReceiver() {
mAccounts = MutableStateFlow(mYhm.accounts())
val pollInterval = mYhm.pollInterval()
mPollInterval.value = pollInterval
registerWorker(context, pollInterval.toLong() / 60, true)
registerWorker(context, pollInterval.toLong() / 60, false)

val filter = IntentFilter()
filter.addAction(POLL_INTENT)
Expand Down Expand Up @@ -205,54 +209,9 @@ class State(context: Context) : BroadcastReceiver() {
when (intent.action) {
POLL_INTENT -> {
Log.d(STATE_LOG_TAG, "Received poll intent")
onPolled(context, intent.getStringExtra(POLL_INTENT))
}
}
}

private fun onPolled(context: Context, errorMsg: String?) {
if (errorMsg != null) {
createServiceErrorNotification(context, errorMsg)
return
}

try {
val events = mYhm.lastEvents()
for (event in events) {
when (event) {
is Event.Email -> {
for (email in event.emails) {
mNotificationState.onNewEmail(
context,
event.email,
event.backend,
email.sender,
email.subject
)
}
}

is Event.Error -> {
mNotificationState.onError(context, event.v1, event.v2)
}

is Event.LoggedOut -> {
mNotificationState.onLoggedOut(
context,
event.v1,
)
}

is Event.Offline -> {
// Do nothing.
}
}
refreshData()
}
} catch (e: Exception) {
createServiceErrorNotification(context, "Failed to retrieve events: $e")
}

refreshData()
}
}

Expand Down
14 changes: 7 additions & 7 deletions you-have-mail-mobile/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion you-have-mail-mobile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "you-have-mail-mobile"
version = "0.12.0"
version = "0.13.0"
edition = "2021"
authors = ["Leander Beernaert <[email protected]>"]
license = "AGPL-3.0-only"
Expand All @@ -14,6 +14,7 @@ name = "youhavemail"
[dependencies]
uniffi = { version = "0.28.0", features = ["cli"] }
you-have-mail-common = { git = "https://github.com/LeanderBB/you-have-mail-common"}
# you-have-mail-common = { path = "../../you-have-mail-common/youhavemail"}
thiserror = "1"
parking_lot = "0.12"
tracing = "0.1"
Expand Down
7 changes: 1 addition & 6 deletions you-have-mail-mobile/src/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn init_log(filepath: String) -> Option<String> {
fn init_log_fn(path: PathBuf) -> Result<(), Box<dyn Error + Send + Sync>> {
let appender = tracing_appender::rolling::never(path, "yhm.log");
let filter = EnvFilter::builder().parse_lossy(
"info,you_have_mail_mobile=debug,you_have_mail_common=debug,http=debug,proton_api=debug",
"info,you_have_mail_common=debug,http=debug,proton_api=debug",
);
tracing_subscriber::FmtSubscriber::builder()
.with_ansi(false)
Expand All @@ -41,11 +41,6 @@ fn yhm_log_info(text: &str) {
tracing::info!("[APP] {text}");
}

#[export]
fn yhm_log_debug(text: &str) {
tracing::debug!("[APP] {text}");
}

#[export]
fn yhm_log_error(text: &str) {
tracing::error!("[APP] {text}");
Expand Down

0 comments on commit 88d429a

Please sign in to comment.