From a633da205ebad7192dddfea9d7a14e34d2e01101 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 25 May 2023 14:32:34 +0200 Subject: [PATCH 01/15] update settings.gradle & app/build.gradle to add e UI sdk in dependencies --- app/build.gradle | 2 +- settings.gradle | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 327208025..6ded8fe2a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -84,7 +84,6 @@ android { } dependencies { - // Core implementation 'androidx.core:core-ktx:1.8.0' implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') @@ -99,4 +98,5 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" + implementation 'foundation.e:elib:0.0.1-alpha11' } diff --git a/settings.gradle b/settings.gradle index b2b9aba90..802eaf228 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,6 +13,7 @@ dependencyResolutionManagement { google() mavenCentral() maven { url "https://jitpack.io" } + maven { url 'https://gitlab.e.foundation/api/v4/groups/9/-/packages/maven'} } } rootProject.name = "Etar-Calendar" -- GitLab From 283ebe7a81737fc03cdd6b4ea96337dd3634c652 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 25 May 2023 15:20:04 +0200 Subject: [PATCH 02/15] Update README to provide updated local build instruction --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 5cb2f9356..208ba7f29 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,16 @@ git submodule update --init gradle aarGen gradle :app:assembleDebug ``` + +*Update on May 25th 2023:* + +1. Clone the repository +2. remove "build" dir inside external/calendar, external/chips, external/colorpicker and external/timezonepicker +3. run `git submodule update --init` +4. in `build.gradle` update `minSdk` to 26 or higher, to avoid icon AAR issue +5. Run `./gradlew aarGen` +6. Run `./gradlew :app:assembleDebug` + ## License Copyright (c) 2005-2013, The Android Open Source Project -- GitLab From 52ade789fee7995978317fe3d35463428c5ae154 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 25 May 2023 17:09:27 +0200 Subject: [PATCH 03/15] add a method to check if there is already an active notification for the given event --- .../android/calendar/alerts/AlertService.java | 20 +++++++++++++++++-- .../calendar/alerts/NotificationMgr.java | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index 3a149a870..a613733d8 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -42,6 +42,7 @@ import android.os.Process; import android.provider.CalendarContract; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.CalendarAlerts; +import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; @@ -238,10 +239,13 @@ public class AlertService extends Service { // the notification list. for (int i = 0; i < highPriorityEvents.size(); i++) { NotificationInfo info = highPriorityEvents.get(i); + if (nm.notificationAlreadyExistForEvent(info.eventId)) { continue; } + String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); + postNotification(info, summaryText, context, true, notificationPrefs, nm, - currentNotificationId++); + currentNotificationId++); // Keep concurrent events high priority (to appear higher in the notification list) // until 15 minutes into the event. @@ -921,7 +925,7 @@ public class AlertService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { - + Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent.getExtras(); @@ -966,6 +970,7 @@ public class AlertService extends Service { // Added wrapper for testing public static class NotificationWrapper { + public static final String EXTRA_EVENT_ID = "eventId"; Notification mNotification; long mEventId; long mBegin; @@ -979,6 +984,7 @@ public class AlertService extends Service { mBegin = startMillis; mEnd = endMillis; + mNotification.extras.putLong(EXTRA_EVENT_ID, eventId); // popup? // notification id? } @@ -1018,6 +1024,16 @@ public class AlertService extends Service { public void notify(int id, NotificationWrapper nw) { mNm.notify(id, nw.mNotification); } + + @Override + public boolean notificationAlreadyExistForEvent(long eventId) { + final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); + for(StatusBarNotification statusBarNotif : statusBarNotifs) { + final long notifEventId = statusBarNotif.getNotification().extras.getLong(NotificationWrapper.EXTRA_EVENT_ID, 0L); + if (notifEventId == eventId) return true; + } + return false; + } } static class NotificationInfo { diff --git a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java index 718f20321..71b5d70de 100644 --- a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java +++ b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java @@ -25,6 +25,8 @@ public abstract class NotificationMgr { public abstract void cancel(int id); public abstract void createNotificationChannel(NotificationChannel channel); + public abstract boolean notificationAlreadyExistForEvent(long eventId); + /** * Don't actually use the notification framework's cancelAll since the SyncAdapter * might post notifications and we don't want to affect those. -- GitLab From bea1cf1ea770b28c646198a19a192ac7ecf93bcb Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Fri, 26 May 2023 10:42:39 +0200 Subject: [PATCH 04/15] Check if new notif's content text is same as displayed notif's content text --- .../android/calendar/alerts/AlertService.java | 16 ++++++++++------ .../android/calendar/alerts/NotificationMgr.java | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index a613733d8..97393091e 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -239,11 +239,12 @@ public class AlertService extends Service { // the notification list. for (int i = 0; i < highPriorityEvents.size(); i++) { NotificationInfo info = highPriorityEvents.get(i); - if (nm.notificationAlreadyExistForEvent(info.eventId)) { continue; } - String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, + final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); + if (nm.notificationAlreadyDisplayed(info.eventId, summaryText)) { continue; } + postNotification(info, summaryText, context, true, notificationPrefs, nm, currentNotificationId++); @@ -1026,11 +1027,14 @@ public class AlertService extends Service { } @Override - public boolean notificationAlreadyExistForEvent(long eventId) { + public boolean notificationAlreadyDisplayed(long eventId, String primaryText) { final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); - for(StatusBarNotification statusBarNotif : statusBarNotifs) { - final long notifEventId = statusBarNotif.getNotification().extras.getLong(NotificationWrapper.EXTRA_EVENT_ID, 0L); - if (notifEventId == eventId) return true; + for (StatusBarNotification statusBarNotif : statusBarNotifs) { + final Bundle extra = statusBarNotif.getNotification().extras; + if (extra == null) continue; + final long activeNotifEventId = statusBarNotif.getNotification().extras.getLong(NotificationWrapper.EXTRA_EVENT_ID, 0L); + final String activeNotifContentText = statusBarNotif.getNotification().extras.getString(Notification.EXTRA_TEXT, ""); + if (activeNotifEventId == eventId && primaryText.equals(activeNotifContentText)) return true; } return false; } diff --git a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java index 71b5d70de..1cb916d61 100644 --- a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java +++ b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java @@ -25,7 +25,7 @@ public abstract class NotificationMgr { public abstract void cancel(int id); public abstract void createNotificationChannel(NotificationChannel channel); - public abstract boolean notificationAlreadyExistForEvent(long eventId); + public abstract boolean notificationAlreadyDisplayed(long eventId, String primaryText); /** * Don't actually use the notification framework's cancelAll since the SyncAdapter -- GitLab From 8e735c19a6bd61499205c363bfa68801be80314c Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Fri, 26 May 2023 11:24:45 +0200 Subject: [PATCH 05/15] add check logic for mediumPriority notification and few 'final' keyword --- .../java/com/android/calendar/alerts/AlertService.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index 97393091e..0d7ca24c6 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -238,7 +238,7 @@ public class AlertService extends Service { // concurrent events). Order these so that earlier start times appear higher in // the notification list. for (int i = 0; i < highPriorityEvents.size(); i++) { - NotificationInfo info = highPriorityEvents.get(i); + final NotificationInfo info = highPriorityEvents.get(i); final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); @@ -259,11 +259,12 @@ public class AlertService extends Service { // TODO: Post these with the same notification priority level as the higher priority // events, so that all notifications will be co-located together. for (int i = mediumPriorityEvents.size() - 1; i >= 0; i--) { - NotificationInfo info = mediumPriorityEvents.get(i); + final NotificationInfo info = mediumPriorityEvents.get(i); // TODO: Change to a relative time description like: "Started 40 minutes ago". // This requires constant refreshing to the message as time goes. - String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, + final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); + if (nm.notificationAlreadyDisplayed(info.eventId, summaryText)) { continue; } postNotification(info, summaryText, context, false, notificationPrefs, nm, currentNotificationId++); -- GitLab From 5de342e13817761ebc26d7023a169938a2aaa1ff Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 29 May 2023 10:16:29 +0200 Subject: [PATCH 06/15] increase notification id even if no new notif is displayed --- .../java/com/android/calendar/alerts/AlertService.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index 0d7ca24c6..70bde3b5a 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -242,11 +242,11 @@ public class AlertService extends Service { final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); - + final int notifId = currentNotificationId++; if (nm.notificationAlreadyDisplayed(info.eventId, summaryText)) { continue; } postNotification(info, summaryText, context, true, notificationPrefs, nm, - currentNotificationId++); + notifId); // Keep concurrent events high priority (to appear higher in the notification list) // until 15 minutes into the event. @@ -264,9 +264,10 @@ public class AlertService extends Service { // This requires constant refreshing to the message as time goes. final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); + final int notifId = currentNotificationId++; if (nm.notificationAlreadyDisplayed(info.eventId, summaryText)) { continue; } postNotification(info, summaryText, context, false, notificationPrefs, nm, - currentNotificationId++); + notifId); // Refresh when concurrent event ends so it will drop into the expired digest. nextRefreshTime = Math.min(nextRefreshTime, getNextRefreshTime(info, currentTime)); -- GitLab From 1bcd6b213490532c2c28e7869a3127e34bf9b6d4 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 31 May 2023 11:06:49 +0200 Subject: [PATCH 07/15] update process for posting notification --- app/src/main/AndroidManifest.xml | 2 +- .../android/calendar/alerts/AlertService.java | 68 +++++++++++++------ .../calendar/alerts/NotificationMgr.java | 11 ++- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 703ced6b5..e7d82796a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -204,7 +204,7 @@ alreadyDisplayedNotifs = new HashSet<>(); + // Post the individual higher priority events (future and recently started // concurrent events). Order these so that earlier start times appear higher in // the notification list. - for (int i = 0; i < highPriorityEvents.size(); i++) { - final NotificationInfo info = highPriorityEvents.get(i); - + for (NotificationInfo info : highPriorityEvents) { + Log.i("PorVince", "Event id: "+info.eventId); final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); - final int notifId = currentNotificationId++; - if (nm.notificationAlreadyDisplayed(info.eventId, summaryText)) { continue; } + + final int notifId = new Long(info.eventId).intValue() + summaryText.hashCode(); + + //final String eventIDHexa = Long.toHexString(info.eventId); //for test puprose, it would avoid overflow issue of parsing long to int + + alreadyDisplayedNotifs.add(notifId); + if (nm.isDisplayedNotificationForEvent(notifId)) { + continue; + } postNotification(info, summaryText, context, true, notificationPrefs, nm, notifId); @@ -264,8 +273,13 @@ public class AlertService extends Service { // This requires constant refreshing to the message as time goes. final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); - final int notifId = currentNotificationId++; - if (nm.notificationAlreadyDisplayed(info.eventId, summaryText)) { continue; } + final int notifId = new Long(info.eventId).intValue() + summaryText.hashCode(); + + alreadyDisplayedNotifs.add(notifId); + if (nm.isDisplayedNotificationForEvent(notifId)) { + continue; + } + postNotification(info, summaryText, context, false, notificationPrefs, nm, notifId); @@ -314,12 +328,8 @@ public class AlertService extends Service { } // Remove the notifications that are hanging around from the previous refresh. - if (currentNotificationId <= maxNotifications) { - nm.cancelAllBetween(currentNotificationId, maxNotifications); - if (DEBUG) { - Log.d(TAG, "Canceling leftover notification IDs " + currentNotificationId + "-" - + maxNotifications); - } + if (alreadyDisplayedNotifs.size() <= maxNotifications) { + nm.cancelAllExcept(alreadyDisplayedNotifs); } // Schedule the next silent refresh time so notifications will change @@ -1028,17 +1038,37 @@ public class AlertService extends Service { mNm.notify(id, nw.mNotification); } + + @Override + public Boolean isDisplayedNotificationForEvent(int notifId) { + final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); + for (StatusBarNotification statusBarNotif : statusBarNotifs) { + if (notifId == statusBarNotif.getId()) return true; + } + return false; + } + @Override - public boolean notificationAlreadyDisplayed(long eventId, String primaryText) { + public void cancelAllExcept(HashSet notifIds) { + final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); + for (StatusBarNotification statusBarNotif : statusBarNotifs) { + final int statusBarNotifId = statusBarNotif.getId(); + if (!notifIds.contains(statusBarNotifId)) { + cancel(statusBarNotifId); + } + } + } + + public HashMap getActiveNotifIdAndEventId() { + final HashMap result = new HashMap<>(); final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); for (StatusBarNotification statusBarNotif : statusBarNotifs) { final Bundle extra = statusBarNotif.getNotification().extras; if (extra == null) continue; - final long activeNotifEventId = statusBarNotif.getNotification().extras.getLong(NotificationWrapper.EXTRA_EVENT_ID, 0L); - final String activeNotifContentText = statusBarNotif.getNotification().extras.getString(Notification.EXTRA_TEXT, ""); - if (activeNotifEventId == eventId && primaryText.equals(activeNotifContentText)) return true; + final long activeNotifEventId = extra.getLong(NotificationWrapper.EXTRA_EVENT_ID, 0L); + result.put(statusBarNotif.getId(), activeNotifEventId); } - return false; + return result; } } diff --git a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java index 1cb916d61..1cf3e8b72 100644 --- a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java +++ b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java @@ -17,15 +17,18 @@ package com.android.calendar.alerts; import android.app.NotificationChannel; +import android.service.notification.StatusBarNotification; import com.android.calendar.alerts.AlertService.NotificationWrapper; +import java.util.HashSet; + public abstract class NotificationMgr { public abstract void notify(int id, NotificationWrapper notification); public abstract void cancel(int id); public abstract void createNotificationChannel(NotificationChannel channel); - public abstract boolean notificationAlreadyDisplayed(long eventId, String primaryText); + public abstract Boolean isDisplayedNotificationForEvent(int notifId); /** * Don't actually use the notification framework's cancelAll since the SyncAdapter @@ -43,4 +46,10 @@ public abstract class NotificationMgr { cancel(i); } } + + /** + * Cancel all notification except the one listed by Ids + * @param notifIds + */ + public abstract void cancelAllExcept(HashSet notifIds); } -- GitLab From 1fb1907e251a59e1df1f1c276d9983f894cd031e Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 31 May 2023 11:16:56 +0200 Subject: [PATCH 08/15] fix crash due to extras in Notification --- .../com/android/calendar/alerts/AlertService.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index a99aeacd8..dfa2f20c7 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -983,7 +983,6 @@ public class AlertService extends Service { // Added wrapper for testing public static class NotificationWrapper { - public static final String EXTRA_EVENT_ID = "eventId"; Notification mNotification; long mEventId; long mBegin; @@ -997,7 +996,6 @@ public class AlertService extends Service { mBegin = startMillis; mEnd = endMillis; - mNotification.extras.putLong(EXTRA_EVENT_ID, eventId); // popup? // notification id? } @@ -1058,18 +1056,6 @@ public class AlertService extends Service { } } } - - public HashMap getActiveNotifIdAndEventId() { - final HashMap result = new HashMap<>(); - final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); - for (StatusBarNotification statusBarNotif : statusBarNotifs) { - final Bundle extra = statusBarNotif.getNotification().extras; - if (extra == null) continue; - final long activeNotifEventId = extra.getLong(NotificationWrapper.EXTRA_EVENT_ID, 0L); - result.put(statusBarNotif.getId(), activeNotifEventId); - } - return result; - } } static class NotificationInfo { -- GitLab From 569775dda882ed6ca370c21c97ecbe703d129c53 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 31 May 2023 11:22:56 +0200 Subject: [PATCH 09/15] remove one log instruction --- app/src/main/java/com/android/calendar/alerts/AlertService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index dfa2f20c7..32e2d4dde 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -241,7 +241,6 @@ public class AlertService extends Service { // concurrent events). Order these so that earlier start times appear higher in // the notification list. for (NotificationInfo info : highPriorityEvents) { - Log.i("PorVince", "Event id: "+info.eventId); final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); -- GitLab From 36b81a9d19209955131f2fe1b9a2de2eac4d1dcc Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 31 May 2023 13:49:44 +0200 Subject: [PATCH 10/15] apply Jonathan's suggestion --- .../main/java/com/android/calendar/alerts/AlertService.java | 6 +++--- .../java/com/android/calendar/alerts/NotificationMgr.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index 32e2d4dde..a35f8930f 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -249,7 +249,7 @@ public class AlertService extends Service { //final String eventIDHexa = Long.toHexString(info.eventId); //for test puprose, it would avoid overflow issue of parsing long to int alreadyDisplayedNotifs.add(notifId); - if (nm.isDisplayedNotificationForEvent(notifId)) { + if (nm.isNotificationDisplayed(notifId)) { continue; } @@ -275,7 +275,7 @@ public class AlertService extends Service { final int notifId = new Long(info.eventId).intValue() + summaryText.hashCode(); alreadyDisplayedNotifs.add(notifId); - if (nm.isDisplayedNotificationForEvent(notifId)) { + if (nm.isNotificationDisplayed(notifId)) { continue; } @@ -1037,7 +1037,7 @@ public class AlertService extends Service { @Override - public Boolean isDisplayedNotificationForEvent(int notifId) { + public boolean isNotificationDisplayed(int notifId) { final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); for (StatusBarNotification statusBarNotif : statusBarNotifs) { if (notifId == statusBarNotif.getId()) return true; diff --git a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java index 1cf3e8b72..0bda43323 100644 --- a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java +++ b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java @@ -28,7 +28,7 @@ public abstract class NotificationMgr { public abstract void cancel(int id); public abstract void createNotificationChannel(NotificationChannel channel); - public abstract Boolean isDisplayedNotificationForEvent(int notifId); + public abstract boolean isNotificationDisplayed(int notifId); /** * Don't actually use the notification framework's cancelAll since the SyncAdapter -- GitLab From 30d7d974bf2ff172e4275418f38ef26b6bf7c2be Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 1 Jun 2023 09:44:14 +0200 Subject: [PATCH 11/15] apply Sayantan suggestion about variable name --- .../java/com/android/calendar/alerts/AlertService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index a35f8930f..7d14caf22 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -235,7 +235,7 @@ public class AlertService extends Service { redistributeBuckets(highPriorityEvents, mediumPriorityEvents, lowPriorityEvents, maxNotifications); - final HashSet alreadyDisplayedNotifs = new HashSet<>(); + final HashSet displayedNotifIds = new HashSet<>(); // Post the individual higher priority events (future and recently started // concurrent events). Order these so that earlier start times appear higher in @@ -248,7 +248,7 @@ public class AlertService extends Service { //final String eventIDHexa = Long.toHexString(info.eventId); //for test puprose, it would avoid overflow issue of parsing long to int - alreadyDisplayedNotifs.add(notifId); + displayedNotifIds.add(notifId); if (nm.isNotificationDisplayed(notifId)) { continue; } @@ -274,7 +274,7 @@ public class AlertService extends Service { info.allDay, info.location); final int notifId = new Long(info.eventId).intValue() + summaryText.hashCode(); - alreadyDisplayedNotifs.add(notifId); + displayedNotifIds.add(notifId); if (nm.isNotificationDisplayed(notifId)) { continue; } @@ -327,8 +327,8 @@ public class AlertService extends Service { } // Remove the notifications that are hanging around from the previous refresh. - if (alreadyDisplayedNotifs.size() <= maxNotifications) { - nm.cancelAllExcept(alreadyDisplayedNotifs); + if (displayedNotifIds.size() <= maxNotifications) { + nm.cancelAllExcept(displayedNotifIds); } // Schedule the next silent refresh time so notifications will change -- GitLab From 004043d6a10c70979a5e4f9f1f10d4601428df5a Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 1 Jun 2023 10:01:13 +0200 Subject: [PATCH 12/15] add nullity annotation as required by Jonathan --- .../main/java/com/android/calendar/alerts/AlertService.java | 3 ++- .../java/com/android/calendar/alerts/NotificationMgr.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index 7d14caf22..d2cbdf4c9 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -47,6 +47,7 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; +import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; @@ -1046,7 +1047,7 @@ public class AlertService extends Service { } @Override - public void cancelAllExcept(HashSet notifIds) { + public void cancelAllExcept(@NonNull HashSet notifIds) { final StatusBarNotification[] statusBarNotifs = mNm.getActiveNotifications(); for (StatusBarNotification statusBarNotif : statusBarNotifs) { final int statusBarNotifId = statusBarNotif.getId(); diff --git a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java index 0bda43323..00e6c1dce 100644 --- a/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java +++ b/app/src/main/java/com/android/calendar/alerts/NotificationMgr.java @@ -19,6 +19,8 @@ package com.android.calendar.alerts; import android.app.NotificationChannel; import android.service.notification.StatusBarNotification; +import androidx.annotation.NonNull; + import com.android.calendar.alerts.AlertService.NotificationWrapper; import java.util.HashSet; @@ -51,5 +53,5 @@ public abstract class NotificationMgr { * Cancel all notification except the one listed by Ids * @param notifIds */ - public abstract void cancelAllExcept(HashSet notifIds); + public abstract void cancelAllExcept(@NonNull HashSet notifIds); } -- GitLab From 2460b7b381b702d2e6f2e5d3ec7792c3a8983846 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Fri, 2 Jun 2023 10:50:01 +0200 Subject: [PATCH 13/15] refactor postNotification --- .../android/calendar/alerts/AlertService.java | 82 +++++++++---------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index d2cbdf4c9..69ea91fc8 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -245,17 +245,9 @@ public class AlertService extends Service { final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); - final int notifId = new Long(info.eventId).intValue() + summaryText.hashCode(); - - //final String eventIDHexa = Long.toHexString(info.eventId); //for test puprose, it would avoid overflow issue of parsing long to int + final int notifId = postNotification(info, summaryText, context, true, notificationPrefs, nm); displayedNotifIds.add(notifId); - if (nm.isNotificationDisplayed(notifId)) { - continue; - } - - postNotification(info, summaryText, context, true, notificationPrefs, nm, - notifId); // Keep concurrent events high priority (to appear higher in the notification list) // until 15 minutes into the event. @@ -273,15 +265,10 @@ public class AlertService extends Service { // This requires constant refreshing to the message as time goes. final String summaryText = AlertUtils.formatTimeLocation(context, info.startMillis, info.allDay, info.location); - final int notifId = new Long(info.eventId).intValue() + summaryText.hashCode(); - displayedNotifIds.add(notifId); - if (nm.isNotificationDisplayed(notifId)) { - continue; - } + final int notifId = postNotification(info, summaryText, context, false, notificationPrefs, nm); - postNotification(info, summaryText, context, false, notificationPrefs, nm, - notifId); + displayedNotifIds.add(notifId); // Refresh when concurrent event ends so it will drop into the expired digest. nextRefreshTime = Math.min(nextRefreshTime, getNextRefreshTime(info, currentTime)); @@ -709,41 +696,48 @@ public class AlertService extends Service { return digestTitle.toString(); } - private static void postNotification(NotificationInfo info, String summaryText, + private static int postNotification(NotificationInfo info, String summaryText, Context context, boolean highPriority, NotificationPrefs prefs, - NotificationMgr notificationMgr, int notificationId) { - int priorityVal = Notification.PRIORITY_DEFAULT; - if (highPriority) { - priorityVal = Notification.PRIORITY_HIGH; - } + NotificationMgr notificationMgr) { - String tickerText = getTickerText(info.eventName, info.location); - NotificationWrapper notification = AlertReceiver.makeExpandingNotification(context, - info.eventName, summaryText, info.description, info.startMillis, - info.endMillis, info.eventId, notificationId, prefs.getDoPopup(), priorityVal); + final int notificationId = Long.valueOf(info.eventId).intValue() + summaryText.hashCode(); + //final String eventIDHexa = Long.toHexString(info.eventId); //for test purpose, it would avoid overflow issue of parsing long to int - boolean quietUpdate = true; - String ringtone = NotificationPrefs.EMPTY_RINGTONE; - if (info.newAlert) { - quietUpdate = prefs.quietUpdate; + if (!notificationMgr.isNotificationDisplayed(notificationId)) { + int priorityVal = Notification.PRIORITY_DEFAULT; + if (highPriority) { + priorityVal = Notification.PRIORITY_HIGH; + } - // If we've already played a ringtone, don't play any more sounds so only - // 1 sound per group of notifications. - ringtone = prefs.getRingtoneAndSilence(); - } - addNotificationOptions(notification, quietUpdate, tickerText, - prefs.getDefaultVibrate(), ringtone, - true); /* Show the LED for these non-expired events */ + String tickerText = getTickerText(info.eventName, info.location); + NotificationWrapper notification = AlertReceiver.makeExpandingNotification(context, + info.eventName, summaryText, info.description, info.startMillis, + info.endMillis, info.eventId, notificationId, prefs.getDoPopup(), priorityVal); - // Post the notification. - notificationMgr.notify(notificationId, notification); + boolean quietUpdate = true; + String ringtone = NotificationPrefs.EMPTY_RINGTONE; + if (info.newAlert) { + quietUpdate = prefs.quietUpdate; - if (DEBUG) { - Log.d(TAG, "Posting individual alarm notification, eventId:" + info.eventId - + ", notificationId:" + notificationId - + (TextUtils.isEmpty(ringtone) ? ", quiet" : ", LOUD") - + (highPriority ? ", high-priority" : "")); + // If we've already played a ringtone, don't play any more sounds so only + // 1 sound per group of notifications. + ringtone = prefs.getRingtoneAndSilence(); + } + addNotificationOptions(notification, quietUpdate, tickerText, + prefs.getDefaultVibrate(), ringtone, + true); /* Show the LED for these non-expired events */ + + // Post the notification. + notificationMgr.notify(notificationId, notification); + + if (DEBUG) { + Log.d(TAG, "Posting individual alarm notification, eventId:" + info.eventId + + ", notificationId:" + notificationId + + (TextUtils.isEmpty(ringtone) ? ", quiet" : ", LOUD") + + (highPriority ? ", high-priority" : "")); + } } + return notificationId; } private static String getTickerText(String eventName, String location) { -- GitLab From 5d4a63dabf0288a38cf269b96657828f52b189cc Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 5 Jun 2023 14:59:08 +0200 Subject: [PATCH 14/15] remove useless import --- app/src/main/java/com/android/calendar/alerts/AlertService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java index 69ea91fc8..f643e3b1b 100644 --- a/app/src/main/java/com/android/calendar/alerts/AlertService.java +++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java @@ -48,7 +48,6 @@ import android.text.format.DateUtils; import android.util.Log; import androidx.annotation.NonNull; -import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; import com.android.calendar.Utils; @@ -59,7 +58,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.TimeZone; import ws.xsoh.etar.R; -- GitLab From 5be0af83de4b1094193d7a066ba17f327a65c312 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 5 Jun 2023 16:23:31 +0200 Subject: [PATCH 15/15] add NB about how to build /e/ OS --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 208ba7f29..d60c0c425 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,9 @@ gradle :app:assembleDebug 5. Run `./gradlew aarGen` 6. Run `./gradlew :app:assembleDebug` + +NB: we were integrating it within /e/OS from Android_prebuilt until version 9. Now it is build with the OS. + ## License Copyright (c) 2005-2013, The Android Open Source Project -- GitLab