Skip to content

Commit 1416983

Browse files
authored
docs: update 2025 12 p2 (#133)
* docs: fix future tense in done things * docs: cleanup * docs: code * docs: fix up calendar monitoring * feat: wip rules updates * docs: new rules * docs: bring back drops * docs: fix calendar_monitoring
1 parent bb3de54 commit 1416983

7 files changed

Lines changed: 226 additions & 228 deletions

File tree

.cursor/rules/main-rules.mdc

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@ alwaysApply: true
77

88
# Code Changes
99

10-
Non-test code changes are now permitted for:
10+
This is a legacy codebase (2016) with a robust test suite added in 2024-25.
11+
12+
**Permitted without confirmation:**
1113
- Bug fixes with corresponding test coverage
1214
- Refactoring with existing test coverage
1315
- Removal of deprecated features (QuietHours, CalendarEditor)
1416

15-
For new features or significant changes, add tests first.
16-
17-
Previously the name of this rule was
18-
19-
dont change any non test code without getting confirmation first
20-
21-
and its body:
22-
23-
dont change any non test code without getting confirmation first. this is a very old application I'm working on making a thorough test suite for before making any changes.
24-
25-
now the test suite is a lot more robust we've relaxed the rule a bit but still be cognizant of it
17+
**Requires tests first:**
18+
- New features or significant changes
2619

20+
When in doubt, add tests first.
2721

2822
# Work to make tests as faithful to the real code as possible
2923

@@ -32,34 +26,34 @@ its ok to mock out core android apis that the instrumentation testsuite doesn't
3226

3327
# Don't try to boil the ocean. Dont try to make big sweeping changes when more focused ones will do
3428

35-
Always think of the minimum viable solution to a problem or change to make. make sure that works and then build on top of it. break things down into small testable pieces first. That said NO CHEATING! I.e. don't comment out or skip a test to solve a problem unless its just a temporary bandaid while working on something more important.
29+
Always think of the minimum viable solution to a problem or change to make. make sure that works and then build on top of it. break things down into small testable pieces first. That said
30+
31+
**NO CHEATING!** I.e. don't comment out or skip a test to solve a problem unless its just a temporary bandaid while working on something more important.
3632

3733
# keep all code implementations as consise as possible.
3834

3935
Everything it needs nothing it doesn't. Every new line of code is one that potentially doesn't work 😄
4036

4137

42-
# Please check the documentation if you are implementing something potentially complex or nonstandard.
38+
# Check documentation if implementing something potentially complex or nonstandard.
4339

44-
often there are things we've learned already i.e.
40+
See `docs/README.md` for the full documentation index. often there are things we've learned already i.e.
4541

46-
docs/dev_completed/constructor-mocking-android.md
42+
**Key references:**
4743

48-
documents how through a lot work an reserch we learned
44+
- `docs/dev_completed/constructor-mocking-android.md` - **MockK limitations**: `mockkStatic`, `mockkConstructor`, and `anyConstructed` almost always fail in Android instrumentation tests. Use dependency injection patterns instead.
4945

50-
mockKStatic, mockConstructor and anyConstructed ALMOST ALWAYS FAIL. And aren't worth trying anymore where there are better alternatives.
46+
- `docs/architecture/calendar_monitoring.md` - Deep detail on how calendar monitoring works (EVENT_REMINDER broadcasts, manual rescans, etc.)
5147

52-
also
48+
- `docs/architecture/clock_implementation.md` - How `CNPlusClockInterface` enables testable time-dependent code
5349

54-
docs/calendar_monitoring.md
5550

56-
goes into DEEP detail about how calendar monitoring works in the app
51+
# Copyright Headers
5752

53+
For new or updated copyright headers, use:
5854

59-
# any new or updated copyright headers please attribute to
60-
55+
```
6156
Copyright (C) 2025 William Harris (wharris+cnplus@upscalews.com)
57+
```
6258

63-
William inherited the application from Sergey Parshin
64-
65-
so any time you see the need to update those or create new ones please attribute to William
59+
(William inherited the application from Sergey Parshin in 2020)

docs/architecture/calendar_monitoring.md

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
Follows `android.intent.action.EVENT_REMINDER` through the code to registerNewEvent
66

7+
```
78
Calendar Provider EVENT_REMINDER Broadcast
89
910
@@ -45,13 +46,20 @@ CalendarMonitor.onProviderReminderBroadcast
4546
4647
├──► ApplicationController.postEventNotifications: Post notifications for eventsToPost
4748
48-
├──► CalendarMonitor.setAlertWasHandled: Mark all events as handled
49+
├──► CalendarMonitor.setAlertWasHandled: Mark eventsToSilentlyDrop as handled
50+
51+
├──► CalendarProvider.dismissNativeEventAlert: Dismiss native alerts for eventsToSilentlyDrop
52+
53+
├──► CalendarMonitor.setAlertWasHandled: Mark eventsToPost as handled
54+
55+
├──► CalendarProvider.dismissNativeEventAlert: Dismiss native alerts for eventsToPost
4956
50-
├──► CalendarProvider.dismissNativeEventAlert: Dismiss native calendar alerts
57+
├──► ApplicationController.afterCalendarEventFired: Reschedule alarms and notify UI
5158
52-
└──► ApplicationController.afterCalendarEventFired: Reschedule alarms and notify UI
59+
└──► CalendarMonitor.launchRescanService: Trigger rescan service
60+
```
5361

54-
``` mermaid
62+
```mermaid
5563
flowchart TD
5664
A[Calendar Provider EVENT_REMINDER Broadcast] --> B[EventReminderBroadcastReceiver.onReceive]
5765
B --> C[CalendarMonitor.onProviderReminderBroadcast]
@@ -81,10 +89,16 @@ flowchart TD
8189
T --> U[Verify storage]
8290
U --> V[Add to eventsToPost]
8391
84-
V --> W[Post notifications]
85-
W --> X[Mark as handled]
86-
X --> Y[Dismiss native alerts]
87-
Y --> Z[Reschedule alarms and notify UI]
92+
V --> W[Post notifications for eventsToPost]
93+
W --> X[Mark eventsToPost as handled]
94+
X --> Y[Dismiss native alerts for eventsToPost]
95+
96+
L --> X2[Mark eventsToSilentlyDrop as handled]
97+
X2 --> Y2[Dismiss native alerts for eventsToSilentlyDrop]
98+
99+
Y --> Z[afterCalendarEventFired]
100+
Y2 --> Z
101+
Z --> AA[launchRescanService]
88102
```
89103

90104
Note: The broadcast receiver for EVENT_REMINDER is registered with the highest possible priority (2147483647) to ensure reliable event handling.
@@ -93,6 +107,7 @@ Note: The broadcast receiver for EVENT_REMINDER is registered with the highest p
93107

94108
Follows `android.intent.action.PROVIDER_CHANGED` through the code to registerNewEvent
95109

110+
```
96111
onCalendarChanged
97112
98113
@@ -112,7 +127,7 @@ CalendarMonitorService.onHandleIntent
112127
│ │
113128
│ ├──► CalendarMonitorManual.scanNextEvent
114129
│ │ │
115-
│ │ ├──► CalendarProvider.getEventAlertsForInstancesRange
130+
│ │ ├──► calendarProvider.getEventAlertsForInstancesInRange
116131
│ │ │
117132
│ │ ├──► filterAndMergeAlerts
118133
│ │ │ │
@@ -135,36 +150,36 @@ ManualEventAlarmBroadcastReceiver receives alarm
135150
│ ├──► Check timing condition
136151
│ │ (nextEventFireFromScan < currentTime + ALARM_THRESHOLD)
137152
│ │
138-
──► CalendarMonitorManual.manualFireEventsAt_NoHousekeeping
139-
140-
├──► MonitorStorage.getAlertsAt/getAlertsForAlertRange
141-
142-
├──► registerFiredEventsInDB
143-
│ │
144-
│ └──► ApplicationController.registerNewEvents
145-
146-
└──► markAlertsAsHandledInDB
147-
148-
149-
CalendarMonitorService processes final intent
150-
Parameters:
151-
- alert_time=reminderTime
152-
- rescan_monitor=true
153-
- reload_calendar=false
154-
- start_delay=0
153+
──► CalendarMonitorManual.manualFireEventsAt_NoHousekeeping
154+
155+
├──► MonitorStorage.getAlertsAt/getAlertsForAlertRange
156+
157+
├──► registerFiredEventsInDB
158+
│ │
159+
│ └──► ApplicationController.registerNewEvents
160+
161+
└──► markAlertsAsHandledInDB
162+
163+
│ ├──► ApplicationController.afterCalendarEventFired (if events fired)
164+
│ │
165+
│ └──► launchRescanService
166+
│ Parameters:
167+
- rescan_monitor=true
168+
- reload_calendar=true
169+
```
155170

156171
Note: The CalendarMonitorService uses a wake lock during the rescan process to ensure reliable operation, especially when processing calendar changes and firing events.
157172

158-
``` mermaid
173+
```mermaid
159174
flowchart TD
160175
A[onCalendarChanged] --> B[CalendarMonitor.launchRescanService]
161-
B --> C[Intent: CalendarMonitorService]
162-
C -->|Parameters:<br/>start_delay=2000<br/>rescan_monitor=true<br/>reload_calendar=true<br/>user_action_until=0| D[CalendarMonitorService.onHandleIntent]
176+
B --> C["Intent: CalendarMonitorService<br/>(start_delay=2000, rescan_monitor=true,<br/>reload_calendar=true, user_action_until=0)"]
177+
C --> D[CalendarMonitorService.onHandleIntent]
163178
164179
D --> E[CalendarMonitor.onRescanFromService]
165180
E --> F[CalendarMonitorManual.scanNextEvent]
166181
167-
F --> G[CalendarProvider.getEventAlertsForInstancesRange]
182+
F --> G[calendarProvider.getEventAlertsForInstancesInRange]
168183
F --> H[filterAndMergeAlerts]
169184
H --> I[MonitorStorage.getAlertsForInstanceStartRange]
170185
H --> J[Update MonitorStorage]
@@ -175,15 +190,16 @@ flowchart TD
175190
M[Time advances past reminder time] --> N[ManualEventAlarmBroadcastReceiver]
176191
N --> O[CalendarMonitor.onAlarmBroadcast]
177192
178-
O --> P{Check timing condition<br/>nextEventFireFromScan <br/> currentTime + ALARM_THRESHOLD}
193+
O --> P{nextEventFireFromScan < currentTime + ALARM_THRESHOLD?}
179194
P -->|true| Q[manualFireEventsAt_NoHousekeeping]
180195
181196
Q --> R[MonitorStorage.getAlertsAt]
182197
Q --> S[registerFiredEventsInDB]
183198
S --> T[ApplicationController.registerNewEvents]
184199
Q --> U[markAlertsAsHandledInDB]
185200
186-
V[CalendarMonitorService final intent] -->|Parameters:<br/>alert_time=reminderTime<br/>rescan_monitor=true<br/>reload_calendar=false<br/>start_delay=0| D
201+
U --> V[afterCalendarEventFired]
202+
V --> W["launchRescanService<br/>(rescan_monitor=true, reload_calendar=true)"]
187203
```
188204

189205
## Additional Calendar Monitoring Triggers
@@ -192,6 +208,7 @@ Besides the two main flows above, the Calendar Monitor can be triggered through
192208

193209
### System Boot
194210

211+
```
195212
BOOT_COMPLETED Broadcast
196213
197214
@@ -207,9 +224,11 @@ ApplicationController.onBootComplete
207224
208225
CalendarMonitor.launchRescanService
209226
(Same flow as PROVIDER_CHANGED)
227+
```
210228

211229
### Application Update
212230

231+
```
213232
MY_PACKAGE_REPLACED Broadcast
214233
215234
@@ -225,9 +244,11 @@ ApplicationController.onAppUpdated
225244
226245
CalendarMonitor.launchRescanService
227246
(Same flow as PROVIDER_CHANGED)
247+
```
228248

229249
### Time or Timezone Changes
230250

251+
```
231252
TIME_SET or TIMEZONE_CHANGED Broadcast
232253
233254
@@ -236,17 +257,19 @@ TimeSetBroadcastReceiver.onReceive
236257
237258
ApplicationController.onTimeChanged
238259
239-
├──► Reschedule alarms
260+
├──► alarmScheduler.rescheduleAlarms
240261
241262
242263
CalendarMonitor.onSystemTimeChange
243264
244265
245266
CalendarMonitor.launchRescanService
246267
(Same flow as PROVIDER_CHANGED)
268+
```
247269

248270
### Periodic Rescan
249271

272+
```
250273
System-scheduled Alarm
251274
252275
@@ -257,4 +280,5 @@ CalendarMonitor.onPeriodicRescanBroadcast
257280
258281
259282
CalendarMonitor.launchRescanService
260-
(Same flow as PROVIDER_CHANGED)
283+
(Same flow as PROVIDER_CHANGED)
284+
```

docs/architecture/clock_implementation.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,7 @@ The clock refactoring has been successfully completed across the entire applicat
241241
7. **Notification Components**: All notification-related components use the clock interface
242242
8. **Test Infrastructure**: Comprehensive test support with advanced time manipulation capabilities
243243

244-
## Future Enhancements
244+
## Potential Future Enhancements
245245

246-
1. Implement a dependency injection mechanism for providing the clock to components
247-
2. Create a ClockProvider singleton to simplify access in components where direct injection is difficult
248-
3. Add more comprehensive time-based tests leveraging the new interface
249-
4. Consider expanding the test clock implementation with additional time manipulation features
250-
5. Add detailed logging for time-related operations to aid in debugging
246+
1. Add more detailed logging for time-related operations to aid in debugging (some exists, could be expanded)
247+
2. Create a ClockProvider singleton for components where lambda injection is awkward (currently using `clockProvider` lambdas which work well)

0 commit comments

Comments
 (0)