- Windows 및 Linux 알림 선행 정리 마일스톤을 아카이브로 이동 - iOS 알림 테스트 마일스톤을 활성 milestone로 변경 - Linux 알림 테스트 가이드 및 smoke evidence 템플릿 추가 - Flutter Test Linux fixture 파일 추가 (open_channel, open_thread)
169 lines
8.4 KiB
Markdown
169 lines
8.4 KiB
Markdown
# 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:
|
|
|
|
```yaml
|
|
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`](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.
|