From 6599c7ddcddab717a06df8185e1ad2e45c72750f Mon Sep 17 00:00:00 2001
From: iusmac <iusico.maxim@libero.it>
Date: Wed, 10 Apr 2024 17:18:23 +0200
Subject: [PATCH] fix(#7): make scheduler respect user SIM enabled/disabled
 state if time matches current system time

Signed-off-by: iusmac <iusico.maxim@libero.it>
---
 .../sevensim/DirectBootAwareBroadcastReceiver.java  | 13 ++++++++-----
 .../iusmac/sevensim/SystemBroadcastReceiver.java    |  3 ++-
 .../sevensim/scheduler/SubscriptionScheduler.java   | 13 ++++++++-----
 .../SubscriptionSchedulerSummaryBuilder.java        |  8 +++++++-
 .../iusmac/sevensim/telephony/Subscription.java     |  5 +++--
 5 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/src/com/github/iusmac/sevensim/DirectBootAwareBroadcastReceiver.java b/src/com/github/iusmac/sevensim/DirectBootAwareBroadcastReceiver.java
index 8008f2c..6ac4ac6 100644
--- a/src/com/github/iusmac/sevensim/DirectBootAwareBroadcastReceiver.java
+++ b/src/com/github/iusmac/sevensim/DirectBootAwareBroadcastReceiver.java
@@ -47,7 +47,8 @@ public void onReceive(final Context context, final Intent intent) {
                 // Need to schedule the next iteration processing of weekly repeat schedules after
                 // the device has finished booting. Note that, this call should only happen after
                 // syncing
-                ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context, now);
+                ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context,
+                        now.plusMinutes(1));
                 break;
 
             case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
@@ -73,10 +74,12 @@ public void onReceive(final Context context, final Intent intent) {
                         /*overrideUserPreference=*/ false);
 
                 // Need to re-schedule the next iteration processing of weekly repeat schedules
-                // after syncing. Note that, if the SIM card was ejected, the SIM subscription won't
-                // exist as well, so there will be nothing to sync, but we still need to do
-                // re-scheduling as there can be other SIM cards in the system with their schedules
-                ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context, now);
+                // after syncing. Note that, if the SIM card was disabled on devices using legacy
+                // RIL, the SIM subscription won't exist as well, so there will be nothing to sync,
+                // but we still need to do re-scheduling as there can be other SIM cards in the
+                // system with their schedules, otherwise it will cancel existing alarm
+                ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context,
+                        now.plusMinutes(1));
                 break;
 
             default:
diff --git a/src/com/github/iusmac/sevensim/SystemBroadcastReceiver.java b/src/com/github/iusmac/sevensim/SystemBroadcastReceiver.java
index 7dceebc..963e94b 100644
--- a/src/com/github/iusmac/sevensim/SystemBroadcastReceiver.java
+++ b/src/com/github/iusmac/sevensim/SystemBroadcastReceiver.java
@@ -70,7 +70,8 @@ public void onReceive(final Context context, final Intent intent) {
                 // Need to reschedule the next weekly repeat schedule processing iteration, as it
                 // relies on a RTC-based alarm, which, in turn is independent of any alteration to
                 // the system time. Note that, this call should only happen after syncing
-                ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context, now);
+                ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context,
+                        now.plusMinutes(1));
                 break;
 
             default:
diff --git a/src/com/github/iusmac/sevensim/scheduler/SubscriptionScheduler.java b/src/com/github/iusmac/sevensim/scheduler/SubscriptionScheduler.java
index 73acc22..921782d 100644
--- a/src/com/github/iusmac/sevensim/scheduler/SubscriptionScheduler.java
+++ b/src/com/github/iusmac/sevensim/scheduler/SubscriptionScheduler.java
@@ -387,8 +387,8 @@ private PendingIntent getPendingIntent() {
     }
 
     /**
-     * Determine the expected SIM subscription enabled state using an opened interval
-     * ({@code a<x<b}) of two opposite schedules.
+     * Determine the expected SIM subscription enabled state using a closed interval
+     * ({@code a<=x<=b}) of two opposite schedules.
      *
      * @param sub The subscription for which to determine the expected enabled state.
      * @param startDateTime The interval start date-time value. This is expected to be date-time of
@@ -398,7 +398,8 @@ private PendingIntent getPendingIntent() {
      * @param overrideUserPreference Whether the user's preference should NOT take precedence over
      * schedule intervals. For instance, if the SIM subscription is expected to be disabled, but the
      * user enabled it manually, then pass {@code false} to keep the state within the allowed
-     * period.
+     * period. Note that, when passed in {@code true}, an opened interval ({@code a<x<b}) will be
+     * used instead for comparison.
      * @return {@code true} if the SIM subscription is expected to be enabled, {@code false}
      * otherwise.
      */
