Skip to content

feat(frontend): add native alarms and voice recording - #133

Closed
gac0812 wants to merge 5 commits into
1024XEngineer:MVPfrom
gac0812:codex/frontend-native-reminders-recording
Closed

feat(frontend): add native alarms and voice recording#133
gac0812 wants to merge 5 commits into
1024XEngineer:MVPfrom
gac0812:codex/frontend-native-reminders-recording

Conversation

@gac0812

@gac0812 gac0812 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add the Android exact-alarm module, full-screen ringing UI, sound service, and schedule synchronization adapter
  • add the Android microphone recorder module and JavaScript voice-recorder adapter
  • register both local native packages through React Native and Expo config plugins
  • declare the notification, alarm, microphone, foreground-service, vibration, and location permissions required by the native flows

Why

Web APIs cannot provide reliable Android alarm delivery or the recorder contract used by the assistant. These local modules supply the native capabilities while keeping the feature layers behind typed JavaScript adapters.

Dependency

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review findings

I found five correctness and security issues in the current diff.

Validation: git diff --check passed. The local npm run check could not execute because the workspace has no usable dependency install (eslint was not executable).

}

const application = AndroidConfig.Manifest.getMainApplicationOrThrow(manifest);
application.$['android:usesCleartextTraffic'] = 'true';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: This enables cleartext traffic for the entire application, not just the intended LAN WebSocket connection. Any HTTP request made by the app can now silently downgrade to http://, which exposes credentials and data on an untrusted network. Keep cleartext narrowly scoped (or use wss:// in release builds) rather than setting the global application flag.

android:turnScreenOn="true"
android:taskAffinity=""
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"/>
<receiver

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reliability: The scheduler persists alarms in SharedPreferences, but this receiver is only registered for the explicit fire PendingIntent; there is no BOOT_COMPLETED receiver or rebuild path. Android removes AlarmManager entries on reboot, so every scheduled reminder is lost after a device restart even though its record remains persisted. Register a boot/package-replaced rebuild receiver or otherwise reschedule persisted records.

include_deleted: false,
});
if (generation !== this.loadGeneration) return;
this.deps.cache.replaceAll(schedules);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: system_schedule_ref_id is a local AlarmManager ID and is not part of the server upsert payload. Replacing the cache with the server list on bootstrap/resync therefore drops the local alarm IDs, so later edits/deletes cannot cancel existing native alarms; resync also never re-arms them. Preserve local refs while merging server entities and reconcile/reschedule alarms during bootstrap.

latitude: 31.236305,
longitude: 121.480237,
};
const initialJson = JSON.stringify(initialLocation);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: JSON.stringify output is inserted directly into an inline <script>. A user/backend-controlled address containing </script> can terminate this script and execute arbitrary JavaScript inside the WebView (with access to the React Native bridge). Escape HTML-significant characters such as </> (or pass the data through a non-script channel) before embedding it.


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
requestCode = intent == null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Android reuses one service instance for repeated starts, but these fields represent only one alarm. If two alarms fire while the first is ringing, the second onStartCommand overwrites requestCode/alarmId/alarmTitle; mediaPlayer != null and overlayView != null then suppress the second alarm, while cleanup only cancels the latest notification/record. Queue or independently track concurrent alarms instead of overwriting the active one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant