wearos-whs: Add ExerciseTypeConfig definitions and UpdateExerciseRequest impl
1. Add ExerciseTypeConfig definitions
Main changes based on aosp/2172806:
- Rename DynamicExerciseConfig to be ExerciseTypeConfig
- Removed autopause from ExerciseTypeConfig
- Removed builder from ExerciseTypeConfig
- Make ExerciseTypeConfig nullable in ExerciseConfig
- Added factory method createGolfExerciseTypeConfig to ExerciseTypeConfig and make ExerciseTypeConfig constructor private
2. Add updateExerciseTypeConfigForActiveExercise in
IExerciseApiService.aidl, and bump up exerciseApiVersion
1->3(considering in APK we're already using version 2)
- Add UpdateExerciseTypeConfigRequest definition as impl
- Implement in ExerciseClient and ServiceBackedExerciseClient
Relnote: add factory method to create golf place tracking info exercise type config
Test: ./gradlew :health:health-services-client:assemble --info
Test: ./gradlew :health:health-services-client:test
Change-Id: I4c539e1abde8e51e65dcc82e3495f202b10282ea
diff --git a/health/health-services-client/api/1.0.0-beta02.txt b/health/health-services-client/api/1.0.0-beta02.txt
index 590e802..d65cfd6 100644
--- a/health/health-services-client/api/1.0.0-beta02.txt
+++ b/health/health-services-client/api/1.0.0-beta02.txt
@@ -17,6 +17,7 @@
method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startExerciseAsync(androidx.health.services.client.data.ExerciseConfig configuration);
+ method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig);
}
public final class ExerciseClientExtensionKt {
@@ -33,6 +34,7 @@
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
+ method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
}
public interface ExerciseUpdateCallback {
@@ -308,12 +310,17 @@
}
public final class ExerciseConfig {
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
method public java.util.Set<androidx.health.services.client.data.DataType<?,?>> getDataTypes();
method public java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> getExerciseGoals();
method public android.os.Bundle getExerciseParams();
method public androidx.health.services.client.data.ExerciseType getExerciseType();
+ method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
method public float getSwimmingPoolLengthMeters();
method public boolean isAutoPauseAndResumeEnabled();
method public boolean isGpsEnabled();
@@ -321,6 +328,7 @@
property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals;
property public final android.os.Bundle exerciseParams;
property public final androidx.health.services.client.data.ExerciseType exerciseType;
+ property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
property public final boolean isAutoPauseAndResumeEnabled;
property public final boolean isGpsEnabled;
property public final float swimmingPoolLengthMeters;
@@ -334,6 +342,7 @@
method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
+ method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsGpsEnabled(boolean isGpsEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setSwimmingPoolLengthMeters(float swimmingPoolLength);
@@ -556,6 +565,17 @@
property public final boolean supportsAutoPauseAndResume;
}
+ public final class ExerciseTypeConfig {
+ method public static androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ method public int getGolfShotTrackingPlaceInfo();
+ property public final int golfShotTrackingPlaceInfo;
+ field public static final androidx.health.services.client.data.ExerciseTypeConfig.Companion Companion;
+ }
+
+ public static final class ExerciseTypeConfig.Companion {
+ method public androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ }
+
public final class ExerciseUpdate {
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<?> dataPoint);
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<?> dataPoint);
diff --git a/health/health-services-client/api/api_lint.ignore b/health/health-services-client/api/api_lint.ignore
index 4b2826d..844c583 100644
--- a/health/health-services-client/api/api_lint.ignore
+++ b/health/health-services-client/api/api_lint.ignore
@@ -1,4 +1,8 @@
// Baseline format: 1.0
+DocumentExceptions: androidx.health.services.client.ExerciseClient#updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig):
+ Method ExerciseClient.updateExerciseTypeConfigAsync appears to be throwing kotlin.NotImplementedError; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
+
+
ExecutorRegistration: androidx.health.services.client.ExerciseClient#clearUpdateCallbackAsync(androidx.health.services.client.ExerciseUpdateCallback):
Registration methods should have overload that accepts delivery Executor: `clearUpdateCallbackAsync`
@@ -7,8 +11,6 @@
Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
InvalidNullabilityOverride: androidx.health.services.client.PassiveListenerService#onBind(android.content.Intent) parameter #0:
Invalid nullability on parameter `intent` in method `onBind`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.health.services.client.VersionApiService#onBind(android.content.Intent):
- Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
PairedRegistration: androidx.health.services.client.MeasureClient#registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<?,?>, androidx.health.services.client.MeasureCallback):
diff --git a/health/health-services-client/api/current.txt b/health/health-services-client/api/current.txt
index 590e802..d65cfd6 100644
--- a/health/health-services-client/api/current.txt
+++ b/health/health-services-client/api/current.txt
@@ -17,6 +17,7 @@
method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startExerciseAsync(androidx.health.services.client.data.ExerciseConfig configuration);
+ method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig);
}
public final class ExerciseClientExtensionKt {
@@ -33,6 +34,7 @@
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
+ method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
}
public interface ExerciseUpdateCallback {
@@ -308,12 +310,17 @@
}
public final class ExerciseConfig {
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
method public java.util.Set<androidx.health.services.client.data.DataType<?,?>> getDataTypes();
method public java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> getExerciseGoals();
method public android.os.Bundle getExerciseParams();
method public androidx.health.services.client.data.ExerciseType getExerciseType();
+ method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
method public float getSwimmingPoolLengthMeters();
method public boolean isAutoPauseAndResumeEnabled();
method public boolean isGpsEnabled();
@@ -321,6 +328,7 @@
property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals;
property public final android.os.Bundle exerciseParams;
property public final androidx.health.services.client.data.ExerciseType exerciseType;
+ property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
property public final boolean isAutoPauseAndResumeEnabled;
property public final boolean isGpsEnabled;
property public final float swimmingPoolLengthMeters;
@@ -334,6 +342,7 @@
method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
+ method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsGpsEnabled(boolean isGpsEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setSwimmingPoolLengthMeters(float swimmingPoolLength);
@@ -556,6 +565,17 @@
property public final boolean supportsAutoPauseAndResume;
}
+ public final class ExerciseTypeConfig {
+ method public static androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ method public int getGolfShotTrackingPlaceInfo();
+ property public final int golfShotTrackingPlaceInfo;
+ field public static final androidx.health.services.client.data.ExerciseTypeConfig.Companion Companion;
+ }
+
+ public static final class ExerciseTypeConfig.Companion {
+ method public androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ }
+
public final class ExerciseUpdate {
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<?> dataPoint);
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<?> dataPoint);
diff --git a/health/health-services-client/api/public_plus_experimental_1.0.0-beta02.txt b/health/health-services-client/api/public_plus_experimental_1.0.0-beta02.txt
index 590e802..d65cfd6 100644
--- a/health/health-services-client/api/public_plus_experimental_1.0.0-beta02.txt
+++ b/health/health-services-client/api/public_plus_experimental_1.0.0-beta02.txt
@@ -17,6 +17,7 @@
method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startExerciseAsync(androidx.health.services.client.data.ExerciseConfig configuration);
+ method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig);
}
public final class ExerciseClientExtensionKt {
@@ -33,6 +34,7 @@
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
+ method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
}
public interface ExerciseUpdateCallback {
@@ -308,12 +310,17 @@
}
public final class ExerciseConfig {
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
method public java.util.Set<androidx.health.services.client.data.DataType<?,?>> getDataTypes();
method public java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> getExerciseGoals();
method public android.os.Bundle getExerciseParams();
method public androidx.health.services.client.data.ExerciseType getExerciseType();
+ method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
method public float getSwimmingPoolLengthMeters();
method public boolean isAutoPauseAndResumeEnabled();
method public boolean isGpsEnabled();
@@ -321,6 +328,7 @@
property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals;
property public final android.os.Bundle exerciseParams;
property public final androidx.health.services.client.data.ExerciseType exerciseType;
+ property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
property public final boolean isAutoPauseAndResumeEnabled;
property public final boolean isGpsEnabled;
property public final float swimmingPoolLengthMeters;
@@ -334,6 +342,7 @@
method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
+ method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsGpsEnabled(boolean isGpsEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setSwimmingPoolLengthMeters(float swimmingPoolLength);
@@ -556,6 +565,17 @@
property public final boolean supportsAutoPauseAndResume;
}
+ public final class ExerciseTypeConfig {
+ method public static androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ method public int getGolfShotTrackingPlaceInfo();
+ property public final int golfShotTrackingPlaceInfo;
+ field public static final androidx.health.services.client.data.ExerciseTypeConfig.Companion Companion;
+ }
+
+ public static final class ExerciseTypeConfig.Companion {
+ method public androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ }
+
public final class ExerciseUpdate {
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<?> dataPoint);
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<?> dataPoint);
diff --git a/health/health-services-client/api/public_plus_experimental_current.txt b/health/health-services-client/api/public_plus_experimental_current.txt
index 590e802..d65cfd6 100644
--- a/health/health-services-client/api/public_plus_experimental_current.txt
+++ b/health/health-services-client/api/public_plus_experimental_current.txt
@@ -17,6 +17,7 @@
method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startExerciseAsync(androidx.health.services.client.data.ExerciseConfig configuration);
+ method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig);
}
public final class ExerciseClientExtensionKt {
@@ -33,6 +34,7 @@
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
+ method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
}
public interface ExerciseUpdateCallback {
@@ -308,12 +310,17 @@
}
public final class ExerciseConfig {
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
method public java.util.Set<androidx.health.services.client.data.DataType<?,?>> getDataTypes();
method public java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> getExerciseGoals();
method public android.os.Bundle getExerciseParams();
method public androidx.health.services.client.data.ExerciseType getExerciseType();
+ method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
method public float getSwimmingPoolLengthMeters();
method public boolean isAutoPauseAndResumeEnabled();
method public boolean isGpsEnabled();
@@ -321,6 +328,7 @@
property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals;
property public final android.os.Bundle exerciseParams;
property public final androidx.health.services.client.data.ExerciseType exerciseType;
+ property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
property public final boolean isAutoPauseAndResumeEnabled;
property public final boolean isGpsEnabled;
property public final float swimmingPoolLengthMeters;
@@ -334,6 +342,7 @@
method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
+ method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsGpsEnabled(boolean isGpsEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setSwimmingPoolLengthMeters(float swimmingPoolLength);
@@ -556,6 +565,17 @@
property public final boolean supportsAutoPauseAndResume;
}
+ public final class ExerciseTypeConfig {
+ method public static androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ method public int getGolfShotTrackingPlaceInfo();
+ property public final int golfShotTrackingPlaceInfo;
+ field public static final androidx.health.services.client.data.ExerciseTypeConfig.Companion Companion;
+ }
+
+ public static final class ExerciseTypeConfig.Companion {
+ method public androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ }
+
public final class ExerciseUpdate {
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<?> dataPoint);
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<?> dataPoint);
diff --git a/health/health-services-client/api/restricted_1.0.0-beta02.txt b/health/health-services-client/api/restricted_1.0.0-beta02.txt
index 590e802..d65cfd6 100644
--- a/health/health-services-client/api/restricted_1.0.0-beta02.txt
+++ b/health/health-services-client/api/restricted_1.0.0-beta02.txt
@@ -17,6 +17,7 @@
method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startExerciseAsync(androidx.health.services.client.data.ExerciseConfig configuration);
+ method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig);
}
public final class ExerciseClientExtensionKt {
@@ -33,6 +34,7 @@
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
+ method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
}
public interface ExerciseUpdateCallback {
@@ -308,12 +310,17 @@
}
public final class ExerciseConfig {
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
method public java.util.Set<androidx.health.services.client.data.DataType<?,?>> getDataTypes();
method public java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> getExerciseGoals();
method public android.os.Bundle getExerciseParams();
method public androidx.health.services.client.data.ExerciseType getExerciseType();
+ method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
method public float getSwimmingPoolLengthMeters();
method public boolean isAutoPauseAndResumeEnabled();
method public boolean isGpsEnabled();
@@ -321,6 +328,7 @@
property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals;
property public final android.os.Bundle exerciseParams;
property public final androidx.health.services.client.data.ExerciseType exerciseType;
+ property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
property public final boolean isAutoPauseAndResumeEnabled;
property public final boolean isGpsEnabled;
property public final float swimmingPoolLengthMeters;
@@ -334,6 +342,7 @@
method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
+ method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsGpsEnabled(boolean isGpsEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setSwimmingPoolLengthMeters(float swimmingPoolLength);
@@ -556,6 +565,17 @@
property public final boolean supportsAutoPauseAndResume;
}
+ public final class ExerciseTypeConfig {
+ method public static androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ method public int getGolfShotTrackingPlaceInfo();
+ property public final int golfShotTrackingPlaceInfo;
+ field public static final androidx.health.services.client.data.ExerciseTypeConfig.Companion Companion;
+ }
+
+ public static final class ExerciseTypeConfig.Companion {
+ method public androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ }
+
public final class ExerciseUpdate {
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<?> dataPoint);
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<?> dataPoint);
diff --git a/health/health-services-client/api/restricted_current.txt b/health/health-services-client/api/restricted_current.txt
index 590e802..d65cfd6 100644
--- a/health/health-services-client/api/restricted_current.txt
+++ b/health/health-services-client/api/restricted_current.txt
@@ -17,6 +17,7 @@
method public void setUpdateCallback(androidx.health.services.client.ExerciseUpdateCallback callback);
method public void setUpdateCallback(java.util.concurrent.Executor executor, androidx.health.services.client.ExerciseUpdateCallback callback);
method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> startExerciseAsync(androidx.health.services.client.data.ExerciseConfig configuration);
+ method public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void> updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig);
}
public final class ExerciseClientExtensionKt {
@@ -33,6 +34,7 @@
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? removeGoalFromActiveExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseGoal<?> exerciseGoal, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? resumeExercise(androidx.health.services.client.ExerciseClient, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? startExercise(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseConfig configuration, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
+ method @kotlin.jvm.Throws(exceptionClasses=android.os.RemoteException::class) public static suspend Object? updateExerciseTypeConfig(androidx.health.services.client.ExerciseClient, androidx.health.services.client.data.ExerciseTypeConfig exerciseTypeConfig, kotlin.coroutines.Continuation<? super java.lang.Void>) throws android.os.RemoteException;
}
public interface ExerciseUpdateCallback {
@@ -308,12 +310,17 @@
}
public final class ExerciseConfig {
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters, optional androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams, optional @FloatRange(from=0.0) float swimmingPoolLengthMeters);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals, optional android.os.Bundle exerciseParams);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled, optional java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
+ ctor public ExerciseConfig(androidx.health.services.client.data.ExerciseType exerciseType, java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes, boolean isAutoPauseAndResumeEnabled, boolean isGpsEnabled);
method public static androidx.health.services.client.data.ExerciseConfig.Builder builder(androidx.health.services.client.data.ExerciseType exerciseType);
method public java.util.Set<androidx.health.services.client.data.DataType<?,?>> getDataTypes();
method public java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> getExerciseGoals();
method public android.os.Bundle getExerciseParams();
method public androidx.health.services.client.data.ExerciseType getExerciseType();
+ method public androidx.health.services.client.data.ExerciseTypeConfig? getExerciseTypeConfig();
method public float getSwimmingPoolLengthMeters();
method public boolean isAutoPauseAndResumeEnabled();
method public boolean isGpsEnabled();
@@ -321,6 +328,7 @@
property public final java.util.List<androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals;
property public final android.os.Bundle exerciseParams;
property public final androidx.health.services.client.data.ExerciseType exerciseType;
+ property public final androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig;
property public final boolean isAutoPauseAndResumeEnabled;
property public final boolean isGpsEnabled;
property public final float swimmingPoolLengthMeters;
@@ -334,6 +342,7 @@
method public androidx.health.services.client.data.ExerciseConfig.Builder setDataTypes(java.util.Set<? extends androidx.health.services.client.data.DataType<?,?>> dataTypes);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseGoals(java.util.List<? extends androidx.health.services.client.data.ExerciseGoal<?>> exerciseGoals);
method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseParams(android.os.Bundle exerciseParams);
+ method public androidx.health.services.client.data.ExerciseConfig.Builder setExerciseTypeConfig(androidx.health.services.client.data.ExerciseTypeConfig? exerciseTypeConfig);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsAutoPauseAndResumeEnabled(boolean isAutoPauseAndResumeEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setIsGpsEnabled(boolean isGpsEnabled);
method public androidx.health.services.client.data.ExerciseConfig.Builder setSwimmingPoolLengthMeters(float swimmingPoolLength);
@@ -556,6 +565,17 @@
property public final boolean supportsAutoPauseAndResume;
}
+ public final class ExerciseTypeConfig {
+ method public static androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ method public int getGolfShotTrackingPlaceInfo();
+ property public final int golfShotTrackingPlaceInfo;
+ field public static final androidx.health.services.client.data.ExerciseTypeConfig.Companion Companion;
+ }
+
+ public static final class ExerciseTypeConfig.Companion {
+ method public androidx.health.services.client.data.ExerciseTypeConfig createGolfExerciseTypeConfig(int golfShotTrackingPlaceInfo);
+ }
+
public final class ExerciseUpdate {
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.IntervalDataPoint<?> dataPoint);
method public java.time.Duration getActiveDurationAtDataPoint(androidx.health.services.client.data.SampleDataPoint<?> dataPoint);
diff --git a/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/IExerciseApiService.aidl b/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/IExerciseApiService.aidl
index c4f225e..87f3b3e 100644
--- a/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/IExerciseApiService.aidl
+++ b/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/IExerciseApiService.aidl
@@ -25,12 +25,13 @@
import androidx.health.services.client.impl.request.ExerciseGoalRequest;
import androidx.health.services.client.impl.request.PrepareExerciseRequest;
import androidx.health.services.client.impl.request.StartExerciseRequest;
+import androidx.health.services.client.impl.request.UpdateExerciseTypeConfigRequest;
import androidx.health.services.client.impl.response.ExerciseCapabilitiesResponse;
/**
* Interface to make ipc calls for health services exercise api.
*
- * The next method added to the interface should use ID: 15
+ * The next method added to the interface should use ID: 17
* (this id needs to be incremented for each added method)
*
* @hide
@@ -41,7 +42,7 @@
* method is added.
*
*/
- const int API_VERSION = 1;
+ const int API_VERSION = 3;
/**
* Returns version of this AIDL interface.
@@ -127,4 +128,11 @@
/** Method to flush data metrics. */
void flushExercise(in FlushRequest request, in IStatusCallback statusCallback) = 12;
+
+ /**
+ * Handles a given request to update an exercise.
+
+ * <p>Added in API version 3.
+ */
+ void updateExerciseTypeConfigForActiveExercise(in UpdateExerciseTypeConfigRequest updateExerciseTypeConfigRequest, IStatusCallback statuscallback) = 16;
}
diff --git a/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequest.aidl b/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequest.aidl
new file mode 100644
index 0000000..3b3a016
--- /dev/null
+++ b/health/health-services-client/src/main/aidl/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequest.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.services.client.impl.request;
+
+/** @hide */
+parcelable UpdateExerciseTypeConfigRequest;
\ No newline at end of file
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt b/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt
index fd572f3..311cdcd 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt
@@ -25,6 +25,7 @@
import androidx.health.services.client.data.ExerciseState
import androidx.health.services.client.data.ExerciseEndReason
import androidx.health.services.client.data.ExerciseType
+import androidx.health.services.client.data.ExerciseTypeConfig
import androidx.health.services.client.data.ExerciseUpdate
import androidx.health.services.client.data.WarmUpConfig
import com.google.common.util.concurrent.ListenableFuture
@@ -281,4 +282,24 @@
* @return a [ListenableFuture] containing the [ExerciseCapabilities] for this device
*/
public fun getCapabilitiesAsync(): ListenableFuture<ExerciseCapabilities>
+
+ /**
+ * Updates the configurable exercise type attributes for the current exercise.
+ *
+ * This can be used to update the configurable attributes for the ongoing exercise, as defined
+ * in [ExerciseTypeConfig]. Minimum Exercise API version for this function is 3.
+ *
+ * @param exerciseTypeConfig a configuration containing the new values for the configurable
+ * attributes
+ * @return a [ListenableFuture] that completes when the configuration has been updated.
+ * @throws [NotImplementedError] if there is an existing [ExerciseClient] that has not
+ * implemented this method. Developers should use [ServiceBackedExerciseClient], which is
+ * guaranteed to have this method implemented.
+ * @see ServiceBackedExerciseClient
+ */
+ public fun updateExerciseTypeConfigAsync(
+ exerciseTypeConfig: ExerciseTypeConfig
+ ): ListenableFuture<Void> {
+ throw NotImplementedError()
+ }
}
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClientExtension.kt b/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClientExtension.kt
index 2e54b70..13106ac 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClientExtension.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClientExtension.kt
@@ -25,6 +25,7 @@
import androidx.health.services.client.data.ExerciseInfo
import androidx.health.services.client.data.ExerciseState
import androidx.health.services.client.data.ExerciseType
+import androidx.health.services.client.data.ExerciseTypeConfig
import androidx.health.services.client.data.ExerciseUpdate
import androidx.health.services.client.data.WarmUpConfig
@@ -247,4 +248,20 @@
* @throws [android.os.RemoteException] if Health Service fails to process the call
*/
@kotlin.jvm.Throws(android.os.RemoteException::class)
-public suspend fun ExerciseClient.getCapabilities() = getCapabilitiesAsync().await()
\ No newline at end of file
+public suspend fun ExerciseClient.getCapabilities() = getCapabilitiesAsync().await()
+
+/**
+ * Updates the configurable exercise type attributes for the current exercise.
+ *
+ * This can be used to update the configurable attributes for the ongoing exercise, as defined
+ * in [ExerciseTypeConfig].
+ *
+ * @param exerciseTypeConfig a configuration containing the new values for the configurable
+ * attributes
+ *
+ * @throws [android.os.RemoteException] if Health Service fails to process the call
+ */
+@kotlin.jvm.Throws(android.os.RemoteException::class)
+public suspend fun ExerciseClient.updateExerciseTypeConfig(
+ exerciseTypeConfig: ExerciseTypeConfig
+) = updateExerciseTypeConfigAsync(exerciseTypeConfig).await()
\ No newline at end of file
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseConfig.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseConfig.kt
index 57ee614..a125add 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseConfig.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseConfig.kt
@@ -39,9 +39,11 @@
* on-going exercise which can be used to pre-populate a new exercise.
* @property swimmingPoolLengthMeters length (in meters) of the swimming pool, or 0 if not relevant to
* this exercise
+ * @property exerciseTypeConfig [ExerciseTypeConfig] containing attributes which may be
+ * modified after the exercise has started
*/
@Suppress("ParcelCreator")
-class ExerciseConfig(
+class ExerciseConfig @JvmOverloads constructor(
val exerciseType: ExerciseType,
val dataTypes: Set<DataType<*, *>>,
val isAutoPauseAndResumeEnabled: Boolean,
@@ -49,6 +51,7 @@
val exerciseGoals: List<ExerciseGoal<*>> = listOf(),
val exerciseParams: Bundle = Bundle(),
@FloatRange(from = 0.0) val swimmingPoolLengthMeters: Float = SWIMMING_POOL_LENGTH_UNSPECIFIED,
+ val exerciseTypeConfig: ExerciseTypeConfig? = null
) {
internal constructor(
@@ -65,7 +68,10 @@
proto.swimmingPoolLength
} else {
SWIMMING_POOL_LENGTH_UNSPECIFIED
- }
+ },
+ if (proto.hasExerciseTypeConfig()) {
+ ExerciseTypeConfig(proto.exerciseTypeConfig)
+ } else null
)
init {
@@ -98,6 +104,7 @@
private var exerciseGoals: List<ExerciseGoal<*>> = emptyList()
private var exerciseParams: Bundle = Bundle.EMPTY
private var swimmingPoolLength: Float = SWIMMING_POOL_LENGTH_UNSPECIFIED
+ private var exerciseTypeConfig: ExerciseTypeConfig? = null
/**
* Sets the requested [DataType]s that should be tracked during this exercise. If not
@@ -171,11 +178,22 @@
/** Sets the swimming pool length (in m). */
@Suppress("MissingGetterMatchingBuilder")
- public fun setSwimmingPoolLengthMeters(swimmingPoolLength: Float): Builder {
+ fun setSwimmingPoolLengthMeters(swimmingPoolLength: Float): Builder {
this.swimmingPoolLength = swimmingPoolLength
return this
}
+ /**
+ * Sets the [ExerciseTypeConfig] which are configurable attributes for the ongoing exercise.
+ *
+ * @param exerciseTypeConfig [ExerciseTypeConfig] specifying active exercise type
+ * configurations
+ */
+ fun setExerciseTypeConfig(exerciseTypeConfig: ExerciseTypeConfig?): Builder {
+ this.exerciseTypeConfig = exerciseTypeConfig
+ return this
+ }
+
/** Returns the built [ExerciseConfig]. */
fun build(): ExerciseConfig {
return ExerciseConfig(
@@ -185,7 +203,8 @@
isGpsEnabled,
exerciseGoals,
exerciseParams,
- swimmingPoolLength
+ swimmingPoolLength,
+ exerciseTypeConfig
)
}
}
@@ -197,19 +216,24 @@
"isAutoPauseAndResumeEnabled=$isAutoPauseAndResumeEnabled, " +
"isGpsEnabled=$isGpsEnabled, " +
"exerciseGoals=$exerciseGoals, " +
- "swimmingPoolLengthMeters=$swimmingPoolLengthMeters)"
+ "swimmingPoolLengthMeters=$swimmingPoolLengthMeters, " +
+ "exerciseTypeConfig=$exerciseTypeConfig)"
- internal fun toProto(): DataProto.ExerciseConfig =
- DataProto.ExerciseConfig.newBuilder()
- .setExerciseType(exerciseType.toProto())
- .addAllDataTypes(dataTypes.filter { !it.isAggregate }.map { it.proto })
- .addAllAggregateDataTypes(dataTypes.filter { it.isAggregate }.map { it.proto })
- .setIsAutoPauseAndResumeEnabled(isAutoPauseAndResumeEnabled)
- .setIsGpsUsageEnabled(isGpsEnabled)
- .addAllExerciseGoals(exerciseGoals.map { it.proto })
- .setExerciseParams(BundlesUtil.toProto(exerciseParams))
- .setSwimmingPoolLength(swimmingPoolLengthMeters)
- .build()
+ internal fun toProto(): DataProto.ExerciseConfig {
+ val builder = DataProto.ExerciseConfig.newBuilder()
+ .setExerciseType(exerciseType.toProto())
+ .addAllDataTypes(dataTypes.filter { !it.isAggregate }.map { it.proto })
+ .addAllAggregateDataTypes(dataTypes.filter { it.isAggregate }.map { it.proto })
+ .setIsAutoPauseAndResumeEnabled(isAutoPauseAndResumeEnabled)
+ .setIsGpsUsageEnabled(isGpsEnabled)
+ .addAllExerciseGoals(exerciseGoals.map { it.proto })
+ .setExerciseParams(BundlesUtil.toProto(exerciseParams))
+ .setSwimmingPoolLength(swimmingPoolLengthMeters)
+ if (exerciseTypeConfig != null) {
+ builder.exerciseTypeConfig = exerciseTypeConfig.toProto()
+ }
+ return builder.build()
+ }
companion object {
/**
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseTypeConfig.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseTypeConfig.kt
new file mode 100644
index 0000000..3d643b7
--- /dev/null
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseTypeConfig.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.services.client.data
+
+import androidx.health.services.client.data.GolfShotTrackingPlaceInfo.Companion.toProto
+import androidx.health.services.client.proto.DataProto
+
+/**
+ * Configuration attributes for a specific exercise type that may be modified after the exercise has
+ * started.
+ *
+ * @property golfShotTrackingPlaceInfo location where user takes [DataType.GOLF_SHOT_COUNT] during
+ * [ExerciseType.GOLF] activity
+ */
+class ExerciseTypeConfig private constructor(
+ @GolfShotTrackingPlaceInfo
+ val golfShotTrackingPlaceInfo: Int = GolfShotTrackingPlaceInfo.UNSPECIFIED
+) {
+
+ internal constructor(
+ proto: DataProto.ExerciseTypeConfig
+ ) : this (
+ GolfShotTrackingPlaceInfo.fromProto(proto.golfShotTrackingPlaceInfo)
+ )
+
+ internal fun toProto(): DataProto.ExerciseTypeConfig {
+ return DataProto.ExerciseTypeConfig.newBuilder()
+ .setGolfShotTrackingPlaceInfo(golfShotTrackingPlaceInfo.toProto())
+ .build()
+ }
+
+ override fun toString(): String =
+ "ExerciseTypeConfig(golfShotTrackingPlaceInfo=$golfShotTrackingPlaceInfo)"
+
+ companion object {
+ /**
+ * Creates golf-specific exercise type configuration.
+ *
+ * @param golfShotTrackingPlaceInfo location where user takes [DataType.GOLF_SHOT_COUNT] during
+ * [ExerciseType.GOLF] activity
+ *
+ * @return an instance of [ExerciseTypeConfig] with specific [GolfShotTrackingPlaceInfo]
+ */
+ @JvmStatic
+ fun createGolfExerciseTypeConfig(
+ @GolfShotTrackingPlaceInfo golfShotTrackingPlaceInfo: Int
+ ): ExerciseTypeConfig {
+ return ExerciseTypeConfig(golfShotTrackingPlaceInfo)
+ }
+ }
+}
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/GolfShotTrackingPlaceInfo.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/GolfShotTrackingPlaceInfo.kt
new file mode 100644
index 0000000..5cf89cb
--- /dev/null
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/GolfShotTrackingPlaceInfo.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.services.client.data
+
+import androidx.annotation.IntDef
+import androidx.health.services.client.proto.DataProto
+import kotlin.annotation.AnnotationRetention.SOURCE
+
+/**
+ * The tracking information for a golf shot used in [ExerciseTypeConfig]. It is the semantic
+ * location of a user while golfing to assist golf swing activity recognition algorithms.
+ *
+ * @hide
+ */
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+ GolfShotTrackingPlaceInfo.UNSPECIFIED,
+ GolfShotTrackingPlaceInfo.FAIRWAY,
+ GolfShotTrackingPlaceInfo.PUTTING_GREEN,
+ GolfShotTrackingPlaceInfo.TEE_BOX
+)
+annotation class GolfShotTrackingPlaceInfo {
+ companion object {
+ /** The golf shot is being taken from an unknown place. */
+ const val UNSPECIFIED: Int = 0
+ /** The golf shot is being taken from the fairway. */
+ const val FAIRWAY: Int = 1
+ /** The golf shot is being taken from the putting green. */
+ const val PUTTING_GREEN: Int = 2
+ /** The golf shot is being taken from the tee box area. */
+ const val TEE_BOX: Int = 3
+
+ internal fun @receiver:GolfShotTrackingPlaceInfo Int.toProto():
+ DataProto.GolfShotTrackingPlaceInfoType =
+ when (this) {
+ FAIRWAY -> DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_FAIRWAY
+ PUTTING_GREEN ->
+ DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_PUTTING_GREEN
+ TEE_BOX -> DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_TEE_BOX
+ else -> DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_UNSPECIFIED
+ }
+
+ @GolfShotTrackingPlaceInfo
+ internal fun fromProto(proto: DataProto.GolfShotTrackingPlaceInfoType): Int =
+ when (proto) {
+ DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_PUTTING_GREEN ->
+ PUTTING_GREEN
+ DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_TEE_BOX -> TEE_BOX
+ DataProto.GolfShotTrackingPlaceInfoType.GOLF_SHOT_TRACKING_PLACE_INFO_FAIRWAY -> FAIRWAY
+ else -> UNSPECIFIED
+ }
+ }
+}
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt
index 786f636..9f92ad7 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt
@@ -27,6 +27,7 @@
import androidx.health.services.client.data.ExerciseConfig
import androidx.health.services.client.data.ExerciseGoal
import androidx.health.services.client.data.ExerciseInfo
+import androidx.health.services.client.data.ExerciseTypeConfig
import androidx.health.services.client.data.WarmUpConfig
import androidx.health.services.client.impl.IpcConstants.EXERCISE_API_BIND_ACTION
import androidx.health.services.client.impl.IpcConstants.SERVICE_PACKAGE_NAME
@@ -42,6 +43,7 @@
import androidx.health.services.client.impl.request.FlushRequest
import androidx.health.services.client.impl.request.PrepareExerciseRequest
import androidx.health.services.client.impl.request.StartExerciseRequest
+import androidx.health.services.client.impl.request.UpdateExerciseTypeConfigRequest
import com.google.common.util.concurrent.FutureCallback
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
@@ -216,6 +218,20 @@
ContextCompat.getMainExecutor(context)
)
+ override fun updateExerciseTypeConfigAsync(
+ exerciseTypeConfig: ExerciseTypeConfig
+ ): ListenableFuture<Void> {
+ return executeWithVersionCheck(
+ { service, resultFuture ->
+ service.updateExerciseTypeConfigForActiveExercise(
+ UpdateExerciseTypeConfigRequest(packageName, exerciseTypeConfig),
+ StatusCallback(resultFuture)
+ )
+ },
+ 3
+ )
+ }
+
internal companion object {
internal const val CLIENT = "HealthServicesExerciseClient"
internal val CLIENT_CONFIGURATION =
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequest.kt b/health/health-services-client/src/main/java/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequest.kt
new file mode 100644
index 0000000..584f05a
--- /dev/null
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequest.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.services.client.impl.request
+
+import android.os.Parcelable
+import androidx.annotation.RestrictTo
+import androidx.health.services.client.data.GolfShotTrackingPlaceInfo
+import androidx.health.services.client.data.ExerciseTypeConfig
+import androidx.health.services.client.data.ProtoParcelable
+import androidx.health.services.client.proto.RequestsProto
+
+/**
+ * Request for updating exercise type configuration in an [ExerciseTypeConfig].
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+class UpdateExerciseTypeConfigRequest(
+ val packageName: String,
+ val exerciseTypeConfig: ExerciseTypeConfig,
+) : ProtoParcelable<RequestsProto.UpdateExerciseTypeConfigRequest>() {
+ override val proto: RequestsProto.UpdateExerciseTypeConfigRequest =
+ RequestsProto.UpdateExerciseTypeConfigRequest.newBuilder()
+ .setPackageName(packageName)
+ .setConfig(exerciseTypeConfig.toProto())
+ .build()
+
+ companion object {
+ @JvmField
+ val CREATOR: Parcelable.Creator<UpdateExerciseTypeConfigRequest> = newCreator { bytes ->
+ val proto = RequestsProto.UpdateExerciseTypeConfigRequest.parseFrom(bytes)
+ UpdateExerciseTypeConfigRequest(
+ proto.packageName,
+ ExerciseTypeConfig.createGolfExerciseTypeConfig(
+ GolfShotTrackingPlaceInfo.fromProto(proto.config.golfShotTrackingPlaceInfo))
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/health/health-services-client/src/main/proto/data.proto b/health/health-services-client/src/main/proto/data.proto
index 420bbc6..65e2287 100644
--- a/health/health-services-client/src/main/proto/data.proto
+++ b/health/health-services-client/src/main/proto/data.proto
@@ -173,16 +173,31 @@
reserved 2 to max; // Next ID
}
+enum GolfShotTrackingPlaceInfoType {
+ GOLF_SHOT_TRACKING_PLACE_INFO_UNSPECIFIED = 0;
+ GOLF_SHOT_TRACKING_PLACE_INFO_FAIRWAY = 1;
+ GOLF_SHOT_TRACKING_PLACE_INFO_PUTTING_GREEN = 2;
+ GOLF_SHOT_TRACKING_PLACE_INFO_TEE_BOX = 3;
+ reserved 4 to max; // Next ID
+}
+
+message ExerciseTypeConfig {
+ optional GolfShotTrackingPlaceInfoType golf_shot_tracking_place_info = 1;
+ reserved 2 to max; // Next ID
+}
+
message ExerciseConfig {
optional ExerciseType exercise_type = 1;
repeated DataType data_types = 2;
repeated DataType aggregate_data_types = 3;
- optional bool is_auto_pause_and_resume_enabled = 4; // TODO(sarakato): Move to dynamicExericseConfig
+ optional bool is_auto_pause_and_resume_enabled = 4;
optional bool is_gps_usage_enabled = 5;
repeated ExerciseGoal exercise_goals = 6;
optional Bundle exercise_params = 7; // TODO(b/241015676): Deprecate
optional float swimming_pool_length = 8;
- reserved 9 to max; // Next ID
+ optional ExerciseTypeConfig exercise_type_config = 10;
+ reserved 9;
+ reserved 11 to max; // Next ID
}
message ExerciseInfo {
diff --git a/health/health-services-client/src/main/proto/requests.proto b/health/health-services-client/src/main/proto/requests.proto
index d71c3a7..39e0b7c 100644
--- a/health/health-services-client/src/main/proto/requests.proto
+++ b/health/health-services-client/src/main/proto/requests.proto
@@ -116,3 +116,9 @@
optional ExerciseConfig config = 2;
reserved 3 to max; // Next ID
}
+
+message UpdateExerciseTypeConfigRequest {
+ optional string package_name = 1;
+ optional ExerciseTypeConfig config = 2;
+ reserved 3 to max; // Next ID
+}
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/ExerciseClientTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/ExerciseClientTest.kt
index 8d2e322..41be3a0d 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/ExerciseClientTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/ExerciseClientTest.kt
@@ -34,7 +34,9 @@
import androidx.health.services.client.data.ExerciseTrackedStatus
import androidx.health.services.client.data.ExerciseType
import androidx.health.services.client.data.ExerciseTypeCapabilities
+import androidx.health.services.client.data.ExerciseTypeConfig
import androidx.health.services.client.data.ExerciseUpdate
+import androidx.health.services.client.data.GolfShotTrackingPlaceInfo
import androidx.health.services.client.data.WarmUpConfig
import androidx.health.services.client.impl.IExerciseApiService
import androidx.health.services.client.impl.IExerciseUpdateListener
@@ -51,6 +53,7 @@
import androidx.health.services.client.impl.request.FlushRequest
import androidx.health.services.client.impl.request.PrepareExerciseRequest
import androidx.health.services.client.impl.request.StartExerciseRequest
+import androidx.health.services.client.impl.request.UpdateExerciseTypeConfigRequest
import androidx.health.services.client.impl.response.AvailabilityResponse
import androidx.health.services.client.impl.response.ExerciseCapabilitiesResponse
import androidx.health.services.client.impl.response.ExerciseInfoResponse
@@ -644,6 +647,23 @@
.isEqualTo(passiveMonitoringCapabilities.toString())
}
+ @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateExerciseTypeConfigForActiveExercise() = runTest {
+ service.exerciseConfig = ExerciseConfig.builder(ExerciseType.GOLF).build()
+ val exerciseTypeConfig =
+ ExerciseTypeConfig.createGolfExerciseTypeConfig(GolfShotTrackingPlaceInfo.FAIRWAY)
+ val request =
+ UpdateExerciseTypeConfigRequest(
+ CLIENT_CONFIGURATION.servicePackageName, exerciseTypeConfig
+ )
+ val statusCallback = IStatusCallback.Default()
+
+ service.updateExerciseTypeConfigForActiveExercise(request, statusCallback)
+
+ Truth.assertThat(service.exerciseConfig?.exerciseTypeConfig).isEqualTo(exerciseTypeConfig)
+ }
+
class FakeExerciseUpdateCallback : ExerciseUpdateCallback {
val availabilities = mutableMapOf<DataType<*, *>, Availability>()
val registrationFailureThrowables = mutableListOf<Throwable>()
@@ -855,6 +875,18 @@
statusCallbackAction.invoke(statusCallback)
}
+ override fun updateExerciseTypeConfigForActiveExercise(
+ updateExerciseTypeConfigRequest: UpdateExerciseTypeConfigRequest,
+ statuscallback: IStatusCallback
+ ) {
+ val newExerciseTypeConfig = updateExerciseTypeConfigRequest.exerciseTypeConfig
+ val newExerciseConfig =
+ ExerciseConfig.builder(
+ exerciseConfig!!.exerciseType
+ ).setExerciseTypeConfig(newExerciseTypeConfig).build()
+ this.exerciseConfig = newExerciseConfig
+ }
+
fun setException() {
throwException = true
}
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseConfigTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseConfigTest.kt
index 8567fa6..c23763f 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseConfigTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseConfigTest.kt
@@ -43,6 +43,8 @@
DataTypeCondition(DISTANCE_TOTAL, 150.0, GREATER_THAN)
),
),
+ exerciseTypeConfig = ExerciseTypeConfig.createGolfExerciseTypeConfig(
+ GolfShotTrackingPlaceInfo.FAIRWAY)
).toProto()
val config = ExerciseConfig(proto)
@@ -57,6 +59,51 @@
assertThat(config.exerciseGoals[1].dataTypeCondition.dataType).isEqualTo(DISTANCE_TOTAL)
assertThat(config.exerciseGoals[1].dataTypeCondition.threshold).isEqualTo(150.0)
assertThat(config.exerciseGoals[1].dataTypeCondition.comparisonType).isEqualTo(GREATER_THAN)
+ assertThat((config.exerciseTypeConfig)?.golfShotTrackingPlaceInfo).isEqualTo(
+ GolfShotTrackingPlaceInfo.FAIRWAY)
+ }
+
+ @Test
+ fun exerciseTypeConfigNull_protoRoundTrip() {
+ val proto = ExerciseConfig(
+ ExerciseType.RUNNING,
+ setOf(LOCATION, DISTANCE_TOTAL, HEART_RATE_BPM),
+ isAutoPauseAndResumeEnabled = true,
+ isGpsEnabled = true,
+ exerciseGoals = listOf(
+ ExerciseGoal.createOneTimeGoal(
+ DataTypeCondition(DISTANCE_TOTAL, 50.0, GREATER_THAN)
+ ),
+ ExerciseGoal.createOneTimeGoal(
+ DataTypeCondition(DISTANCE_TOTAL, 150.0, GREATER_THAN)
+ ),
+ )
+ ).toProto()
+
+ val config = ExerciseConfig(proto)
+
+ assertThat(config.exerciseType).isEqualTo(ExerciseType.RUNNING)
+ assertThat(config.dataTypes).containsExactly(LOCATION, HEART_RATE_BPM, DISTANCE_TOTAL)
+ assertThat(config.isAutoPauseAndResumeEnabled).isEqualTo(true)
+ assertThat(config.isGpsEnabled).isEqualTo(true)
+ assertThat(config.exerciseGoals[0].dataTypeCondition.dataType).isEqualTo(DISTANCE_TOTAL)
+ assertThat(config.exerciseGoals[0].dataTypeCondition.threshold).isEqualTo(50.0)
+ assertThat(config.exerciseGoals[0].dataTypeCondition.comparisonType).isEqualTo(GREATER_THAN)
+ assertThat(config.exerciseGoals[1].dataTypeCondition.dataType).isEqualTo(DISTANCE_TOTAL)
+ assertThat(config.exerciseGoals[1].dataTypeCondition.threshold).isEqualTo(150.0)
+ assertThat(config.exerciseGoals[1].dataTypeCondition.comparisonType).isEqualTo(GREATER_THAN)
+ assertThat((config.exerciseTypeConfig)).isNull()
+ }
+
+ @Test
+ fun builder_exerciseTypeConfigNull() {
+ val exerciseTypeConfigNotSetExerciseConfig =
+ ExerciseConfig.builder(ExerciseType.UNKNOWN).build()
+ val setNullExerciseTypeConfigExerciseConfig =
+ ExerciseConfig.builder(ExerciseType.UNKNOWN).setExerciseTypeConfig(null).build()
+
+ assertThat(exerciseTypeConfigNotSetExerciseConfig.exerciseTypeConfig).isNull()
+ assertThat(setNullExerciseTypeConfigExerciseConfig.exerciseTypeConfig).isNull()
}
@Test
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseTypeConfigTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseTypeConfigTest.kt
new file mode 100644
index 0000000..10cf21d
--- /dev/null
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseTypeConfigTest.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.services.client.data
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class ExerciseTypeConfigTest {
+ @Test
+ fun protoRoundTrip() {
+ val proto = ExerciseTypeConfig.createGolfExerciseTypeConfig(
+ GolfShotTrackingPlaceInfo.FAIRWAY).toProto()
+ val config = ExerciseTypeConfig(proto)
+
+ assertThat(config.golfShotTrackingPlaceInfo).isEqualTo(GolfShotTrackingPlaceInfo.FAIRWAY)
+ }
+
+ @Test
+ fun createGolfExerciseTypeConfigFromFactoryMethod() {
+ val golfExerciseStyleConfig = ExerciseTypeConfig.createGolfExerciseTypeConfig(
+ GolfShotTrackingPlaceInfo.FAIRWAY)
+
+ assertThat(golfExerciseStyleConfig.golfShotTrackingPlaceInfo).isEqualTo(
+ GolfShotTrackingPlaceInfo.FAIRWAY)
+ }
+}
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseUpdateTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseUpdateTest.kt
index e5c0a69..b4b0537 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseUpdateTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/data/ExerciseUpdateTest.kt
@@ -59,9 +59,12 @@
exerciseConfig = ExerciseConfig(
WALKING,
setOf(CALORIES_TOTAL),
- isAutoPauseAndResumeEnabled = true,
+ isAutoPauseAndResumeEnabled = false,
isGpsEnabled = false,
- exerciseGoals = listOf(goal)
+ exerciseGoals = listOf(goal),
+ exerciseTypeConfig = ExerciseTypeConfig.createGolfExerciseTypeConfig(
+ GolfShotTrackingPlaceInfo.FAIRWAY
+ )
),
activeDurationCheckpoint = ActiveDurationCheckpoint(42.instant(), 30.duration()),
updateDurationFromBoot = 42.duration(),
@@ -81,7 +84,62 @@
.isEqualTo(CALORIES_TOTAL)
assertThat(markerSummary.achievedGoal.dataTypeCondition.dataType).isEqualTo(CALORIES_TOTAL)
assertThat(update.exerciseConfig!!.exerciseType).isEqualTo(WALKING)
+ assertThat(
+ update.exerciseConfig!!.exerciseTypeConfig!!.golfShotTrackingPlaceInfo).isEqualTo(
+ GolfShotTrackingPlaceInfo.FAIRWAY)
assertThat(update.activeDurationCheckpoint!!.activeDuration).isEqualTo(30.duration())
assertThat(update.exerciseStateInfo.state).isEqualTo(ExerciseState.ACTIVE)
}
-}
\ No newline at end of file
+
+ @Test
+ fun exerciseTypeConfigNull_protoRoundTrip() {
+ val goal = createOneTimeGoal(
+ DataTypeCondition(CALORIES_TOTAL, 125.0, GREATER_THAN_OR_EQUAL)
+ )
+ val proto = ExerciseUpdate(
+ latestMetrics = DataPointContainer(
+ listOf(DataPoints.calories(130.0, 15.duration(), 35.duration()))
+ ),
+ latestAchievedGoals = setOf(goal),
+ latestMilestoneMarkerSummaries = setOf(
+ MilestoneMarkerSummary(
+ 15.instant(),
+ 40.instant(),
+ 20.duration(),
+ goal,
+ DataPointContainer(
+ listOf(DataPoints.calories(130.0, 15.duration(), 35.duration()))
+ )
+ )
+ ),
+ exerciseStateInfo = ExerciseStateInfo(ExerciseState.ACTIVE, ExerciseEndReason.UNKNOWN),
+ exerciseConfig = ExerciseConfig(
+ WALKING,
+ setOf(CALORIES_TOTAL),
+ isAutoPauseAndResumeEnabled = false,
+ isGpsEnabled = false,
+ exerciseGoals = listOf(goal),
+ ),
+ activeDurationCheckpoint = ActiveDurationCheckpoint(42.instant(), 30.duration()),
+ updateDurationFromBoot = 42.duration(),
+ startTime = 10.instant()
+ ).proto
+
+ val update = ExerciseUpdate(proto)
+
+ val caloriesDataPoint = update.latestMetrics.getData(DataType.CALORIES).first()
+ val markerSummary = update.latestMilestoneMarkerSummaries.first()
+ assertThat(update.startTime).isEqualTo(10.instant())
+ assertThat(update.getUpdateDurationFromBoot()).isEqualTo(42.duration())
+ assertThat(caloriesDataPoint.value).isEqualTo(130.0)
+ assertThat(caloriesDataPoint.startDurationFromBoot).isEqualTo(15.duration())
+ assertThat(caloriesDataPoint.endDurationFromBoot).isEqualTo(35.duration())
+ assertThat(update.latestAchievedGoals.first().dataTypeCondition.dataType)
+ .isEqualTo(CALORIES_TOTAL)
+ assertThat(markerSummary.achievedGoal.dataTypeCondition.dataType).isEqualTo(CALORIES_TOTAL)
+ assertThat(update.exerciseConfig!!.exerciseType).isEqualTo(WALKING)
+ assertThat(update.exerciseConfig!!.exerciseTypeConfig).isNull()
+ assertThat(update.activeDurationCheckpoint!!.activeDuration).isEqualTo(30.duration())
+ assertThat(update.exerciseStateInfo.state).isEqualTo(ExerciseState.ACTIVE)
+ }
+}
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
index 32e90cf..b519939 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
@@ -31,6 +31,8 @@
import androidx.health.services.client.data.ExerciseType
import androidx.health.services.client.data.ExerciseUpdate
import androidx.health.services.client.data.WarmUpConfig
+import androidx.health.services.client.data.ExerciseTypeConfig
+import androidx.health.services.client.data.GolfShotTrackingPlaceInfo
import androidx.health.services.client.impl.event.ExerciseUpdateListenerEvent
import androidx.health.services.client.impl.internal.IExerciseInfoCallback
import androidx.health.services.client.impl.internal.IStatusCallback
@@ -41,6 +43,7 @@
import androidx.health.services.client.impl.request.FlushRequest
import androidx.health.services.client.impl.request.PrepareExerciseRequest
import androidx.health.services.client.impl.request.StartExerciseRequest
+import androidx.health.services.client.impl.request.UpdateExerciseTypeConfigRequest
import androidx.health.services.client.impl.response.AvailabilityResponse
import androidx.health.services.client.impl.response.ExerciseCapabilitiesResponse
import androidx.test.core.app.ApplicationProvider
@@ -107,7 +110,7 @@
ExerciseType.WALKING,
setOf(HEART_RATE_BPM),
isAutoPauseAndResumeEnabled = false,
- isGpsEnabled = false
+ isGpsEnabled = false,
)
val availabilityEvent = ExerciseUpdateListenerEvent.createAvailabilityUpdateEvent(
AvailabilityResponse(HEART_RATE_BPM, ACQUIRING)
@@ -171,6 +174,34 @@
}
@Test
+ fun withExerciseTypeConfig_statsAndSample_startExercise() {
+ val exerciseConfig = ExerciseConfig(
+ ExerciseType.GOLF,
+ setOf(HEART_RATE_BPM, HEART_RATE_BPM_STATS),
+ isAutoPauseAndResumeEnabled = false,
+ isGpsEnabled = false,
+ exerciseTypeConfig = ExerciseTypeConfig.createGolfExerciseTypeConfig(
+ GolfShotTrackingPlaceInfo.FAIRWAY
+ )
+ )
+ val availabilityEvent = ExerciseUpdateListenerEvent.createAvailabilityUpdateEvent(
+ // Currently the proto form of HEART_RATE_BPM and HEART_RATE_BPM_STATS is identical. The
+ // APK doesn't know about _STATS, so pass the sample type to mimic that behavior.
+ AvailabilityResponse(HEART_RATE_BPM, ACQUIRING)
+ )
+ client.setUpdateCallback(callback)
+ client.startExerciseAsync(exerciseConfig)
+ shadowOf(getMainLooper()).idle()
+
+ fakeService.listener!!.onExerciseUpdateListenerEvent(availabilityEvent)
+ shadowOf(getMainLooper()).idle()
+
+ // When both the sample type and stat type are requested, both should be notified
+ assertThat(callback.availabilities).containsEntry(HEART_RATE_BPM, ACQUIRING)
+ assertThat(callback.availabilities).containsEntry(HEART_RATE_BPM_STATS, ACQUIRING)
+ }
+
+ @Test
fun dataTypeInAvailabilityCallbackShouldMatchRequested_justSampleType_prepare() {
val warmUpConfig = WarmUpConfig(
ExerciseType.WALKING,
@@ -302,5 +333,12 @@
override fun flushExercise(request: FlushRequest?, statusCallback: IStatusCallback?) {
throw NotImplementedError()
}
+
+ override fun updateExerciseTypeConfigForActiveExercise(
+ updateExerciseTypeConfigRequest: UpdateExerciseTypeConfigRequest?,
+ statuscallback: IStatusCallback?
+ ) {
+ throw NotImplementedError()
+ }
}
-}
\ No newline at end of file
+}
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequestTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequestTest.kt
new file mode 100644
index 0000000..1e2a23c
--- /dev/null
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/impl/request/UpdateExerciseTypeConfigRequestTest.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.services.client.impl.request
+
+import android.os.Parcel
+import androidx.health.services.client.data.ExerciseTypeConfig
+import androidx.health.services.client.data.GolfShotTrackingPlaceInfo
+import com.google.common.truth.Truth
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class UpdateExerciseTypeConfigRequestTest {
+ @Test
+ fun parcelableRoundTrip() {
+ val request =
+ UpdateExerciseTypeConfigRequest(
+ "package",
+ ExerciseTypeConfig.createGolfExerciseTypeConfig(GolfShotTrackingPlaceInfo.TEE_BOX)
+ )
+ val parcel = Parcel.obtain()
+
+ request.writeToParcel(parcel, 0)
+ parcel.setDataPosition(0)
+ val fromParcel = UpdateExerciseTypeConfigRequest.CREATOR.createFromParcel(parcel)
+
+ Truth.assertThat(request).isEqualTo(fromParcel)
+ }
+}
\ No newline at end of file