@@ -408,7 +409,8 @@ private static boolean getSubscriptionExpectedEnabledState(final Subscription su
 
         if (sub.isSimEnabled()) {
             return endDateTime.map((end) -> {
-                if (!overrideUserPreference && sub.getLastActivatedTime().isAfter(end)) {
+                if (!overrideUserPreference && (sub.getLastActivatedTime().equals(end) ||
+                            sub.getLastActivatedTime().isAfter(end))) {
                     return true;
                 }
 
@@ -430,7 +432,8 @@ private static boolean getSubscriptionExpectedEnabledState(final Subscription su
             });
         }
         return startDateTime.map((start) -> {
-            if (!overrideUserPreference && sub.getLastDeactivatedTime().isAfter(start)) {
+            if (!overrideUserPreference && (sub.getLastDeactivatedTime().equals(start) ||
+                        sub.getLastDeactivatedTime().isAfter(start))) {
                 return false;
             }
             return endDateTime.map((end) -> end.isBefore(start)).orElse(true);
diff --git a/src/com/github/iusmac/sevensim/scheduler/SubscriptionSchedulerSummaryBuilder.java b/src/com/github/iusmac/sevensim/scheduler/SubscriptionSchedulerSummaryBuilder.java
index d7dee22..4a1efe3 100644
--- a/src/com/github/iusmac/sevensim/scheduler/SubscriptionSchedulerSummaryBuilder.java
+++ b/src/com/github/iusmac/sevensim/scheduler/SubscriptionSchedulerSummaryBuilder.java
@@ -101,8 +101,14 @@ public SubscriptionSchedulerSummaryBuilder(final @ApplicationContext Context con
         // Since we don't support seconds and milliseconds, drop them off to avoid inexact summaries
         dateTime = dateTime.truncatedTo(ChronoUnit.MINUTES);
 
+        // NOTE: if the SIM subscription state change time matches the target date-time, then we'll
+        // start seeking for the next weekly repeat schedule date-time that happens no earlier than
+        // one minute from the target date-time. This to avoid showing a summary for the schedule
+        // that just happened
+        final LocalDateTime dateTime2 = sub.getLastActivatedTime().equals(dateTime) ||
+                sub.getLastDeactivatedTime().equals(dateTime) ? dateTime.plusMinutes(1) : dateTime;
         final LocalDateTime nearestScheduleDateTime =
-            SubscriptionScheduler.getDateTimeAfter(nearestSchedule.get(), dateTime).get();
+            SubscriptionScheduler.getDateTimeAfter(nearestSchedule.get(), dateTime2).get();
 
         // NOTE: we *must* isolate the usage of the Formatter to avoid result aggregation from
         // concurrent threads, also protect the StringBuilder length resetting
diff --git a/src/com/github/iusmac/sevensim/telephony/Subscription.java b/src/com/github/iusmac/sevensim/telephony/Subscription.java
index 1fa4316..85cb442 100644
--- a/src/com/github/iusmac/sevensim/telephony/Subscription.java
+++ b/src/com/github/iusmac/sevensim/telephony/Subscription.java
@@ -14,6 +14,7 @@
 
 import java.time.LocalDateTime;
 import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoUnit;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -103,7 +104,7 @@ public LocalDateTime getLastActivatedTime() {
     }
 
     public void setLastActivatedTime(final LocalDateTime lastActivatedTime) {
-        mLastActivatedTime = lastActivatedTime;
+        mLastActivatedTime = lastActivatedTime.truncatedTo(ChronoUnit.MINUTES);
     }
 
     public LocalDateTime getLastDeactivatedTime() {
@@ -111,7 +112,7 @@ public LocalDateTime getLastDeactivatedTime() {
     }
 
     public void setLastDeactivatedTime(final LocalDateTime lastDeactivatedTime) {
-        mLastDeactivatedTime = lastDeactivatedTime;
+        mLastDeactivatedTime = lastDeactivatedTime.truncatedTo(ChronoUnit.MINUTES);
     }
 
     public Boolean getKeepDisabledAcrossBoots() {