nexo/docs/linux-notification-test-guide.md
toki ee2e79b334 docs: Linux 알림 테스트 가이드 및 evidence 템플릿 추가, Windows/Linux 선행 정리 아카이브
- Windows 및 Linux 알림 선행 정리 마일스톤을 아카이브로 이동
- iOS 알림 테스트 마일스톤을 활성 milestone로 변경
- Linux 알림 테스트 가이드 및 smoke evidence 템플릿 추가
- Flutter Test Linux fixture 파일 추가 (open_channel, open_thread)
2026-06-02 10:50:27 +09:00

8.4 KiB

Linux Notification Test Guide

Last verified: 2026-06-02

This guide fixes the preflight contract for Linux notification work before a Linux test machine, distribution, desktop environment, notification daemon, or real OS notification UI evidence is available.

Do not commit private host values, device tokens, auth tokens, signing keys, runtime endpoints, user names, channel names, desktop session details that identify a private machine, or private package repository values into tracked docs. Use placeholders in examples and keep credential files in approved local or secret-store locations.

Current Repository State

  • packages/messaging_flutter/pubspec.yaml does not currently register a Linux plugin platform.
  • There is no packages/messaging_flutter/linux/ plugin scaffold and no apps/flutter-test/linux/ host scaffold in the current repository.
  • Dart already expects native notification and action channels: com.tokilabs.nexo.messaging/notifications and com.tokilabs.nexo.messaging/notification_actions.
  • The Linux bridge is therefore not implemented yet. Until it exists, local routing can only be tested through Dart unit tests or a future debug injection bridge.
  • Local routing fixtures live under apps/flutter-test/linux/Fixtures/*.json.

The first useful Linux smoke target is:

  1. Add a Linux plugin platform registration and generated host scaffold in a controlled implementation plan.
  2. Register the expected EventChannel and MethodChannel in the Linux plugin.
  3. Implement a debug-only local injection path compatible with debugSendNativeEvent.
  4. Choose a notification API path and runtime dependency strategy for the smoke.
  5. Map notification daemon action data or portal activation data into the Dart NotificationOpenedEvent contract.
  6. Collect display, click/open routing, lifecycle, and known ACK, dismiss, and inline reply gap evidence.

Platform Registration Contract

Do not add a partial Linux platform entry without the matching source and host scaffold. A future implementation plan should update these together:

flutter:
  plugin:
    platforms:
      linux:
        pluginClass: NexoMessagingPlugin

Expected source/host areas for that plan:

  • packages/messaging_flutter/linux/ for the Linux plugin implementation.
  • apps/flutter-test/linux/ for the test host scaffold generated by Flutter.
  • packages/messaging_flutter/pubspec.yaml for platform registration.
  • apps/flutter-test/README.md and package docs for smoke instructions.

The current preflight milestone documents this contract only. It does not claim Linux runtime support.

Minimum Bridge Contract

The Dart SDK expects the Linux native side to preserve these channel names:

Channel Name Direction Minimum Linux behavior
EventChannel com.tokilabs.nexo.messaging/notifications native to Dart Emit codec-safe maps for notification, open, token, clear, session, and future action-failure events.
MethodChannel com.tokilabs.nexo.messaging/notification_actions Dart to native Accept SDK action methods used by Dart without crashing the host app.

Minimum methods for the action channel:

Method Minimum preflight result Production expectation
debugSendNativeEvent Validate the argument is a map and emit it on the EventChannel. Debug/test-only injection path.
saveDeviceToken Accept and store or no-op a formatted token string without logging secrets. Store the Linux server-registration token once the platform token source is chosen.
getDeviceToken Return the last stored formatted token or null. Return the current formatted Linux server-registration token.
setAuthToken Validate required string arguments and no-op. Persist token for ACK/reply work only after storage rules are designed.
clearAuthToken Validate serverUrl and no-op. Clear persisted token for the server.
setSigningKey Validate required string arguments and no-op without persistence. Persist the signing key only after secure storage rules are designed.

Fallback boundaries:

  • Missing bridge methods should return the Flutter Linux equivalent of "not implemented", not a successful placeholder.
  • Token, auth, signing-key, ACK, dismiss, and inline reply persistence are not implied by this preflight milestone.
  • Real notification display and activation handling belong to Linux 알림 테스트 unless a smaller bridge implementation plan explicitly handles them first.

Notification API Matrix

Candidate Environment fit Strength Preflight constraint
D-Bus org.freedesktop.Notifications Common desktop notification daemon path Broad support across GNOME, KDE, XFCE, and other desktops Action callbacks and capabilities vary by daemon and session.
XDG Desktop Portal notifications Flatpak/sandbox-friendly desktops Better fit for portal-mediated desktop environments Portal availability and notification support vary by distribution and session.
libnotify wrapper Thin client around the freedesktop notification spec Simple display smoke for common desktops Callback/action support still depends on the underlying daemon.
Local debug injection only No daemon, package, or desktop requirement Deterministic EventChannel/opened-routing verification Does not prove OS display or activation.

Preflight default: use local debug injection for contract tests, and defer the D-Bus vs desktop portal vs libnotify runtime decision to the Linux 알림 테스트 milestone or a dedicated implementation plan.

Runtime Dependency Boundaries

Future Linux notification implementation should record the runtime assumptions before claiming smoke support:

  • Distribution and version, such as Ubuntu, Fedora, Debian, or another target.
  • Desktop environment and session type, such as GNOME/KDE/XFCE and X11/Wayland.
  • Notification daemon or portal availability.
  • Required build packages and runtime libraries.
  • Whether action callbacks are supported by the chosen daemon or portal path.

Tracked docs should keep these as sanitized evidence fields, not private machine configuration dumps.

Payload Mapping

Linux notification action data maps into Dart using the same stable keys as the Android, iOS, macOS, and Windows contracts:

Payload key Dart event field Notes
type type Use message for visible message notifications and opened for direct open events.
server_url server_url Required before host navigation callbacks can run.
server_id server_id Diagnostic and future server URL fallback input.
channel_id channel_id Drives onNavigateToChannel when thread routing is not selected.
root_id root_id Drives onNavigateToThread when CRT is enabled.
is_crt_enabled is_crt_enabled Accept boolean true, string "true", or string "1".
ack_id ack_id Preserve for future ACK evidence; do not invent ACK behavior.
post_id post_id Preserve for notification identity and future ACK/display evidence.
userInteraction userInteraction Set to true when a click/open path caused the event.

Routing expectation:

  • Channel fixture: server_url and channel_id are present, root_id is empty and is_crt_enabled is false, so Dart calls onNavigateToChannel.
  • Thread fixture: server_url and root_id are present and is_crt_enabled is true, so Dart calls onNavigateToThread.

Local Fixtures

Use the fixture files as sanitized payloads for a future debug injection method or for manual D-Bus/portal action data construction during smoke testing:

  • apps/flutter-test/linux/Fixtures/open_channel.json
  • apps/flutter-test/linux/Fixtures/open_thread.json

The fixtures intentionally use https://example.invalid and smoke IDs. Replace private runtime values only in local run notes or sanitized evidence.

Evidence

Use linux-notification-smoke-evidence-template.md for Linux runs. Preflight evidence should explicitly separate:

  • distribution, desktop environment, session, and daemon or portal state
  • visible display state
  • click/open routing result
  • app lifecycle state
  • ACK, dismiss, and inline reply implementation gaps

Until the scaffold, bridge, and real OS smoke exist, a valid preflight result may be "not implemented yet" with a concrete follow-up plan, rather than a failed runtime claim.