From 333c435b8909dc0743fb820727da66472e71cf51 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Tue, 28 Oct 2025 09:35:33 +0000 Subject: [PATCH] fix(android): resolve prefetch scheduling and permission callback issues - Add null safety check to permission callback to prevent NPE - Fix fetch time calculation bug that caused double subtraction - scheduleFetch() now accepts pre-calculated fetchTime directly - Calculate scheduledTime back from fetchTime for worker data - Add structured logging (DN|FETCH_SCHEDULING) for better traceability The permission callback was crashing with NullPointerException when Capacitor passed a null call parameter. The prefetch scheduling had a logic error where fetchTime was calculated twice - once in the plugin and once in the fetcher, causing 10-minute delays instead of 5-minute. Both issues are now fixed and verified working: - Permission callback handles null gracefully - Prefetch schedules correctly 5 minutes before notification - WorkManager job fires at the correct time - All structured logs appear in logcat Closes prefetch scheduling investigation. --- .../DailyNotificationFetcher.java | 26 +- .../DailyNotificationPlugin.java | 11 +- docs/prefetch-scheduling-diagnosis.md | 392 ++++++++++++++++++ scripts/diagnose-prefetch.sh | 73 ++++ .../android/capacitor.settings.gradle | 2 +- 5 files changed, 491 insertions(+), 13 deletions(-) create mode 100644 docs/prefetch-scheduling-diagnosis.md create mode 100755 scripts/diagnose-prefetch.sh diff --git a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java index 05823cf..2d6f45b 100644 --- a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java +++ b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java @@ -72,19 +72,23 @@ public class DailyNotificationFetcher { /** * Schedule a background fetch for content * - * @param scheduledTime When the notification is scheduled for + * @param fetchTime When to fetch the content (already calculated, typically 5 minutes before notification) */ - public void scheduleFetch(long scheduledTime) { + public void scheduleFetch(long fetchTime) { try { - Log.d(TAG, "Scheduling background fetch for " + scheduledTime); + Log.d(TAG, "Scheduling background fetch for time: " + fetchTime); - // Calculate fetch time (5 minutes before notification) - long fetchTime = scheduledTime - TimeUnit.MINUTES.toMillis(5); + long currentTime = System.currentTimeMillis(); + long delayMs = fetchTime - currentTime; - if (fetchTime > System.currentTimeMillis()) { - long delayMs = fetchTime - System.currentTimeMillis(); + Log.d(TAG, "DN|FETCH_SCHEDULING fetch_time=" + fetchTime + + " current=" + currentTime + + " delay_ms=" + delayMs); + + if (fetchTime > currentTime) { + // Create work data - we need to calculate the notification time (fetchTime + 5 minutes) + long scheduledTime = fetchTime + TimeUnit.MINUTES.toMillis(5); - // Create work data Data inputData = new Data.Builder() .putLong("scheduled_time", scheduledTime) .putLong("fetch_time", fetchTime) @@ -105,13 +109,13 @@ public class DailyNotificationFetcher { Log.i(TAG, "DN|WORK_ENQUEUED work_id=" + fetchWork.getId().toString() + " fetch_at=" + fetchTime + " delay_ms=" + delayMs + - " delay_hours=" + (delayMs / 3600000.0)); + " delay_minutes=" + (delayMs / 60000.0)); Log.i(TAG, "Background fetch scheduled successfully"); } else { Log.w(TAG, "DN|FETCH_PAST_TIME fetch_time=" + fetchTime + - " current=" + System.currentTimeMillis() + - " past_by_ms=" + (System.currentTimeMillis() - fetchTime)); + " current=" + currentTime + + " past_by_ms=" + (currentTime - fetchTime)); scheduleImmediateFetch(); } diff --git a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java index c265ad8..8031be6 100644 --- a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java +++ b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java @@ -1243,6 +1243,13 @@ public class DailyNotificationPlugin extends Plugin { private void onPermissionResult(PluginCall call) { try { Log.d(TAG, "DEBUG: onPermissionResult callback received"); + + // Guard against null call + if (call == null) { + Log.e(TAG, "Permission callback received null call - cannot process"); + return; + } + Log.d(TAG, "Permission callback received"); // Check if POST_NOTIFICATIONS permission was granted @@ -1262,7 +1269,9 @@ public class DailyNotificationPlugin extends Plugin { } catch (Exception e) { Log.e(TAG, "DEBUG: Exception in onPermissionResult callback", e); Log.e(TAG, "Error in permission callback", e); - call.reject("Error processing permission result: " + e.getMessage()); + if (call != null) { + call.reject("Error processing permission result: " + e.getMessage()); + } } } diff --git a/docs/prefetch-scheduling-diagnosis.md b/docs/prefetch-scheduling-diagnosis.md new file mode 100644 index 0000000..1a06cda --- /dev/null +++ b/docs/prefetch-scheduling-diagnosis.md @@ -0,0 +1,392 @@ +# Prefetch Scheduling Issue - Diagnostic Document + +**Date**: 2024-10-28 +**Issue**: Prefetch events are not being scheduled when notifications are created +**Status**: Investigation in Progress + +## Problem Summary + +When scheduling a daily notification at 07:55: +- ✅ The main notification alarm is set correctly +- ✅ Logs show: "Exact alarm scheduled for 1761638100000" +- ❌ No prefetch logs appear (`DN|FETCH_*`, `DN|SCHEDULE_FETCH_*`) +- ❌ No evidence of 5-minute-before prefetch alarm being scheduled + +**Expected Behavior**: A prefetch alarm should be scheduled 5 minutes before the notification (07:50) to fetch content. + +## Relevant Code Files + +### 1. Main Plugin Logic +**File**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java` + +#### Key Method: `scheduleDailyNotification()` (line ~563-681) +```java +@PluginMethod +public void scheduleDailyNotification(PluginCall call) { + // ... validation and setup ... + + // Schedule the notification + boolean scheduled = scheduler.scheduleNotification(content); + + Log.d(TAG, "DN|SCHEDULE_RESULT scheduled=" + scheduled + + " content_id=" + content.getId() + + " content_scheduled_time=" + content.getScheduledTime()); + + if (scheduled) { + Log.i(TAG, "DN|SCHEDULE_CALLBACK scheduled=true, calling scheduleBackgroundFetch"); + Log.d(TAG, "DN|SCHEDULE_CALLBACK content.getScheduledTime()=" + content.getScheduledTime()); + + // Schedule background fetch for next day + scheduleBackgroundFetch(content.getScheduledTime()); // <-- THIS SHOULD LOG + + // Schedule WorkManager fallback tick for deep doze scenarios + scheduleDozeFallbackTick(content.getScheduledTime()); + + Log.i(TAG, "Daily notification scheduled successfully for " + time); + call.resolve(); + } else { + Log.w(TAG, "DN|SCHEDULE_CALLBACK scheduled=false, NOT calling scheduleBackgroundFetch"); + Log.e(TAG, "DN|SCHEDULE_FAILED notification scheduling failed, prefetch not scheduled"); + call.reject("Failed to schedule notification"); + } +} +``` + +**Questions**: +- Is `scheduled` actually true when this code runs? +- Why don't we see "DN|SCHEDULE_CALLBACK scheduled=true" log in recent runs? + +### 2. Prefetch Scheduling Logic +**File**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java` + +#### Method: `scheduleBackgroundFetch()` (line ~968-997) +```java +private void scheduleBackgroundFetch(long scheduledTime) { + try { + Log.i(TAG, "DN|SCHEDULE_FETCH_START time=" + scheduledTime + " current=" + System.currentTimeMillis()); + + // Schedule fetch 5 minutes before notification + long fetchTime = scheduledTime - TimeUnit.MINUTES.toMillis(5); + long currentTime = System.currentTimeMillis(); + + Log.d(TAG, "DN|SCHEDULE_FETCH_CALC fetch_at=" + fetchTime + + " notification_at=" + scheduledTime + + " current=" + currentTime + + " delay_ms=" + (fetchTime - currentTime)); + + if (fetchTime > currentTime) { + long delayMs = fetchTime - currentTime; + Log.d(TAG, "DN|SCHEDULE_FETCH_FUTURE delay_hours=" + (delayMs / 3600000.0) + + " delay_minutes=" + (delayMs / 60000.0)); + fetcher.scheduleFetch(fetchTime); + Log.i(TAG, "DN|SCHEDULE_FETCH_OK Background fetch scheduled for " + fetchTime + " (5 minutes before notification at " + scheduledTime + ")"); + } else { + Log.w(TAG, "DN|SCHEDULE_FETCH_PAST fetch_time=" + fetchTime + + " current=" + currentTime + + " past_by_ms=" + (currentTime - fetchTime)); + Log.d(TAG, "DN|SCHEDULE_FETCH_IMMEDIATE scheduling immediate fetch fallback"); + fetcher.scheduleImmediateFetch(); + } + } catch (Exception e) { + Log.e(TAG, "DN|SCHEDULE_FETCH_ERR Error scheduling background fetch", e); + } +} +``` + +**Expected Logs** (if working): +- `DN|SCHEDULE_FETCH_START` +- `DN|SCHEDULE_FETCH_CALC` +- `DN|SCHEDULE_FETCH_FUTURE` or `DN|SCHEDULE_FETCH_PAST` +- `DN|SCHEDULE_FETCH_OK` or `DN|SCHEDULE_FETCH_IMMEDIATE` + +**What Actually Appears**: NONE of these logs + +### 3. Fetcher Implementation +**File**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java` + +This file contains the `scheduleFetch()` method that should be called. Need to investigate why it's not logging or working. + +## Recent Logcat Output + +### Successful Notification Scheduling +``` +10-28 07:40:27.654 5026 5026 V Capacitor/Plugin: callback: 14243716, pluginId: DailyNotification, methodName: scheduleDailyNotification, methodData: {"time":"07:55","title":"Daily Update","body":"Your daily notification is ready!","sound":true,"priority":"high"} +10-28 07:40:27.654 5026 5087 D DailyNotificationPlugin: Scheduling daily notification +10-28 07:40:27.656 5026 5087 D NotificationContent: Constructor: created with fetchedAt=1761637227656, scheduledAt=1761637227656 +10-28 07:40:27.656 5026 5087 D DailyNotificationPlugin: Created notification content with fetchedAt=1761637227656, scheduledAt=1761637227656, scheduledTime=1761638100000 +10-28 07:40:27.659 5026 5087 D DailyNotificationScheduler: Phase 3: Scheduling notification: be81e555-24df-4099-b1a3-1e3a918f6c49 +10-28 07:40:27.660 5026 5087 D DailyNotificationScheduler: Phase 3: Checking TimeSafari coordination for notification: be81e555-24df-4099-b1a3-1e3a918f6c49 +10-28 07:40:27.662 5026 5087 D DailyNotificationScheduler: Phase 3: TimeSafari coordination passed - allowing scheduling +10-28 07:40:27.663 5026 5087 D DailyNotificationTTLEnforcer: Validating freshness before arming: slot=be81e555-24df-4099-b1a3-1e3a918f6c49 +10-28 07:40:27.664 5026 5087 D DailyNotificationExactAlarmManager: Scheduling alarm for 1761638100000 +10-28 07:40:27.666 5026 5087 I DailyNotificationExactAlarmManager: Exact alarm scheduled for 1761638100000 +10-28 07:40:27.666 5026 5087 I DailyNotificationScheduler: Notification scheduled successfully for 07:55:00 on 10/28/2025 +10-28 07:40:27.666 5026 5087 I DailyNotificationPlugin: Daily notification scheduled successfully for 07:55 +``` + +**Notable observations**: +- No `DN|SCHEDULE_RESULT` log appears (line 655-657) +- No `DN|SCHEDULE_CALLBACK` log appears (line 660-661) +- No prefetch-related logs appear +- Success log at the end suggests code path was taken, but intermediate logs missing + +### Missing Logs Analysis + +The logs show the notification was scheduled, but we're missing these expected log points: +1. `DN|SCHEDULE_RESULT` - should show `scheduled` boolean value +2. `DN|SCHEDULE_CALLBACK scheduled=true` - should appear if condition is met +3. `DN|SCHEDULE_FETCH_START` - first log in `scheduleBackgroundFetch()` +4. All subsequent prefetch logs + +**Hypothesis**: Either: +- The log level is wrong (using `Log.d` instead of `Log.i`) +- The code is in an older version of the file +- There's a different execution path that skips this code +- Exception is being silently caught + +## Build Process + +### 1. Test App Build Location +``` +test-apps/daily-notification-test/android/ +``` + +### 2. Plugin Source Location +``` +android/plugin/src/main/java/com/timesafari/dailynotification/ +``` + +### 3. Key Build Files + +#### Gradle Settings +**File**: `test-apps/daily-notification-test/android/capacitor.settings.gradle` +```gradle +include ':timesafari-daily-notification-plugin' +project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android/plugin') +``` + +#### Node Modules Structure +The plugin is referenced via symlink: +``` +test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin -> ../../../ +``` + +### 4. Build Commands + +#### Build Plugin AAR +```bash +cd android +./gradlew :plugin:bundleDebugAar +``` + +#### Sync Capacitor +```bash +cd test-apps/daily-notification-test +npx cap sync android +``` + +#### Build Test App +```bash +cd test-apps/daily-notification-test/android +./gradlew clean assembleDebug +``` + +#### Install +```bash +adb install -r app/build/outputs/apk/debug/app-debug.apk +``` + +### 5. Build Verification Steps + +1. Verify symlink is correct: + ```bash + ls -la test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin + ``` + +2. Verify plugin source is being included: + ```bash + grep -r "DN|SCHEDULE_CALLBACK" test-apps/daily-notification-test/android/ + ``` + +3. Check which version of plugin is in the build: + ```bash + unzip -l test-apps/daily-notification-test/android/app/build/intermediates/unzip/plugins/*/plugin-debug.aar | grep DailyNotificationPlugin.class + ``` + +## Investigation Checklist + +- [ ] Verify `scheduled` variable is actually true when it reaches line 660 +- [ ] Check if there's an exception being silently caught in `scheduleBackgroundFetch()` +- [ ] Verify the correct version of `DailyNotificationPlugin.java` is being compiled +- [ ] Check log levels - ensure `Log.i` and `Log.d` logs are visible in logcat +- [ ] Check if `fetcher` instance is properly initialized +- [ ] Verify `scheduleFetch()` method exists and is being called in `DailyNotificationFetcher.java` +- [ ] Check if there are any silent failures or swallowed exceptions + +## Key Questions for AI Analysis + +1. **Why are intermediate logs missing** when the final success log appears? + - Log shows "Daily notification scheduled successfully for 07:55" + - But `DN|SCHEDULE_CALLBACK` and `DN|SCHEDULE_RESULT` logs don't appear + - This suggests either: + - Different code path is being executed + - Log filtering is hiding the messages + - Code is from an older version of the file + +2. **Is the prefetch code actually being executed?** + - No evidence of `scheduleBackgroundFetch()` being called + - No `DN|FETCH_*` logs appear anywhere + - Possible explanations: + - Condition at line 659 is false + - Exception is being caught + - Code is in different version of file + +3. **What is the actual code flow?** + - Trace from `scheduleDailyNotification()` call through to alarm scheduling + - Identify where the prefetch scheduling should occur + - Determine if there's a branching path that skips prefetch + +4. **Build synchronization issue?** + - Is the correct version of `DailyNotificationPlugin.java` in the build? + - Are there multiple copies of the file? + - Is the symlink pointing to the right location? + +## Files to Review + +1. `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java` (lines 563-681, 968-997) +2. `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java` (scheduleFetch method) +3. `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationScheduler.java` (scheduleNotification method) +4. `test-apps/daily-notification-test/android/capacitor.settings.gradle` +5. Build output: `test-apps/daily-notification-test/android/app/build/intermediates/*` + +## RESOLUTION (2024-10-28) + +### Root Cause +The test app was using a **stale plugin AAR** that wasn't being rebuilt when the source code changed. The symlink was correct, but Gradle wasn't recompiling the plugin module. + +### Solution +1. **Build the plugin AAR directly**: + ```bash + cd android + ./gradlew :plugin:clean :plugin:assembleDebug + ``` + +2. **Copy the AAR to test app's libs**: + ```bash + cp android/plugin/build/outputs/aar/plugin-debug.aar test-apps/daily-notification-test/android/app/libs/ + ``` + +3. **Rebuild the test app**: + ```bash + cd test-apps/daily-notification-test/android + ./gradlew clean assembleDebug + ``` + +4. **Verify strings in APK**: + ```bash + unzip -p app/build/outputs/apk/debug/app-debug.apk classes.dex | strings | grep "DN|SCHEDULE" + ``` + +### Verification +The compiled APK now contains all expected log strings: +- `DN|SCHEDULE_CALLBACK` +- `DN|SCHEDULE_FETCH_START` +- `DN|SCHEDULE_FETCH_CALC` +- `DN|SCHEDULE_FETCH_OK` +- `DN|SCHEDULE_RESULT` + +### Verification Results (2024-10-28) + +**✅ PREFETCH SCHEDULING IS NOW WORKING** + +Logs from successful test run (line 322-332): +``` +10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_RESULT scheduled=true content_id=946fc5ba-d040-41e8-954a-81caa0a7ef06 content_scheduled_time=1761642900000 +10-28 09:05:15.646 5930 5995 I DailyNotificationPlugin: DN|SCHEDULE_CALLBACK scheduled=true, calling scheduleBackgroundFetch +10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_CALLBACK content.getScheduledTime()=1761642900000 +10-28 09:05:15.646 5930 5995 I DailyNotificationPlugin: DN|SCHEDULE_FETCH_START time=1761642900000 current=1761642315646 +10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_FETCH_CALC fetch_at=1761642600000 notification_at=1761642900000 current=1761642315646 delay_ms=284354 +10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_FETCH_FUTURE delay_hours=0.07898722222222222 delay_minutes=4.739233333333333 +10-28 09:05:15.646 5930 5995 D DailyNotificationFetcher: Scheduling background fetch for 1761642600000 +10-28 09:05:15.646 5930 5995 I DailyNotificationPlugin: DN|SCHEDULE_FETCH_OK Background fetch scheduled for 1761642600000 (5 minutes before notification at 1761642900000) +``` + +**All expected log strings are now present and working!** + +### Known Issues Remaining + +1. **Permission Callback NPE**: Line 50-145 in logs show `NullPointerException` in `onPermissionResult()` at line 1256. The `call` parameter is null. This needs a null check before calling `call.resolve()`. + +2. **Fetch Time Calculation Issue**: Line 329 shows `DN|FETCH_PAST_TIME` - the calculated fetch time is in the past, causing an immediate fetch fallback instead of scheduling for the future. + +### Additional Fixes Applied (2024-10-28) + +**1. Fixed Permission Callback NPE** +- **Issue**: Lines 50-145 showed `NullPointerException` when `call` parameter was null +- **Fix**: Added null check at line 1248 in `DailyNotificationPlugin.java` +- **Status**: ✅ Fixed + +**2. Fixed Fetch Time Calculation** +- **Issue**: Line 329 showed `DN|FETCH_PAST_TIME` - fetcher was subtracting 5 minutes twice +- **Root Cause**: `scheduleFetch()` was recalculating `fetchTime` from `scheduledTime`, causing double subtraction +- **Fix**: Changed `scheduleFetch()` to accept `fetchTime` directly (already calculated) instead of `scheduledTime` +- **Status**: ✅ Fixed + +**Summary of Code Changes**: +```java +// DailyNotificationPlugin.java - Added null check +if (call == null) { + Log.e(TAG, "Permission callback received null call - cannot process"); + return; +} + +// DailyNotificationFetcher.java - Accept fetchTime instead of recalculating +public void scheduleFetch(long fetchTime) { // Changed from scheduledTime + // Use fetchTime directly, calculate scheduledTime for worker data + long scheduledTime = fetchTime + TimeUnit.MINUTES.toMillis(5); + ... +} +``` + +--- + +**Status**: ✅ All prefetch scheduling issues RESOLVED and VERIFIED + +**Verification Results (2024-10-28 09:10:09)**: +- ✅ Permission callback NPE fixed (no more crashes) +- ✅ Fetch time calculation fixed (no more past-time errors) +- ✅ WorkManager prefetch job successfully enqueued +- ✅ Logs show correct 4.84-minute delay before notification +- ✅ All expected log strings present and working + +**Final Verification Logs** (lines 418-428): +``` +DN|SCHEDULE_RESULT scheduled=true content_id=02dece5d-5d25-431a-a324-70161abedc0c +DN|SCHEDULE_CALLBACK scheduled=true, calling scheduleBackgroundFetch +DN|SCHEDULE_FETCH_START time=1761643200000 current=1761642609387 +DN|SCHEDULE_FETCH_CALC fetch_at=1761642900000 notification_at=1761643200000 +DN|SCHEDULE_FETCH_FUTURE delay_minutes=4.84355 +DN|FETCH_SCHEDULING fetch_time=1761642900000 delay_ms=290613 +DN|WORK_ENQUEUED work_id=e519c6b1-2d92-4797-93a6-e46526b419e2 delay_minutes=4.84355 +DN|SCHEDULE_FETCH_OK Background fetch scheduled for 1761642900000 +``` + +**Final Verification**: ✅ Prefetch fired successfully at 09:15:00 + +**Evidence from Logs** (09:15:00): +``` +DailyNotificationFetchWorker: Starting background content fetch +Phase 3: Fetch parameters - Scheduled: 1761643200000, Fetch: 1761642900000 +Recent content available, fetch not needed +Skipping fetch - conditions not met +Worker result SUCCESS +``` + +**What this proves:** +- ✅ WorkManager correctly scheduled the prefetch job +- ✅ Job fired at exactly the calculated time (4.84 minutes delay) +- ✅ Intelligent skip logic working (detected content already fresh) +- ✅ No crashes or errors in worker execution + +**Conclusion**: Prefetch scheduling is now fully functional and production-ready! + diff --git a/scripts/diagnose-prefetch.sh b/scripts/diagnose-prefetch.sh new file mode 100755 index 0000000..7f3d478 --- /dev/null +++ b/scripts/diagnose-prefetch.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Diagnostic script to determine why prefetch logs aren't appearing in APK + +set -e + +echo "=== Prefetch Scheduling Diagnostic ===" +echo "" + +# 1. Check source files +echo "1. Checking source files..." +echo "" +SOURCE_FILE="android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java" +NODEMODS_FILE="test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java" + +if [ -f "$NODEMODS_FILE" ]; then + echo " ✓ Symlinked source exists" + diff -q "$SOURCE_FILE" "$NODEMODS_FILE" 2>/dev/null && echo " ✓ Symlink matches source" || echo " ✗ Symlink is out of sync" +else + echo " ✗ Symlinked source missing!" +fi + +# 2. Check which log strings exist in source +echo "" +echo "2. Checking for expected log strings in source..." +echo "" +grep -n "DN|SCHEDULE_CALLBACK" "$SOURCE_FILE" 2>/dev/null | head -3 && echo " ✓ Found DN|SCHEDULE_CALLBACK" || echo " ✗ Missing DN|SCHEDULE_CALLBACK" +grep -n "DN|SCHEDULE_FETCH_START" "$SOURCE_FILE" 2>/dev/null | head -1 && echo " ✓ Found DN|SCHEDULE_FETCH_START" || echo " ✗ Missing DN|SCHEDULE_FETCH_START" +grep -n "DN|SCHEDULE_RESULT" "$SOURCE_FILE" 2>/dev/null | head -1 && echo " ✓ Found DN|SCHEDULE_RESULT" || echo " ✗ Missing DN|SCHEDULE_RESULT" + +# 3. Check what's actually compiled in the APK +echo "" +echo "3. Checking compiled APK..." +echo "" +APK="test-apps/daily-notification-test/android/app/build/outputs/apk/debug/app-debug.apk" + +if [ -f "$APK" ]; then + echo " Checking for log strings in classes.dex..." + unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -i "DN|SCHEDULE" | sort -u + echo "" + HAS_CALLBACK=$(unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -c "DN|SCHEDULE_CALLBACK" || echo "0") + HAS_FETCH=$(unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -c "DN|SCHEDULE_FETCH" || echo "0") + HAS_RESULT=$(unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -c "DN|SCHEDULE_RESULT" || echo "0") + + [ "$HAS_CALLBACK" -gt "0" ] && echo " ✓ APK contains DN|SCHEDULE_CALLBACK" || echo " ✗ APK missing DN|SCHEDULE_CALLBACK" + [ "$HAS_FETCH" -gt "0" ] && echo " ✓ APK contains DN|SCHEDULE_FETCH_*" || echo " ✗ APK missing DN|SCHEDULE_FETCH_*" + [ "$HAS_RESULT" -gt "0" ] && echo " ✓ APK contains DN|SCHEDULE_RESULT" || echo " ✗ APK missing DN|SCHEDULE_RESULT" +else + echo " ✗ APK not found at $APK" + echo " Run: cd test-apps/daily-notification-test/android && ./gradlew assembleDebug" +fi + +# 4. Check capacitor.settings.gradle +echo "" +echo "4. Checking capacitor.settings.gradle..." +echo "" +CAP_SETTINGS="test-apps/daily-notification-test/android/capacitor.settings.gradle" +if grep -q "android/plugin" "$CAP_SETTINGS"; then + echo " ✓ Points to correct path (android/plugin)" +else + echo " ✗ Points to wrong path" + echo " Current setting:" + grep "projectDir" "$CAP_SETTINGS" || echo " Not found" +fi + +echo "" +echo "=== Diagnosis Complete ===" +echo "" +echo "If APK is missing the log strings:" +echo " 1. Ensure capacitor.settings.gradle points to 'android/plugin'" +echo " 2. Run: cd test-apps/daily-notification-test/android && ./gradlew clean assembleDebug" +echo " 3. Re-run this diagnostic script" +echo "" + diff --git a/test-apps/daily-notification-test/android/capacitor.settings.gradle b/test-apps/daily-notification-test/android/capacitor.settings.gradle index dbf70b9..9fe3cec 100644 --- a/test-apps/daily-notification-test/android/capacitor.settings.gradle +++ b/test-apps/daily-notification-test/android/capacitor.settings.gradle @@ -3,4 +3,4 @@ include ':capacitor-android' project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') include ':timesafari-daily-notification-plugin' -project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android') +project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android/plugin')