feat: add Locale plugin integration for automation apps - #974
Conversation
|
@Nain57, one remaining UI-organization choice to decide separately from the finalized Locale-plugin behavior: Should External Action remain a distinct Smart-scenario action, as implemented here, or should it be combined with the existing raw Intent action? I kept it separate because it gives Tasker/MacroDroid users an end-to-end friendly flow: name the signal in Klick'r, select the same name while configuring the host event, then use it as a normal automation trigger. The existing Intent action remains untouched for the developer/advanced use cases you mentioned in Discussion #949. However, since the raw Intent action is already useful and its dialog could potentially support multiple external-communication formats, I can merge this UI into it if that is the preferred long-term organization. This is the only remaining design choice from my side; the plugin surface, launch semantics, and background fallback are finalized. |
|
@Nain57 The decision remains open whether to:
|
Summary
This PR adds a user-facing Locale-plugin integration for automation hosts such as Tasker, MacroDroid, and Automate. It replaces the need for users to construct raw scenario-control intents themselves with host-native configuration screens, while also allowing Smart scenarios to send named events back to an automation host.
The detailed background, design discussion, FAQs, and the full set of demos are in Discussion #949.
Demo: External Action
Screenrecorder-2026-07-09-14-37-15-704.mp4
The video shows the intended low-friction flow: give an
External Actiona meaningful name in Klick'r, configure the matching event once in the automation app, then use it as a normal automation trigger.What this adds
Incoming scenario controls
The app now exposes two Locale setting plugins:
The configuration result follows the Locale bundle/blurb contract. The payload is JSON signed with an HMAC-SHA256 key kept in AndroidKeyStore; the receiver reconstructs and verifies the exact payload before resolving it. Missing, malformed, unsigned, or altered settings are rejected instead of allowing another local app to forge a launch/stop request.
Scenario IDs are resolved from the current database at execution time, so deleted scenarios fail safely. The executor deliberately treats launch as selecting/loading a scenario, rather than silently pressing Play: a request for an already loaded Dumb scenario is a no-op; replacing a different scenario stops the existing one and leaves the requested scenario ready for the user. For a Smart scenario with an already active screen-recording session, Klick'r can switch the selected scenario without requesting MediaProjection again.
Outgoing External Action events
Smart scenarios gain an
External Actiontype. An action carries a user-defined, non-empty name and is persisted through the normal action database, compatibility, and mapping paths. When executed, it broadcasts a Locale/TaskerREQUEST_QUERYcarrying that name as pass-through data.The event-plugin configuration screen stores the name the host should listen for. On the corresponding
QUERY_CONDITION, Klick'r returns satisfied only when the configured and fired names match. The scenario editor also offers existing names as reusable choices, so repeated signals stay consistent without exposing implementation details to the user.Android background-launch handling
MediaProjection consent cannot be shown reliably from every background state, especially on a locked device or under OEM background-launch restrictions. The receiver therefore uses the following guarded flow:
Request IDs plus an in-process tracker and small persisted hand-off store prevent delayed Android delivery, an old notification tap, or a second launch attempt from reviving stale work. The implementation also defers to the notification path when the scenario configuration UI is open, avoiding an external request silently replacing work the user is editing.
Notification permission is offered during Launch Scenario setup to support this fallback, but declining it does not block saving the automation.
Structure and compatibility
feature:external-launch, preserving the tile while giving both tile and plugin controls one shared service boundary.External Action.Validation
git diff --check upstream/master...feature/automation-triggerpasses.The hosted validation was run before removing the fork-only debug workflow and its ABI build-speed tuning from this upstream branch; the integration source under review is unchanged by that cleanup.
Status
The public plugin surface,
launchbehavior, and background-launch fallback described above are finalized. They were discussed and demonstrated in Discussion #949; this remains a draft only for upstream review before approval.The only remaining UI-organization decision is whether
External Actionshould remain distinct from the existing rawIntentaction or be combined with it. That question is isolated in a separate PR comment.