diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml
index cfcfc004cf..1e8e7e3209 100644
--- a/play-services-core/src/main/AndroidManifest.xml
+++ b/play-services-core/src/main/AndroidManifest.xml
@@ -1087,7 +1087,6 @@
-
diff --git a/play-services-fitness/core/src/main/AndroidManifest.xml b/play-services-fitness/core/src/main/AndroidManifest.xml
index 161741daa0..ab5b28aadb 100644
--- a/play-services-fitness/core/src/main/AndroidManifest.xml
+++ b/play-services-fitness/core/src/main/AndroidManifest.xml
@@ -33,5 +33,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/config/FitConfigBroker.kt b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/config/FitConfigBroker.kt
index 99cb3819c2..a054bc0060 100644
--- a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/config/FitConfigBroker.kt
+++ b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/config/FitConfigBroker.kt
@@ -5,10 +5,12 @@
package com.google.android.gms.fitness.service.config
+import FITNESS_FEATURES
import android.os.Parcel
import android.util.Log
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.Status
+import com.google.android.gms.common.internal.ConnectionInfo
import com.google.android.gms.common.internal.GetServiceRequest
import com.google.android.gms.common.internal.IGmsCallbacks
import com.google.android.gms.fitness.internal.IGoogleFitConfigApi
@@ -23,7 +25,10 @@ private const val TAG = "FitConfigBroker"
class FitConfigBroker : BaseService(TAG, GmsService.FITNESS_CONFIG) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
- callback.onPostInitComplete(CommonStatusCodes.SUCCESS, FitConfigBrokerImpl(), null)
+ callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitConfigBrokerImpl(),
+ ConnectionInfo().apply {
+ features = FITNESS_FEATURES
+ })
}
}
diff --git a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/history/FitHistoryBroker.kt b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/history/FitHistoryBroker.kt
index 349f48b395..9be378e2ee 100644
--- a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/history/FitHistoryBroker.kt
+++ b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/history/FitHistoryBroker.kt
@@ -5,10 +5,12 @@
package com.google.android.gms.fitness.service.history
+import FITNESS_FEATURES
import android.os.Bundle
import android.os.Parcel
import android.util.Log
import com.google.android.gms.common.api.CommonStatusCodes
+import com.google.android.gms.common.internal.ConnectionInfo
import com.google.android.gms.common.internal.GetServiceRequest
import com.google.android.gms.common.internal.IGmsCallbacks
import com.google.android.gms.fitness.internal.IGoogleFitHistoryApi
@@ -34,7 +36,10 @@ private const val TAG = "FitHistoryBroker"
class FitHistoryBroker : BaseService(TAG, GmsService.FITNESS_HISTORY) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
- callback.onPostInitComplete(CommonStatusCodes.SUCCESS, FitHistoryBrokerImpl().asBinder(), Bundle())
+ callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitHistoryBrokerImpl().asBinder(),
+ ConnectionInfo().apply {
+ features = FITNESS_FEATURES
+ })
}
}
diff --git a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/recording/FitRecordingBroker.kt b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/recording/FitRecordingBroker.kt
new file mode 100644
index 0000000000..cd8347b602
--- /dev/null
+++ b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/recording/FitRecordingBroker.kt
@@ -0,0 +1,55 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.service.recording
+
+import FITNESS_FEATURES
+import android.util.Log
+import com.google.android.gms.common.api.CommonStatusCodes
+import com.google.android.gms.common.api.Status
+import com.google.android.gms.common.internal.ConnectionInfo
+import com.google.android.gms.common.internal.GetServiceRequest
+import com.google.android.gms.common.internal.IGmsCallbacks
+import com.google.android.gms.fitness.data.Subscription
+import com.google.android.gms.fitness.internal.IGoogleFitRecordingApi
+import com.google.android.gms.fitness.request.ListSubscriptionsRequest
+import com.google.android.gms.fitness.request.SubscribeRequest
+import com.google.android.gms.fitness.request.UnsubscribeRequest
+import com.google.android.gms.fitness.result.ListSubscriptionsResult
+import org.microg.gms.BaseService
+import org.microg.gms.common.GmsService
+
+private const val TAG = "FitRecordingBroker"
+
+class FitRecordingBroker : BaseService(TAG, GmsService.FITNESS_RECORDING) {
+
+ override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
+ Log.d(TAG, "handleServiceRequest: account: ${request.account.name} packageName: ${request.packageName}")
+ callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitRecordingBrokerImpl(),
+ ConnectionInfo().apply {
+ features = FITNESS_FEATURES
+ })
+ }
+
+}
+
+class FitRecordingBrokerImpl() : IGoogleFitRecordingApi.Stub() {
+
+ override fun subscribe(request: SubscribeRequest) {
+ Log.d(TAG, "Not yet implemented subscribe request: $request")
+ return request.callback.onResult(Status.SUCCESS)
+ }
+
+ override fun unsubscribe(request: UnsubscribeRequest) {
+ Log.d(TAG, "Not yet implemented unsubscribe request: $request")
+ request.callback.onResult(Status.SUCCESS)
+ }
+
+ override fun listSubscriptions(request: ListSubscriptionsRequest) {
+ Log.d(TAG, "Not yet implemented listSubscriptions request: $request")
+ return request.callback.onListSubscriptions(ListSubscriptionsResult(emptyList(), Status(5008)))
+ }
+
+}
\ No newline at end of file
diff --git a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/sessions/FitSessionsBroker.kt b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/sessions/FitSessionsBroker.kt
index 987801c12d..bc87ce2a6e 100644
--- a/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/sessions/FitSessionsBroker.kt
+++ b/play-services-fitness/core/src/main/kotlin/com/google/android/gms/fitness/service/sessions/FitSessionsBroker.kt
@@ -5,9 +5,11 @@
package com.google.android.gms.fitness.service.sessions;
+import FITNESS_FEATURES
import android.os.Parcel
import android.util.Log
import com.google.android.gms.common.api.CommonStatusCodes
+import com.google.android.gms.common.internal.ConnectionInfo
import com.google.android.gms.common.internal.GetServiceRequest
import com.google.android.gms.common.internal.IGmsCallbacks
import com.google.android.gms.fitness.internal.IGoogleFitSessionsApi
@@ -25,7 +27,10 @@ private const val TAG = "FitSessionsBroker"
class FitSessionsBroker : BaseService(TAG, GmsService.FITNESS_SESSIONS) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
- callback.onPostInitComplete(CommonStatusCodes.SUCCESS, FitSessionsBrokerImpl(), null)
+ callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitSessionsBrokerImpl(),
+ ConnectionInfo().apply {
+ features = FITNESS_FEATURES
+ })
}
}
diff --git a/play-services-fitness/core/src/main/kotlin/extensions.kt b/play-services-fitness/core/src/main/kotlin/extensions.kt
new file mode 100644
index 0000000000..5b801c595d
--- /dev/null
+++ b/play-services-fitness/core/src/main/kotlin/extensions.kt
@@ -0,0 +1,13 @@
+import com.google.android.gms.common.Feature
+
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+val FITNESS_FEATURES = arrayOf(
+ Feature("temp_data_point_changelogs", 1L),
+ Feature("temp_session_changelogs", 1L),
+ Feature("temp_data_source_changelogs", 1L),
+ Feature("local_no_account_mode", 1L),
+)
\ No newline at end of file
diff --git a/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/internal/IGoogleFitRecordingApi.aidl b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/internal/IGoogleFitRecordingApi.aidl
new file mode 100644
index 0000000000..3e232dea9b
--- /dev/null
+++ b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/internal/IGoogleFitRecordingApi.aidl
@@ -0,0 +1,16 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.internal;
+
+import com.google.android.gms.fitness.request.ListSubscriptionsRequest;
+import com.google.android.gms.fitness.request.SubscribeRequest;
+import com.google.android.gms.fitness.request.UnsubscribeRequest;
+
+interface IGoogleFitRecordingApi {
+ void subscribe(in SubscribeRequest request) = 0;
+ void unsubscribe(in UnsubscribeRequest request) = 1;
+ void listSubscriptions(in ListSubscriptionsRequest request) = 2;
+}
diff --git a/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/internal/IListSubscriptionsCallback.aidl b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/internal/IListSubscriptionsCallback.aidl
new file mode 100644
index 0000000000..5ac606161a
--- /dev/null
+++ b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/internal/IListSubscriptionsCallback.aidl
@@ -0,0 +1,12 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.internal;
+
+import com.google.android.gms.fitness.result.ListSubscriptionsResult;
+
+interface IListSubscriptionsCallback {
+ void onListSubscriptions(in ListSubscriptionsResult listSubscriptionsResult) = 0;
+}
diff --git a/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/ListSubscriptionsRequest.aidl b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/ListSubscriptionsRequest.aidl
new file mode 100644
index 0000000000..b3f1a85335
--- /dev/null
+++ b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/ListSubscriptionsRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.request;
+
+parcelable ListSubscriptionsRequest;
\ No newline at end of file
diff --git a/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/SubscribeRequest.aidl b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/SubscribeRequest.aidl
new file mode 100644
index 0000000000..3ef299ec86
--- /dev/null
+++ b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/SubscribeRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.request;
+
+parcelable SubscribeRequest;
\ No newline at end of file
diff --git a/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/UnsubscribeRequest.aidl b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/UnsubscribeRequest.aidl
new file mode 100644
index 0000000000..d8616b73a0
--- /dev/null
+++ b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/request/UnsubscribeRequest.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.request;
+
+parcelable UnsubscribeRequest;
\ No newline at end of file
diff --git a/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/result/ListSubscriptionsResult.aidl b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/result/ListSubscriptionsResult.aidl
new file mode 100644
index 0000000000..52bbe95290
--- /dev/null
+++ b/play-services-fitness/src/main/aidl/com/google/android/gms/fitness/result/ListSubscriptionsResult.aidl
@@ -0,0 +1,8 @@
+/*
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.result;
+
+parcelable ListSubscriptionsResult;
\ No newline at end of file
diff --git a/play-services-fitness/src/main/java/com/google/android/gms/fitness/data/Subscription.java b/play-services-fitness/src/main/java/com/google/android/gms/fitness/data/Subscription.java
new file mode 100644
index 0000000000..1f64c3216b
--- /dev/null
+++ b/play-services-fitness/src/main/java/com/google/android/gms/fitness/data/Subscription.java
@@ -0,0 +1,44 @@
+/*
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.data;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+
+@SafeParcelable.Class
+public class Subscription extends AbstractSafeParcelable {
+ @Field(1)
+ public DataSource dataSource;
+ @Field(2)
+ public DataType dataType;
+ @Field(3)
+ public long samplingIntervalMicros;
+ @Field(4)
+ public int accuracyMode;
+ @Field(5)
+ public int subscriptionType;
+
+ @Constructor
+ public Subscription(@Param(1) DataSource dataSource, @Param(2) DataType dataType, @Param(3) long samplingIntervalMicros, @Param(4) int accuracyMode, @Param(5) int subscriptionType) {
+ this.dataSource = dataSource;
+ this.dataType = dataType;
+ this.samplingIntervalMicros = samplingIntervalMicros;
+ this.accuracyMode = accuracyMode;
+ this.subscriptionType = subscriptionType;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(Subscription.class);
+}
diff --git a/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/ListSubscriptionsRequest.java b/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/ListSubscriptionsRequest.java
new file mode 100644
index 0000000000..b90148e4f1
--- /dev/null
+++ b/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/ListSubscriptionsRequest.java
@@ -0,0 +1,31 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.request;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+import com.google.android.gms.fitness.data.DataType;
+import com.google.android.gms.fitness.internal.IListSubscriptionsCallback;
+
+@SafeParcelable.Class
+public class ListSubscriptionsRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public DataType dataType;
+ @Field(2)
+ public IListSubscriptionsCallback callback;
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ListSubscriptionsRequest.class);
+}
diff --git a/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/SubscribeRequest.java b/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/SubscribeRequest.java
new file mode 100644
index 0000000000..71de19d1b4
--- /dev/null
+++ b/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/SubscribeRequest.java
@@ -0,0 +1,33 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.request;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+import com.google.android.gms.fitness.data.Subscription;
+import com.google.android.gms.fitness.internal.IStatusCallback;
+
+@SafeParcelable.Class
+public class SubscribeRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public Subscription subscription;
+ @Field(2)
+ public boolean isServerType; // SERVER:true LOCAL_AND_SERVER:false
+ @Field(3)
+ public IStatusCallback callback;
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(SubscribeRequest.class);
+}
\ No newline at end of file
diff --git a/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/UnsubscribeRequest.java b/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/UnsubscribeRequest.java
new file mode 100644
index 0000000000..5d0bff83c9
--- /dev/null
+++ b/play-services-fitness/src/main/java/com/google/android/gms/fitness/request/UnsubscribeRequest.java
@@ -0,0 +1,34 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.request;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+import com.google.android.gms.fitness.data.DataSource;
+import com.google.android.gms.fitness.data.DataType;
+import com.google.android.gms.fitness.internal.IStatusCallback;
+
+@SafeParcelable.Class
+public class UnsubscribeRequest extends AbstractSafeParcelable {
+ @Field(1)
+ public DataType dataType;
+ @Field(2)
+ public DataSource dataSource;
+ @Field(3)
+ public IStatusCallback callback;
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(UnsubscribeRequest.class);
+}
diff --git a/play-services-fitness/src/main/java/com/google/android/gms/fitness/result/ListSubscriptionsResult.java b/play-services-fitness/src/main/java/com/google/android/gms/fitness/result/ListSubscriptionsResult.java
new file mode 100644
index 0000000000..0b64e77d2c
--- /dev/null
+++ b/play-services-fitness/src/main/java/com/google/android/gms/fitness/result/ListSubscriptionsResult.java
@@ -0,0 +1,40 @@
+/**
+ * SPDX-FileCopyrightText: 2025 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.google.android.gms.fitness.result;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.common.api.Status;
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+import com.google.android.gms.fitness.data.Subscription;
+
+import java.util.List;
+
+@SafeParcelable.Class
+public class ListSubscriptionsResult extends AbstractSafeParcelable {
+
+ @Field(1)
+ public List subscriptions;
+ @Field(2)
+ public Status status;
+
+ @Constructor
+ public ListSubscriptionsResult(@Param(1) List list, @Param(2) Status status) {
+ this.subscriptions = list;
+ this.status = status;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(ListSubscriptionsResult.class);
+}