Add data logging delivery to companion apps - #37
Open
neelts wants to merge 1 commit into
Open
Conversation
Data logging sessions of watchapps now get to companion apps. The server sends batches and the session-finish event over the bound listener service (new DATA_LOG_RECEIVED / DATA_LOG_SESSION_FINISHED actions). A client overrides onDataLogReceived() / onDataLogSessionFinished() and stores the data. The Ack/Nack result makes the delivery safe. The companion sends Ack only after it stored the data. So the Pebble app knows if it can discard the data or must send it again. An old client library answers with an empty bundle. That decodes as ReceiveResult.Unknown.
|
This does seem to cover my use-case at first glance, yes. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #1.
Problem
A watchapp can record data offline with
data_logging_create()/data_logging_log(). The watchspools the data to storage and sends it when the phone is connected. But PebbleKit2 has no API that
lets a companion app receive this data. The current Pebble app drains third-party sessions off the
watch and drops the data (see coredevices/mobileapp#292, which was redirected here).
Change
The server sends the data over the existing bound listener service, as two new actions on the
generic bundle protocol. There are no AIDL changes. Old and new libraries stay compatible.
DataLogSession(common-api):tag+ starttimestamp+itemSize. The watchapp UUID, thetag and the timestamp identify a session. Two recordings with the same tag stay distinct.
BasePebbleListenerService.onDataLogReceived(watchappUUID, session, data, itemsLeft, watch): ReceiveResultandonDataLogSessionFinished(watchappUUID, session, watch): ReceiveResult.BaseJavaPebbleListenerServicehas callback-style wrappers.PebbleListenerConnector.sendOnDataLogReceived()/sendOnDataLogSessionFinished().Design notes:
data.size / session.itemSizeitems). Alarge offline spool drains without a binder round-trip for each item. The contract requires whole
items, sequential batches for each session, and at most 100 KB for one call (binder limit).
Ackonly after it stored the data.On
Nack,Unknownornullthe server keeps the data and sends it again later, a limitednumber of times; then it discards the data. An old client library answers the unknown action with
an empty bundle. That decodes as
ReceiveResult.Unknown, so the server can tell "old library"from "stored". Companions must store batches idempotently, so a retry is always safe.
itemSize <= 0, split items)instead of crashing. Binder failures (for example
TransactionTooLargeException) map tonull.The Java wrappers answer
Nackwhen the responder is not called in 30 seconds, so a companionbug cannot stall the server. The new connector methods have default implementations, so existing
PebbleListenerConnectorimplementations stay source and binary compatible.connector also outside the app opened/closed window. The bind operation wakes the companion app.
Open design questions
DefaultPebbleAndroidAppPicker) also filters data log delivery. With twoPebble apps installed, the auto-selected app can differ from the app that holds the watch
connection, and delivery is then silently rejected. Messages have the same limitation today.
UniversalRequestResponse.requestsuspends with no binder death watch and no timeout, so akilled client process can stall a server coroutine. This also exists for messages; background
data log delivery makes it more likely. A
linkToDeathinSuspendingBindingConnectionwouldfix both.
transport-scoped and not usable as identity. Two sessions with the same tag made in the same
second are not distinguishable.
Testing
failure handling, responder timeout, default implementations) come from it.
coredevices/mobileapp (successor of #292). Then I test the full path with a real watchapp: a swim
tracker records with phone Bluetooth off, and the spool arrives on reconnect.
@matejdro this implements #1 and I am happy to adjust the API shape.
@kescherCode does this cover your use case?
@Fauxmage this is the API that mobileapp#201 needed.
@sjp4 FYI, the matching mobileapp server side comes as a follow-up PR.
Sorry for mass-tagging 😅, I'm a simple man who really wants to track their swims 🏊