-
-
Notifications
You must be signed in to change notification settings - Fork 37.6k
Add live activity token retention, notify usage and clean up cycle to mobile_app #172928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
bgoncal
wants to merge
71
commits into
home-assistant:dev
Choose a base branch
from
bgoncal:live-activity-last-mile
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 56 commits
Commits
Show all changes
71 commits
Select commit
Hold shift + click to select a range
7d4713a
Add iOS Live Activity webhook handlers to mobile_app integration
rwarner e377da7
Use constants for event names and add EventOrigin.remote
rwarner 14a6987
Address Copilot review: Inclusive validation and token cleanup
rwarner 3d7ea81
Wire up notify.py to route Live Activity pushes through APNs relay
rwarner 3f6346d
Simplify Live Activity routing — use FCM native liveActivityToken
rwarner d1163a5
Address Copilot feedback: validate tag type and use constants in events
rwarner d299519
Tighten input validation for Live Activity fields
rwarner b76e405
Address Copilot review: use ATTR_WEBHOOK_ID in events, validate dismi…
rwarner d9df34f
Require non-empty tag in update_live_activity_token webhook schema
rwarner ecbb296
Use live_update: true instead of live_activity: true for iOS Live Act…
rwarner a16c8c9
Remove unused bus events and supports_live_activities helper; simplif…
rwarner 336c64b
Rename live activity webhook tag field from 'tag' to 'live_activity_tag'
rwarner 023065f
Align webhook type names with iOS companion app
rwarner 23ff061
Remove unused ATTR_WEBHOOK_ID import from webhook.py
rwarner 61a609b
Fix test_init.py to use renamed webhook type and tag field
rwarner d5e8477
Add comments clarifying live_update vs live_activity naming
rwarner 1337547
Address edenhaus review comments on Live Activity code
rwarner df217bd
Use cv.string for live activity webhook schemas
rwarner 9d9ef58
Fix docstring indentation in test_notify.py after merge conflict reso…
rwarner a1a6db3
Rename live activity webhooks to drop mobile_app_ prefix
rwarner d44727e
Fix prek formatting: remove unused import, sort imports, wrap long line
rwarner eb478d4
Fix live activity token storage format and stale webhook type in tests
rwarner 978d802
mobile_app: simplify live activity comments and docstrings
rwarner 1437794
mobile_app: restore websocket channel comment in SCHEMA_APP_DATA
rwarner 25340ac
mobile_app: persist live activity tokens across restarts with TTL cle…
rwarner 883f1f8
Merge upstream/dev into feat/ios-live-activity
rwarner b0cb713
mobile_app: fold live activity tokens into existing store
rwarner 16fde1c
mobile_app: fix pylint hass-use-runtime-data in savable_state
rwarner 83ee21a
mobile_app: fix import order in test_notify
rwarner e5ae0fa
mobile_app: clean up live activity tokens on remove, not unload
rwarner 983ed24
mobile_app: add store migration for live_activity_tokens (v1 → v2)
rwarner 0ec8f4e
mobile_app: remove duplicate condition in live activity token filter
rwarner 0f092eb
mobile_app: save store and schedule cleanup on startup for live activ…
rwarner 917a4fc
mobile_app: use direct indexing where keys are guaranteed to exist
rwarner 8c85dbf
mobile_app: remove eager token cleanup from notify, rely on cleanup task
rwarner fccb524
Merge upstream/dev into branch
rwarner bbf2bfe
mobile_app: fix ruff formatting — line length and import order
rwarner 8b41416
mobile_app: drop unnecessary delay floor in token cleanup scheduling
rwarner 0eea88e
mobile_app: reuse cleanup function at startup instead of duplicating it
rwarner c4f85ec
mobile_app: use async_call_later to schedule live activity token cleanup
rwarner 0d00b7f
mobile_app: restart live activity token cleanup when a token is added
rwarner 4926cec
mobile_app: index live activity token stored_at directly
rwarner 78b5f66
mobile_app: debounce live activity token store writes
rwarner 1c98aeb
mobile_app: bump store minor version instead of major for the new field
rwarner 3660474
Merge remote-tracking branch 'upstream/dev' into feat/ios-live-activity
rwarner 3afe179
Merge branch 'dev' into feat/ios-live-activity
edenhaus 4227077
Restructure live activty
edenhaus 94b4a8d
Refactor tests
edenhaus 334f24b
Apply suggestions from code review
edenhaus 3097854
Rename variable
edenhaus 135cd18
mobile_app: translate flat Live Activity payload and end via clear_no…
rwarner a7f2052
mobile_app: address review feedback for live activities
rwarner b7ffeac
mobile_app: alphabetize ATTR_TOKEN import in webhook.py
rwarner 237a415
Add live activity token retention, notify usage and clean up cycle to…
bgoncal d51de14
Document live activity push routing
bgoncal 7b6e08a
Merge branch 'dev' into live-activity-last-mile
bgoncal 1776af6
Clarify ActivityKit routing comments
bgoncal e21b629
Improve naming and add comments
bgoncal de47f7b
Rename live activity tag constant
bgoncal ff5de45
Move live activity token storage comment
bgoncal 9e96478
Separate live activity push-to-start token key
bgoncal d057e14
Move live activity helpers into module
bgoncal 9f2f7b5
Clarify live activity cleanup naming
bgoncal 830cc39
Remove redundant live activity comment
bgoncal b749ac8
Move Live Activity related code to separate files and folder
bgoncal ab773c5
Keep remote notification sending generic
bgoncal b9221f8
Address live activity review comments
bgoncal ecff7fa
Merge branch 'dev' into live-activity-last-mile
bgoncal 8f34c9e
Update __init__.py
bgoncal 3f8977d
Update const.py
bgoncal ec936a0
Fix ATTR
bgoncal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| """Live Activity push token lifecycle: expiry-driven cleanup loop.""" | ||
| # pylint: disable=home-assistant-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern | ||
|
|
||
| from datetime import datetime | ||
|
|
||
| from homeassistant.core import HomeAssistant, callback | ||
| from homeassistant.helpers.event import async_call_later | ||
| from homeassistant.util import dt as dt_util | ||
|
|
||
| from .const import ATTR_EXPIRES_AT, DATA_LIVE_ACTIVITY_TOKENS, DATA_STORE, DOMAIN | ||
| from .helpers import savable_state | ||
|
|
||
|
|
||
| @callback | ||
| def async_schedule_next_cleanup(hass: HomeAssistant) -> None: | ||
| """Schedule a sweep for the earliest token expiry. | ||
|
|
||
| Only call when no sweep is already in flight. The invariant is: tokens | ||
| non-empty ⟹ sweep scheduled. So the two safe call sites are (1) the | ||
| webhook that added the first token (tokens was empty beforehand) and | ||
| (2) the tail of a sweep that found surviving tokens (its own timer | ||
| just fired). | ||
| """ | ||
| tokens = hass.data[DOMAIN][DATA_LIVE_ACTIVITY_TOKENS] | ||
| earliest_expires_at = min( | ||
| ( | ||
| token[ATTR_EXPIRES_AT] | ||
| for device_tokens in tokens.values() | ||
| for token in device_tokens.values() | ||
| ), | ||
| default=None, | ||
| ) | ||
| if earliest_expires_at is None: | ||
| return | ||
|
|
||
| delay = earliest_expires_at - dt_util.utcnow().timestamp() | ||
|
|
||
| async def run_cleanup(_now: datetime) -> None: | ||
| await async_cleanup_expired_tokens(hass) | ||
|
|
||
| async_call_later(hass, delay, run_cleanup) | ||
|
|
||
|
|
||
| async def async_cleanup_expired_tokens(hass: HomeAssistant) -> None: | ||
| """Remove expired tokens and reschedule the next sweep at the earliest expiry. | ||
|
|
||
| Runs as a one-shot callback scheduled by ``async_schedule_next_cleanup``. After | ||
| sweeping, if any tokens remain it calls ``async_schedule_next_cleanup`` again to | ||
| queue the next sweep — this self-rescheduling chain is what "the loop" refers to. | ||
| When tokens are empty no further sweep is scheduled; the chain restarts the next | ||
| time the webhook stores a token into an empty store. | ||
| """ | ||
| now = dt_util.utcnow().timestamp() | ||
| tokens = hass.data[DOMAIN][DATA_LIVE_ACTIVITY_TOKENS] | ||
| changed = False | ||
|
|
||
| for webhook_id in list(tokens): | ||
| device_tokens = tokens[webhook_id] | ||
| for tag, data in list(device_tokens.items()): | ||
| if data[ATTR_EXPIRES_AT] <= now: | ||
| del device_tokens[tag] | ||
| changed = True | ||
| if not device_tokens: | ||
| del tokens[webhook_id] | ||
| changed = True | ||
|
|
||
| if tokens: | ||
| async_schedule_next_cleanup(hass) | ||
|
|
||
| if changed: | ||
| await hass.data[DOMAIN][DATA_STORE].async_save(savable_state(hass)) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.