[go: nahoru, domu]

blob: 080b83a1ff66bbc43caa701beb53110cea09dbd1 [file] [log] [blame]
Sean Kelley7817f412021-05-08 17:30:48 -07001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.health.services.client
18
sutterlin747627f2022-11-01 23:17:17 +000019import androidx.health.services.client.data.BatchingMode
Sean Kelleybe4255a2022-04-04 14:37:43 -070020import androidx.health.services.client.data.DataPoint
21import androidx.health.services.client.data.DataType
Sean Kelleye6ee3632021-05-10 16:13:38 -070022import androidx.health.services.client.data.ExerciseCapabilities
Sean Kelley7817f412021-05-08 17:30:48 -070023import androidx.health.services.client.data.ExerciseConfig
Jeff Gastonbcaacc82023-05-09 22:44:28 -040024import androidx.health.services.client.data.ExerciseEndReason
Sean Kelley7817f412021-05-08 17:30:48 -070025import androidx.health.services.client.data.ExerciseGoal
26import androidx.health.services.client.data.ExerciseInfo
Sean Kelleybe4255a2022-04-04 14:37:43 -070027import androidx.health.services.client.data.ExerciseState
28import androidx.health.services.client.data.ExerciseType
Scarlett Song46347962022-10-25 16:59:48 -070029import androidx.health.services.client.data.ExerciseTypeConfig
Sean Kelley7817f412021-05-08 17:30:48 -070030import androidx.health.services.client.data.ExerciseUpdate
Justin Lannin665af7f2021-09-07 17:56:57 +000031import androidx.health.services.client.data.WarmUpConfig
Sean Kelley7817f412021-05-08 17:30:48 -070032import com.google.common.util.concurrent.ListenableFuture
33import java.util.concurrent.Executor
34
Julia McClellan1f4daf42022-11-03 15:57:36 -040035@JvmDefaultWithCompatibility
Sean Kelley7817f412021-05-08 17:30:48 -070036/** Client which provides a way to subscribe to the health data of a device during an exercise. */
37public interface ExerciseClient {
38 /**
Justin Lannin665af7f2021-09-07 17:56:57 +000039 * Prepares for a new exercise.
40 *
41 * Once called, Health Services will warmup the sensors based on the [ExerciseType] and
42 * requested [DataType]s
43 *
44 * If the calling app already has an active exercise in progress or if it does not have the
45 * required permissions, then this call returns a failed future. If another app owns the active
46 * exercise then this call will succeed.
47 *
48 * Sensors available for warmup are GPS [DataType.LOCATION] and HeartRate
49 * [DataType.HEART_RATE_BPM]. Other [DataType]s requested for warmup based on exercise
50 * capabilities will be a no-op for the prepare stage.
51 *
52 * The DataType availability can be obtained through the
Sean Kelleybe4255a2022-04-04 14:37:43 -070053 * [ExerciseUpdateCallback.onAvailabilityChanged] callback. [ExerciseUpdate]s with the supported
54 * DataType [DataPoint] will also be returned in the [ExerciseState.PREPARING] state, though no
Justin Lannin665af7f2021-09-07 17:56:57 +000055 * aggregation will occur until the exercise is started.
56 *
57 * If an app is actively preparing and another app starts tracking an active exercise then the
Nagesh Pachorkardc9a67d2022-10-12 17:27:37 -070058 * preparing app should expect to receive an [ExerciseUpdate] with [ExerciseState.ENDED] along
59 * with the reason [ExerciseEndReason.AUTO_END_SUPERSEDED] to the [ExerciseUpdateCallback]
Justin Lannin665af7f2021-09-07 17:56:57 +000060 * indicating that their session has been superseded and ended. At that point no additional
61 * updates to availability or data will be sent until the app calls prepareExercise again.
62 *
Sean Kelleybe4255a2022-04-04 14:37:43 -070063 * @param configuration the [WarmUpConfig] containing the desired exercise and data types
Justin Lannin665af7f2021-09-07 17:56:57 +000064 * @return a [ListenableFuture] that completes once Health Services starts preparing the sensors
65 * or fails due to missing permissions or the app owning another active exercise.
66 */
Sean Kelleybe4255a2022-04-04 14:37:43 -070067 public fun prepareExerciseAsync(configuration: WarmUpConfig): ListenableFuture<Void>
Justin Lannin665af7f2021-09-07 17:56:57 +000068
69 /**
Sean Kelley7817f412021-05-08 17:30:48 -070070 * Starts a new exercise.
71 *
Sean Kelleye6ee3632021-05-10 16:13:38 -070072 * Once started, Health Services will begin collecting data associated with the exercise.
Sean Kelley7817f412021-05-08 17:30:48 -070073 *
Sean Kelleye6ee3632021-05-10 16:13:38 -070074 * Since Health Services only allows a single active exercise at a time, this will terminate any
Justin Lannin665af7f2021-09-07 17:56:57 +000075 * active exercise currently in progress before starting the new one. If this occurs, clients
Nagesh Pachorkardc9a67d2022-10-12 17:27:37 -070076 * can expect to receive an [ExerciseUpdate] with [ExerciseState.ENDED] along with the reason
77 * [ExerciseEndReason.AUTO_END_SUPERSEDED] to the [ExerciseUpdateCallback] indicating that their
78 * exercise has been superseded and that no additional updates will be sent. Clients can use
79 * [getCurrentExerciseInfoAsync] (described below) to check if they or another app has an active
80 * exercise in-progress.
Sean Kelley7817f412021-05-08 17:30:48 -070081 *
Nagesh Pachorkarbf893352022-11-18 11:23:27 -080082 * The exercise will be terminated and clients can expect to receive an [ExerciseUpdate] with
83 * [ExerciseState.ENDED] along with the reason [ExerciseEndReason.AUTO_END_MISSING_LISTENER]
84 * (indicating that their exercise has been automatically ended due to the lack of callback) if
85 * there is ever a five minute period where no [ExerciseUpdateCallback] is registered. A notable
86 * example is if the process with the registered [ExerciseUpdateCallback] dies and does not
87 * re-register the [ExerciseUpdateCallback] within five minutes.
Justin Lannin665af7f2021-09-07 17:56:57 +000088 *
89 * Clients should only request [ExerciseType]s, [DataType]s, goals, and auto-pause enabled that
Sean Kelley125448c2022-04-26 17:26:10 -070090 * matches the [ExerciseCapabilities] returned by [getCapabilitiesAsync] since Health Services
91 * will reject requests asking for unsupported configurations.
Justin Lannin665af7f2021-09-07 17:56:57 +000092 *
Sean Kelleybe4255a2022-04-04 14:37:43 -070093 * @param configuration the [ExerciseConfig] describing this exercise
Justin Lannin665af7f2021-09-07 17:56:57 +000094 * @return a [ListenableFuture] that completes once the exercise has been started or fails due
95 * to the application missing the required permissions or requesting metrics which are not
96 * supported for the given [ExerciseType].
Sean Kelley7817f412021-05-08 17:30:48 -070097 */
Sean Kelleybe4255a2022-04-04 14:37:43 -070098 public fun startExerciseAsync(configuration: ExerciseConfig): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -070099
100 /**
101 * Pauses the current exercise, if it is currently started.
102 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700103 * Before transitioning to [ExerciseState.USER_PAUSED], Health Services will flush and return
104 * the sensor data. While the exercise is paused, active time and cumulative metrics such as
Justin Lannin665af7f2021-09-07 17:56:57 +0000105 * distance will not accumulate. Instantaneous measurements such as speed and heart rate will
106 * continue to update if requested in the [ExerciseConfig].
Sean Kelley7817f412021-05-08 17:30:48 -0700107 *
Justin Lannin665af7f2021-09-07 17:56:57 +0000108 * Note that GPS and other sensors may be stopped when the exercise is paused in order to
109 * conserve battery. This may happen immediately, or after some time. (The exact behavior is
110 * hardware dependent.) Should this happen, access will automatically resume when the exercise
111 * is resumed.
Sean Kelley7817f412021-05-08 17:30:48 -0700112 *
113 * If the exercise is already paused then this method has no effect. If the exercise has ended
114 * then the returned future will fail.
115 *
Justin Lannin665af7f2021-09-07 17:56:57 +0000116 * @return a [ListenableFuture] that completes once the exercise has been paused or fails if the
117 * calling application does not own the active exercise.
Sean Kelley7817f412021-05-08 17:30:48 -0700118 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700119 public fun pauseExerciseAsync(): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700120
121 /**
122 * Resumes the current exercise, if it is currently paused.
123 *
124 * Once resumed active time and cumulative metrics such as distance will resume accumulating.
125 *
126 * If the exercise has been started but is not currently paused this method has no effect. If
127 * the exercise has ended then the returned future will fail.
128 *
Justin Lannin665af7f2021-09-07 17:56:57 +0000129 * @return a [ListenableFuture] that completes once the exercise has been resumed or fails if
130 * the calling application does not own the active exercise.
Sean Kelley7817f412021-05-08 17:30:48 -0700131 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700132 public fun resumeExerciseAsync(): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700133
134 /**
Justin Lannin665af7f2021-09-07 17:56:57 +0000135 * Ends the current exercise, if it has been started.
136 *
137 * Health Services will flush and then shut down the active sensors and return an
Sara Kato21530532022-05-26 17:02:30 +0000138 * [ExerciseUpdate] with [ExerciseState.ENDED] along with the reason
139 * [ExerciseEndReason.USER_END] to the [ExerciseUpdateCallback]. If the exercise has ended then
140 * this future will fail.
Sean Kelley7817f412021-05-08 17:30:48 -0700141 *
142 * No additional metrics will be produced for the exercise and any on device persisted data
143 * about the exercise will be deleted after the summary has been sent back.
Justin Lannin665af7f2021-09-07 17:56:57 +0000144 *
145 * @return a [ListenableFuture] that completes once the exercise has been ended or fails if the
146 * calling application does not own the active exercise.
Sean Kelley7817f412021-05-08 17:30:48 -0700147 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700148 public fun endExerciseAsync(): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700149
150 /**
Justin Lannin665af7f2021-09-07 17:56:57 +0000151 * Flushes the sensors for the active exercise. This call should be used sparingly and will be
152 * subject to throttling by Health Services.
153 *
154 * @return a [ListenableFuture] that completes once the flush has been completed or fails if the
155 * calling application does not own the active exercise.
156 */
Nagesh Pachorkare4331562022-09-02 14:56:34 -0700157 public fun flushAsync(): ListenableFuture<Void>
Justin Lannin665af7f2021-09-07 17:56:57 +0000158
159 /**
Sean Kelleybe4255a2022-04-04 14:37:43 -0700160 * Ends the current lap, calls [ExerciseUpdateCallback.onLapSummaryReceived] with data spanning
161 * the marked lap and starts a new lap. If the exercise supports laps this method can be called
162 * at any point after an exercise has been started and before it has been ended regardless of
163 * the exercise status.
Sean Kelley7817f412021-05-08 17:30:48 -0700164 *
165 * The metrics in the lap summary will start from either the start time of the exercise or the
166 * last time a lap was marked to the time this method is being called.
167 *
168 * If there's no exercise being tracked or if the exercise does not support laps then this
169 * future will fail.
Sean Kelleybe4255a2022-04-04 14:37:43 -0700170 *
171 * @return a [ListenableFuture] that completes once the lap has been marked successfully or
172 * fails if the calling application does not own the active exercise
Sean Kelley7817f412021-05-08 17:30:48 -0700173 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700174 public fun markLapAsync(): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700175
Justin Lannin665af7f2021-09-07 17:56:57 +0000176 /**
177 * Returns the current [ExerciseInfo].
178 *
179 * This can be used by clients to determine if they or another app already owns an active
180 * exercise being tracked by Health Services. For example, if an app is killed and it learns it
Sean Kelleybe4255a2022-04-04 14:37:43 -0700181 * owns the active exercise it can register a new [ExerciseUpdateCallback] and pick tracking up
Justin Lannin665af7f2021-09-07 17:56:57 +0000182 * from where it left off.
Sean Kelleybe4255a2022-04-04 14:37:43 -0700183 *
184 * @return a [ListenableFuture] that contains information about the current exercise or fails if
185 * the calling application does not own the active exercise
Justin Lannin665af7f2021-09-07 17:56:57 +0000186 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700187 public fun getCurrentExerciseInfoAsync(): ListenableFuture<ExerciseInfo>
Sean Kelley7817f412021-05-08 17:30:48 -0700188
189 /**
Sean Kelleybe4255a2022-04-04 14:37:43 -0700190 * Sets the callback for the current [ExerciseUpdate].
Sean Kelley7817f412021-05-08 17:30:48 -0700191 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700192 * This callback won't be called until the calling application prepares or starts an exercise.
Justin Lannin665af7f2021-09-07 17:56:57 +0000193 * It will only receive updates from exercises tracked by this app.
Sean Kelley7817f412021-05-08 17:30:48 -0700194 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700195 * If an exercise is in progress, the [ExerciseUpdateCallback] is immediately called with the
Sean Kelley7817f412021-05-08 17:30:48 -0700196 * associated [ExerciseUpdate], and subsequently whenever the state is updated or an event is
Justin Lannin665af7f2021-09-07 17:56:57 +0000197 * triggered. Health Services will cache [ExerciseUpdate]s of an active exercise that are
Sean Kelleybe4255a2022-04-04 14:37:43 -0700198 * generated while a callback is not active (for example, due to the app getting killed) and
199 * deliver them as soon as the callback is registered again. If the client fails to maintain a
200 * live [ExerciseUpdateCallback] for at least five minutes during the duration of the exercise
Justin Lannin665af7f2021-09-07 17:56:57 +0000201 * Health Services can decide to terminate the exercise automatically. If this occurs, clients
Nagesh Pachorkardc9a67d2022-10-12 17:27:37 -0700202 * can expect to receive an [ExerciseUpdate] with [ExerciseState.ENDED] along with the reason
203 * [ExerciseEndReason.AUTO_END_MISSING_LISTENER] to the [ExerciseUpdateCallback] indicating that
Sean Kelleybe4255a2022-04-04 14:37:43 -0700204 * their exercise has been automatically ended due to the lack of callback.
Sean Kelley7817f412021-05-08 17:30:48 -0700205 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700206 * Calls to the callback will be executed on the main application thread. To control where to
207 * execute the callback, see the overload taking an [Executor]. To remove the callback use
208 * [clearUpdateCallbackAsync].
209 *
210 * @param callback the [ExerciseUpdateCallback] that will receive updates from Health Services
Sean Kelley7817f412021-05-08 17:30:48 -0700211 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700212 public fun setUpdateCallback(callback: ExerciseUpdateCallback)
Sean Kelley7817f412021-05-08 17:30:48 -0700213
214 /**
Sean Kelleybe4255a2022-04-04 14:37:43 -0700215 * Calls to the callback will be executed using the specified [Executor]. To execute the
216 * callback on the main application thread use the overload without the [Executor].
217 *
218 * @param executor the [Executor] on which [callback] will be invoked
219 * @param callback the [ExerciseUpdateCallback] that will receive updates from Health Services
Sean Kelley7817f412021-05-08 17:30:48 -0700220 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700221 public fun setUpdateCallback(
222 executor: Executor,
223 callback: ExerciseUpdateCallback
224 )
Sean Kelley7817f412021-05-08 17:30:48 -0700225
226 /**
Sean Kelleybe4255a2022-04-04 14:37:43 -0700227 * Clears the callback set using [setUpdateCallback].
Sean Kelley7817f412021-05-08 17:30:48 -0700228 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700229 * If this callback is not already registered then this will be a no-op.
Justin Lannin665af7f2021-09-07 17:56:57 +0000230 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700231 * @param callback the [ExerciseUpdateCallback] to clear
232 * @return a [ListenableFuture] that completes once the callback has been cleared (or verified
Justin Lannin665af7f2021-09-07 17:56:57 +0000233 * not to be set).
Sean Kelley7817f412021-05-08 17:30:48 -0700234 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700235 public fun clearUpdateCallbackAsync(callback: ExerciseUpdateCallback): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700236
237 /**
238 * Adds an [ExerciseGoal] for an active exercise.
239 *
Sean Kelley7817f412021-05-08 17:30:48 -0700240 * Goals apply to only active exercises owned by the client, and will be invalidated once the
241 * exercise is complete.
242 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700243 * @param exerciseGoal the [ExerciseGoal] to add to this exercise
Sean Kelley7817f412021-05-08 17:30:48 -0700244 * @return a [ListenableFuture] that completes once the exercise goal has been added. This
Justin Lannin665af7f2021-09-07 17:56:57 +0000245 * returned [ListenableFuture] fails if the calling app does not own the active exercise.
Sean Kelley7817f412021-05-08 17:30:48 -0700246 */
Sean Kelleyb9f566f2022-04-25 10:24:17 -0700247 public fun addGoalToActiveExerciseAsync(exerciseGoal: ExerciseGoal<*>): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700248
249 /**
Justin Lannin665af7f2021-09-07 17:56:57 +0000250 * Removes an exercise goal for an active exercise.
251 *
252 * Takes into account equivalent milestones (i.e. milestones which are not equal but are
253 * different representation of a common milestone. e.g. milestone A for every 2kms, currently at
254 * threshold of 10kms, and milestone B for every 2kms, currently at threshold of 8kms).
255 *
Sean Kelleybe4255a2022-04-04 14:37:43 -0700256 * @param exerciseGoal the [ExerciseGoal] to remove from this exercise
Justin Lannin665af7f2021-09-07 17:56:57 +0000257 * @return a [ListenableFuture] that completes once the exercise goal has been removed. This
258 * returned [ListenableFuture] fails if the exercise is not active, and will be a no-op if
259 * [exerciseGoal] has not been added in the past.
260 */
Sean Kelleyb9f566f2022-04-25 10:24:17 -0700261 public fun removeGoalFromActiveExerciseAsync(
262 exerciseGoal: ExerciseGoal<*>
263 ): ListenableFuture<Void>
Justin Lannin665af7f2021-09-07 17:56:57 +0000264
265 /**
266 * Enables or disables auto pause/resume for the current exercise.
Sean Kelley7817f412021-05-08 17:30:48 -0700267 *
268 * @param enabled a boolean to indicate if should be enabled or disabled
Sean Kelley125448c2022-04-26 17:26:10 -0700269 * @return a [ListenableFuture] that completes once the override has completed. This returned
270 * [ListenableFuture] fails if an exercise is not active for this app.
Sean Kelley7817f412021-05-08 17:30:48 -0700271 */
Sean Kelleybe4255a2022-04-04 14:37:43 -0700272 public fun overrideAutoPauseAndResumeForActiveExerciseAsync(
273 enabled: Boolean
274 ): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700275
Justin Lannin665af7f2021-09-07 17:56:57 +0000276 /**
sutterlin747627f2022-11-01 23:17:17 +0000277 * Sets the batching mode for the current exercise.
278 *
279 * @param batchingModes [BatchingMode] overrides for exercise updates. Passing an empty set will
280 * clear all existing overrides.
281 * @return a [ListenableFuture] that completes once the override has completed. This returned
282 * [ListenableFuture] fails if an exercise is not active for this app.
283 */
284 public fun overrideBatchingModesForActiveExerciseAsync(
285 batchingModes: Set<BatchingMode>
286 ): ListenableFuture<Void>
287
288 /**
Justin Lannin665af7f2021-09-07 17:56:57 +0000289 * Returns the [ExerciseCapabilities] of this client for the device.
290 *
291 * This can be used to determine what [ExerciseType]s and [DataType]s this device supports.
292 * Clients should use the capabilities to inform their requests since Health Services will
Sean Kelleybe4255a2022-04-04 14:37:43 -0700293 * typically reject requests made for [DataType]s or features (such as auto-pause) which are not
Justin Lannin665af7f2021-09-07 17:56:57 +0000294 * enabled for the rejected [ExerciseType].
Sean Kelleybe4255a2022-04-04 14:37:43 -0700295 *
296 * @return a [ListenableFuture] containing the [ExerciseCapabilities] for this device
Justin Lannin665af7f2021-09-07 17:56:57 +0000297 */
Sean Kelley1d0bdb52022-04-23 14:53:11 -0700298 public fun getCapabilitiesAsync(): ListenableFuture<ExerciseCapabilities>
Scarlett Song46347962022-10-25 16:59:48 -0700299
300 /**
301 * Updates the configurable exercise type attributes for the current exercise.
302 *
303 * This can be used to update the configurable attributes for the ongoing exercise, as defined
304 * in [ExerciseTypeConfig]. Minimum Exercise API version for this function is 3.
305 *
306 * @param exerciseTypeConfig a configuration containing the new values for the configurable
307 * attributes
308 * @return a [ListenableFuture] that completes when the configuration has been updated.
Scarlett Song46347962022-10-25 16:59:48 -0700309 */
310 public fun updateExerciseTypeConfigAsync(
311 exerciseTypeConfig: ExerciseTypeConfig
Scarlett Songe5d808e2022-12-09 14:38:37 -0800312 ): ListenableFuture<Void>
Sean Kelley7817f412021-05-08 17:30:48 -0700313}