Repo Created

This commit is contained in:
Fr4nz D13trich 2025-11-15 17:44:12 +01:00
parent eb305e2886
commit a8c22c65db
4784 changed files with 329907 additions and 2 deletions

1
play-services-fitness/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,36 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
}
android {
namespace "com.google.android.gms.fitness"
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"
buildFeatures {
aidl = true
}
defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
dependencies {
// Dependencies from play-services-fitness:21.2.0
api 'androidx.collection:collection:1.0.0'
api project(':play-services-base')
api project(':play-services-basement')
api project(':play-services-tasks')
annotationProcessor project(':safe-parcel-processor')
}

View file

@ -0,0 +1,50 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'maven-publish'
apply plugin: 'signing'
dependencies {
api project(':play-services-fitness')
implementation project(':play-services-base-core')
}
android {
namespace "org.microg.gms.fitness.core"
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'MissingTranslation', 'GetLocales'
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
kotlinOptions {
jvmTarget = 1.8
}
}
// Not publishable yet
// apply from: '../../gradle/publish-android.gradle'
description = 'microG service implementation for play-services-fitness'

View file

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ SPDX-FileCopyrightText: 2024 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<service
android:name="com.google.android.gms.fitness.service.config.FitConfigBroker"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.google.android.gms.fitness.ConfigApi" />
</intent-filter>
</service>
<service
android:name="com.google.android.gms.fitness.service.history.FitHistoryBroker"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.fitness.HistoryApi" />
</intent-filter>
</service>
<service
android:name="com.google.android.gms.fitness.service.sessions.FitSessionsBroker"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.fitness.SessionsApi" />
</intent-filter>
</service>
<service
android:name="com.google.android.gms.fitness.service.recording.FitRecordingBroker"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.fitness.RecordingApi"/>
</intent-filter>
</service>
</application>
</manifest>

View file

@ -0,0 +1,56 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.service.config
import com.google.android.gms.fitness.service.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
import com.google.android.gms.fitness.request.DataTypeCreateRequest
import com.google.android.gms.fitness.request.DisableFitRequest
import com.google.android.gms.fitness.request.ReadDataTypeRequest
import org.microg.gms.BaseService
import org.microg.gms.common.GmsService
import org.microg.gms.utils.warnOnTransactionIssues
private const val TAG = "FitConfigBroker"
class FitConfigBroker : BaseService(TAG, GmsService.FITNESS_CONFIG) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitConfigBrokerImpl(),
ConnectionInfo().apply {
features = FITNESS_FEATURES
})
}
}
class FitConfigBrokerImpl : IGoogleFitConfigApi.Stub() {
override fun createCustomDataType(request: DataTypeCreateRequest?) {
Log.d(TAG, "Not implemented createCustomDataType: $request")
}
override fun readDataType(request: ReadDataTypeRequest?) {
Log.d(TAG, "Not implemented readDataType: $request")
}
override fun disableFit(request: DisableFitRequest?) {
Log.d(TAG, "Method <disableFit> Called: $request")
try {
request?.callback?.onResult(Status.SUCCESS)
} catch (e: Exception) {
Log.w(TAG, "disableFit Error $e")
}
}
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) }
}

View file

@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 2025 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.service
import com.google.android.gms.common.Feature
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),
)

View file

@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.service.history
import com.google.android.gms.fitness.service.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.IGoogleFitHistoryApi
import com.google.android.gms.fitness.request.DailyTotalRequest
import com.google.android.gms.fitness.request.DataDeleteRequest
import com.google.android.gms.fitness.request.DataInsertRequest
import com.google.android.gms.fitness.request.DataPointChangesRequest
import com.google.android.gms.fitness.request.DataReadRequest
import com.google.android.gms.fitness.request.DataUpdateListenerRegistrationRequest
import com.google.android.gms.fitness.request.DataUpdateListenerUnregistrationRequest
import com.google.android.gms.fitness.request.DataUpdateRequest
import com.google.android.gms.fitness.request.DebugInfoRequest
import com.google.android.gms.fitness.request.GetFileUriRequest
import com.google.android.gms.fitness.request.GetSyncInfoRequest
import com.google.android.gms.fitness.request.ReadRawRequest
import com.google.android.gms.fitness.request.ReadStatsRequest
import com.google.android.gms.fitness.request.SessionChangesRequest
import org.microg.gms.BaseService
import org.microg.gms.common.GmsService
import org.microg.gms.utils.warnOnTransactionIssues
private const val TAG = "FitHistoryBroker"
class FitHistoryBroker : BaseService(TAG, GmsService.FITNESS_HISTORY) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitHistoryBrokerImpl().asBinder(),
ConnectionInfo().apply {
features = FITNESS_FEATURES
})
}
}
class FitHistoryBrokerImpl : IGoogleFitHistoryApi.Stub() {
override fun readData(request: DataReadRequest?) {
Log.d(TAG, "Not implemented readData: $request")
}
override fun insertData(request: DataInsertRequest?) {
Log.d(TAG, "Not implemented insertData: $request")
}
override fun deleteData(request: DataDeleteRequest?) {
Log.d(TAG, "Not implemented deleteData: $request")
}
override fun getSyncInfo(request: GetSyncInfoRequest) {
Log.d(TAG, "Not implemented getSyncInfo: $request")
}
override fun readStats(request: ReadStatsRequest?) {
Log.d(TAG, "Not implemented readStats: $request")
}
override fun readRaw(request: ReadRawRequest?) {
Log.d(TAG, "Not implemented readRaw: $request")
}
override fun getDailyTotal(request: DailyTotalRequest?) {
Log.d(TAG, "Not implemented getDailyTotal: $request")
}
override fun insertDataPrivileged(request: DataInsertRequest?) {
Log.d(TAG, "Not implemented insertDataPrivileged: $request")
}
override fun updateData(request: DataUpdateRequest?) {
Log.d(TAG, "Not implemented updateData: $request")
}
override fun registerDataUpdateListener(request: DataUpdateListenerRegistrationRequest?) {
Log.d(TAG, "Not implemented registerDataUpdateListener: $request")
}
override fun unregisterDataUpdateListener(request: DataUpdateListenerUnregistrationRequest?) {
Log.d(TAG, "Not implemented unregisterDataUpdateListener: $request")
}
override fun getFileUri(request: GetFileUriRequest?) {
Log.d(TAG, "Not implemented getFileUri: $request")
}
override fun getDebugInfo(request: DebugInfoRequest?) {
Log.d(TAG, "Not implemented getDebugInfo: $request")
}
override fun getDataPointChanges(request: DataPointChangesRequest?) {
Log.d(TAG, "Not implemented getDataPointChanges: $request")
}
override fun getSessionChanges(request: SessionChangesRequest?) {
Log.d(TAG, "Not implemented getSessionChanges: $request")
}
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) }
}

View file

@ -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 com.google.android.gms.fitness.service.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<Subscription>(), Status(5008)))
}
}

View file

@ -0,0 +1,64 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.service.sessions;
import com.google.android.gms.fitness.service.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
import com.google.android.gms.fitness.request.SessionInsertRequest
import com.google.android.gms.fitness.request.SessionReadRequest
import com.google.android.gms.fitness.request.SessionRegistrationRequest
import com.google.android.gms.fitness.request.SessionStartRequest
import com.google.android.gms.fitness.request.SessionStopRequest
import com.google.android.gms.fitness.request.SessionUnregistrationRequest
import org.microg.gms.BaseService
import org.microg.gms.common.GmsService
import org.microg.gms.utils.warnOnTransactionIssues
private const val TAG = "FitSessionsBroker"
class FitSessionsBroker : BaseService(TAG, GmsService.FITNESS_SESSIONS) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, FitSessionsBrokerImpl(),
ConnectionInfo().apply {
features = FITNESS_FEATURES
})
}
}
class FitSessionsBrokerImpl : IGoogleFitSessionsApi.Stub() {
override fun startRequest(startRequest: SessionStartRequest?) {
Log.d(TAG, "Not implemented startRequest: $startRequest")
}
override fun stopRequest(stopRequest: SessionStopRequest?) {
Log.d(TAG, "Not implemented stopRequest: $stopRequest")
}
override fun insertRequest(insetRequest: SessionInsertRequest?) {
Log.d(TAG, "Not implemented insertRequest: $insetRequest")
}
override fun readRequest(readRequest: SessionReadRequest?) {
Log.d(TAG, "Not implemented readRequest: $readRequest")
}
override fun registrationRequest(registrationRequest: SessionRegistrationRequest?) {
Log.d(TAG, "Not implemented registrationRequest: $registrationRequest")
}
override fun unRegistrationRequest(unRegistrationRequest: SessionUnregistrationRequest?) {
Log.d(TAG, "Not implemented unRegistrationRequest: $unRegistrationRequest")
}
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) }
}

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface IDailyTotalCallback {
}

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface IDataPointChangesCallback {
}

View file

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.request.DataReadResult;
interface IDataReadCallback {
void onPostResult(in DataReadResult dataReadResult) = 0;
}

View file

@ -0,0 +1,12 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.result.DataTypeResult;
interface IDataTypeCallback {
void onDataType(in DataTypeResult dataTypeResult) = 0;
}

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface IDebugInfoCallback {
}

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface IFileUriCallback {
}

View file

@ -0,0 +1,16 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.request.DataTypeCreateRequest;
import com.google.android.gms.fitness.request.DisableFitRequest;
import com.google.android.gms.fitness.request.ReadDataTypeRequest;
interface IGoogleFitConfigApi {
void createCustomDataType(in DataTypeCreateRequest request) = 0;
void readDataType(in ReadDataTypeRequest request) = 1;
void disableFit(in DisableFitRequest request) = 21;
}

View file

@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.request.DataDeleteRequest;
import com.google.android.gms.fitness.request.GetSyncInfoRequest;
import com.google.android.gms.fitness.request.DataInsertRequest;
import com.google.android.gms.fitness.request.DataReadRequest;
import com.google.android.gms.fitness.request.ReadStatsRequest;
import com.google.android.gms.fitness.request.ReadRawRequest;
import com.google.android.gms.fitness.request.DailyTotalRequest;
import com.google.android.gms.fitness.request.DataUpdateRequest;
import com.google.android.gms.fitness.request.DataUpdateListenerRegistrationRequest;
import com.google.android.gms.fitness.request.DataUpdateListenerUnregistrationRequest;
import com.google.android.gms.fitness.request.GetFileUriRequest;
import com.google.android.gms.fitness.request.DebugInfoRequest;
import com.google.android.gms.fitness.request.DataPointChangesRequest;
import com.google.android.gms.fitness.request.SessionChangesRequest;
interface IGoogleFitHistoryApi {
void readData(in DataReadRequest request) = 0;
void insertData(in DataInsertRequest request) = 1;
void deleteData(in DataDeleteRequest request) = 2;
void getSyncInfo(in GetSyncInfoRequest request) = 3;
void readStats(in ReadStatsRequest request) = 4;
void readRaw(in ReadRawRequest request) = 5;
void getDailyTotal(in DailyTotalRequest request) = 6;
void insertDataPrivileged(in DataInsertRequest request) = 7;
void updateData(in DataUpdateRequest request) = 8;
void registerDataUpdateListener(in DataUpdateListenerRegistrationRequest request) = 9;
void unregisterDataUpdateListener(in DataUpdateListenerUnregistrationRequest request) = 10;
void getFileUri(in GetFileUriRequest request) = 11;
void getDebugInfo(in DebugInfoRequest request) = 12;
void getDataPointChanges(in DataPointChangesRequest request) = 15;
void getSessionChanges(in SessionChangesRequest request) = 16;
}

View file

@ -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;
}

View file

@ -0,0 +1,21 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.request.SessionStartRequest;
import com.google.android.gms.fitness.request.SessionStopRequest;
import com.google.android.gms.fitness.request.SessionInsertRequest;
import com.google.android.gms.fitness.request.SessionReadRequest;
import com.google.android.gms.fitness.request.SessionRegistrationRequest;
import com.google.android.gms.fitness.request.SessionUnregistrationRequest;
interface IGoogleFitSessionsApi {
void startRequest(in SessionStartRequest startRequest) = 0;
void stopRequest(in SessionStopRequest stopRequest) = 1;
void insertRequest(in SessionInsertRequest insetRequest) = 2;
void readRequest(in SessionReadRequest readRequest) = 3;
void registrationRequest(in SessionRegistrationRequest registrationRequest) = 4;
void unRegistrationRequest(in SessionUnregistrationRequest unRegistrationRequest) = 5;
}

View file

@ -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;
}

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface IReadRawCallback {
}

View file

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.result.DataStatsResult;
interface IReadStatsCallback {
void onResult(in DataStatsResult result) = 1;
}

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface ISessionChangesCallback {
}

View file

@ -0,0 +1,11 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.result.SessionReadResult;
interface ISessionReadCallback {
void onResult(in SessionReadResult sessionReadResult) = 0;
}

View file

@ -0,0 +1,11 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.fitness.result.SessionStopResult;
interface ISessionStopCallback {
void onResult(in SessionStopResult sessionStopReult) = 0;
}

View file

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
import com.google.android.gms.common.api.Status;
interface IStatusCallback {
void onResult(in Status status) = 0;
}

View file

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.internal;
interface ISyncInfoCallback {
}

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DailyTotalRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataDeleteRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataInsertRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataPointChangesRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataReadRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataReadResult;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataSourceQueryParams;

View file

@ -0,0 +1,8 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataTypeCreateRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataUpdateListenerRegistrationRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataUpdateListenerUnregistrationRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DataUpdateRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DebugInfoRequest;

View file

@ -0,0 +1,8 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable DisableFitRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable GetFileUriRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable GetSyncInfoRequest;

View file

@ -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;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable ReadDataTypeRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable ReadRawRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable ReadStatsRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionChangesRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionInsertRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionReadRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionRegistrationRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionStartRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionStopRequest;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
parcelable SessionUnregistrationRequest;

View file

@ -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;

View file

@ -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;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.result;
parcelable DataSourceStatsResult;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.result;
parcelable DataStatsResult;

View file

@ -0,0 +1,8 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.result;
parcelable DataTypeResult;

View file

@ -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;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.result;
parcelable SessionReadResult;

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.result;
parcelable SessionStopResult;

View file

@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2023 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;
import org.microg.gms.common.Constants;
import org.microg.gms.common.Hide;
import org.microg.gms.utils.ToStringHelper;
@SafeParcelable.Class
@Hide
public class Application extends AbstractSafeParcelable {
public static final Application GMS_APP = new Application(Constants.GMS_PACKAGE_NAME);
@Field(value = 1, getterName = "getPackageName")
@NonNull
private final String packageName;
@Constructor
public Application(@Param(1) @NonNull String packageName) {
this.packageName = packageName;
}
@NonNull
public String getPackageName() {
return packageName;
}
@NonNull
@Override
public String toString() {
return ToStringHelper.name("Application").value(packageName).end();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<Application> CREATOR = findCreator(Application.class);
}

View file

@ -0,0 +1,157 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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 org.microg.gms.utils.ToStringHelper;
import java.util.List;
import java.util.concurrent.TimeUnit;
@SafeParcelable.Class
public class Bucket extends AbstractSafeParcelable {
/**
* Type constant denoting that bucketing by time is requested.
*/
public static final int TYPE_TIME = 1;
/**
* Type constant denoting that bucketing by session is requested.
*/
public static final int TYPE_SESSION = 2;
/**
* Type constant denoting that bucketing by activity type is requested.
*/
public static final int TYPE_ACTIVITY_TYPE = 3;
/**
* Type constant denoting that bucketing by individual activity segment is requested.
*/
public static final int TYPE_ACTIVITY_SEGMENT = 4;
@Field(value = 1, getterName = "getStartTimeMillis")
private final long startTimeMillis;
@Field(value = 2, getterName = "getEndTimeMillis")
private final long endTimeMillis;
@Field(value = 3, getterName = "getSession")
@Nullable
private final Session session;
@Field(value = 4, getterName = "getActivityType")
private final int activityType;
@Field(value = 5, getterName = "getDataSets")
private final List<DataSet> dataSets;
@Field(value = 6, getterName = "getBucketType")
private final int bucketType;
@Constructor
public Bucket(@Param(1) long startTimeMillis, @Param(2) long endTimeMillis, @Nullable @Param(3) Session session, @Param(4) int activityType, @Param(5) List<DataSet> dataSets, @Param(6) int bucketType) {
this.startTimeMillis = startTimeMillis;
this.endTimeMillis = endTimeMillis;
this.session = session;
this.activityType = activityType;
this.dataSets = dataSets;
this.bucketType = bucketType;
}
/**
* Returns the activity of the bucket if bucketing by activity was requested, or {@link FitnessActivities#UNKNOWN} otherwise.
*/
@NonNull
public String getActivity() {
// TODO
return null;
}
/**
* Returns the type of the bucket.
*/
public int getBucketType() {
return bucketType;
}
/**
* Returns the data set of requested data type over the time interval of the bucket. Returns null, if data set for the requested type is not found.
*/
public DataSet getDataSet(@NonNull DataType dataType) {
for (DataSet dataSet : this.dataSets) {
if (dataSet.getDataType().equals(dataType)) {
return dataSet;
}
}
return null;
}
/**
* Returns the requested data sets over the time interval of the bucket.
*/
public List<DataSet> getDataSets() {
return dataSets;
}
/**
* Returns the end time of the bucket, in the given time unit since epoch.
*/
public long getEndTime(TimeUnit timeUnit) {
return timeUnit.convert(this.endTimeMillis, TimeUnit.MILLISECONDS);
}
/**
* Returns the session of the bucket if bucketing by session was requested, {@code null} otherwise.
*/
@Nullable
public Session getSession() {
return session;
}
/**
* Returns the start time of the bucket, in the given time unit since epoch.
*/
public long getStartTime(@NonNull TimeUnit timeUnit) {
return timeUnit.convert(this.startTimeMillis, TimeUnit.MILLISECONDS);
}
int getActivityType() {
return activityType;
}
long getEndTimeMillis() {
return endTimeMillis;
}
long getStartTimeMillis() {
return startTimeMillis;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<Bucket> CREATOR = findCreator(Bucket.class);
@NonNull
@Override
public String toString() {
return ToStringHelper.name("Bucket")
.field("startTimeMillis", startTimeMillis)
.field("endTimeMillis", endTimeMillis)
.field("session", session)
.field("activityType", activityType)
.field("dataSets", dataSets)
.field("bucketType", bucketType)
.end();
}
}

View file

@ -0,0 +1,394 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.content.Intent;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.common.internal.safeparcel.SafeParcelableSerializer;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@SafeParcelable.Class
public class DataPoint extends AbstractSafeParcelable {
@Field(value = 1, getterName = "getDataSource")
@NonNull
private final DataSource dataSource;
@Field(value = 3, getterName = "getTimestampNanos")
private long timestampNanos;
@Field(value = 4, getterName = "getStartTimeNanos")
private long startTimeNanos;
@Field(value = 5, getterName = "getValues")
private final Value[] values;
@Field(value = 6, getterName = "getOriginalDataSourceIfSet")
@Nullable
private DataSource originalDataSource;
@Field(value = 7, getterName = "getRawTimestamp")
private final long rawTimestamp;
DataPoint(DataSource dataSource) {
this.dataSource = dataSource;
List<com.google.android.gms.fitness.data.Field> fields = dataSource.getDataType().getFields();
this.values = new Value[fields.size()];
for (int i = 0; i < fields.size(); i++) {
values[i] = new Value(fields.get(i).getFormat());
}
this.rawTimestamp = 0;
}
@Constructor
DataPoint(@Param(1) @NonNull DataSource dataSource, @Param(3) long timestampNanos, @Param(4) long startTimeNanos, @Param(5) Value[] values, @Param(6) @Nullable DataSource originalDataSource, @Param(7) long rawTimestamp) {
this.dataSource = dataSource;
this.timestampNanos = timestampNanos;
this.startTimeNanos = startTimeNanos;
this.values = values;
this.originalDataSource = originalDataSource;
this.rawTimestamp = rawTimestamp;
}
/**
* Returns the data source for the data point. If the data point is part of a {@link DataSet}, this will correspond to the data set's data source.
*/
@NonNull
public DataSource getDataSource() {
return dataSource;
}
/**
* Returns the data type defining the format of the values in this data point.
*/
@NonNull
public DataType getDataType() {
return dataSource.getDataType();
}
/**
* Returns the end time of the interval represented by this data point, in the given unit since epoch. This method is equivalent to
* {@link #getTimestamp(TimeUnit)}
*/
public long getEndTime(@NonNull TimeUnit timeUnit) {
return timeUnit.convert(this.timestampNanos, TimeUnit.NANOSECONDS);
}
/**
* Returns the original data source for this data point. The original data source helps identify the source of the data point as it gets merged and
* transformed into different streams.
* <p>
* Note that, if this data point is part of a {@link DataSet}, the data source returned here may be different from the data set's data source. In case of
* transformed or merged data sets, each data point's original data source will retain the original attribution as much as possible, while the
* data set's data source will represent the merged or transformed stream.
* <p>
* WARNING: do not rely on this field for anything other than debugging. The value of this field, if it is set at all, is an implementation detail and
* is not guaranteed to remain consistent.
*/
@NonNull
public DataSource getOriginalDataSource() {
if (originalDataSource != null) return originalDataSource;
return dataSource;
}
/**
* Returns the start time of the interval represented by this data point, in the given unit since epoch.
*/
public long getStartTime(@NonNull TimeUnit timeUnit) {
return timeUnit.convert(this.startTimeNanos, TimeUnit.NANOSECONDS);
}
/**
* Returns the timestamp of the data point, in the given unit since epoch. For data points that represent intervals, this method will return the
* end time.
*/
public long getTimestamp(@NonNull TimeUnit timeUnit) {
return timeUnit.convert(this.timestampNanos, TimeUnit.NANOSECONDS);
}
/**
* Returns the value holder for the field with the given name. This method can be used both to query the value and to set it.
*
* @param field One of the fields of this data type.
* @return The Value associated with the given field.
* @throws IllegalArgumentException If the given field doesn't match any of the fields for this DataPoint's data type.
*/
@NonNull
public Value getValue(com.google.android.gms.fitness.data.Field field) {
return this.values[getDataType().indexOf(field)];
}
long getTimestampNanos() {
return timestampNanos;
}
long getStartTimeNanos() {
return startTimeNanos;
}
Value[] getValues() {
return values;
}
DataSource getOriginalDataSourceIfSet() {
return originalDataSource;
}
long getRawTimestamp() {
return rawTimestamp;
}
/**
* Sets the values of this data point, where the format for all of its values is float.
*
* @param values The value for each field of the data point, in order.
* @deprecated Use {@link DataPoint.Builder} to create {@link DataPoint} instances.
*/
@Deprecated
public DataPoint setFloatValues(float... values) {
if (values.length != this.getDataType().getFields().size())
throw new IllegalArgumentException("The number of values does not match the number of fields");
for (int i = 0; i < values.length; i++) {
this.values[i].setFloat(values[i]);
}
return this;
}
/**
* Sets the values of this data point, where the format for all of its values is int.
*
* @param values The value for each field of the data point, in order.
* @deprecated Use {@link DataPoint.Builder} to create {@link DataPoint} instances.
*/
@Deprecated
public DataPoint setIntValues(int... values) {
if (values.length != this.getDataType().getFields().size())
throw new IllegalArgumentException("The number of values does not match the number of fields");
for (int i = 0; i < values.length; i++) {
this.values[i].setInt(values[i]);
}
return this;
}
/**
* Sets the time interval of a data point that represents an interval of time. For data points that represent instantaneous readings,
* {@link #setTimestamp(long, TimeUnit)} should be used.
*
* @param startTime The start time in the given unit, representing elapsed time since epoch.
* @param endTime The end time in the given unit, representing elapsed time since epoch.
* @param timeUnit The time unit of both start and end timestamps.
* @deprecated Use {@link DataPoint.Builder} to create {@link DataPoint} instances.
*/
@Deprecated
public DataPoint setTimeInterval(long startTime, long endTime, TimeUnit timeUnit) {
this.startTimeNanos = timeUnit.toNanos(startTime);
this.timestampNanos = timeUnit.toNanos(endTime);
return this;
}
/**
* Sets the timestamp of a data point that represent an instantaneous reading, measurement, or input. For data points that represent intervals,
* {@link #setTimeInterval(long, long, TimeUnit)} should be used.
*
* @param timestamp The timestamp in the given unit, representing elapsed time since epoch.
* @param timeUnit The unit of the given timestamp.
* @deprecated Use {@link DataPoint.Builder} to create {@link DataPoint} instances.
*/
@Deprecated
public DataPoint setTimestamp(long timestamp, TimeUnit timeUnit) {
this.timestampNanos = timeUnit.toNanos(timestamp);
return this;
}
/**
* Creates a new builder for a {@link DataPoint} with the given {@code dataSource}.
*
* @throws NullPointerException If specified data source is null.
*/
@NonNull
public static Builder builder(@NonNull DataSource dataSource) {
return new Builder(dataSource);
}
/**
* Creates a new data point for the given dataSource. An unset {@link Value} is created for each field of the data source's data type.
*
* @return An empty data point instance.
* @deprecated Use {@link DataPoint.Builder} to create {@link DataPoint} instances.
*/
@NonNull
@Deprecated
public static DataPoint create(@NonNull DataSource dataSource) {
return new DataPoint(dataSource);
}
/**
* Extracts a data point from a callback intent received after registering to a data source with a PendingIntent.
*
* @return The extracted DataPoint, or {@code null} if the given intent does not contain a DataPoint
*/
@Nullable
public static DataPoint extract(@NonNull Intent intent) {
return SafeParcelableSerializer.deserializeFromBytes(intent.getByteArrayExtra("com.google.android.gms.fitness.EXTRA_DATA_POINT"), CREATOR);
}
/**
* Builder for {@link DataPoint} instances.
*/
public static class Builder {
private final DataPoint dataPoint;
private boolean built = false;
Builder(DataSource dataSource) {
this.dataPoint = DataPoint.create(dataSource);
}
/**
* Builds and returns the {@link DataPoint}.
*/
@NonNull
public DataPoint build() {
if (built) throw new IllegalStateException("DataPoint already built");
this.built = true;
return this.dataPoint;
}
/**
* Sets the value of an activity field to {@code activity}.
*
* @throws IllegalArgumentException If the given index is out of the range for this data type.
* @throws IllegalStateException If the field isn't of format {@link com.google.android.gms.fitness.data.Field#FORMAT_INT32}.
*/
@NonNull
public Builder setActivityField(@NonNull com.google.android.gms.fitness.data.Field field, @NonNull String activity) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.getValue(field).setActivity(activity);
return this;
}
/**
* Sets the floating point value of the given {@code field} to {@code value}.
*
* @throws IllegalArgumentException If the given index is out of the range for this data type.
* @throws IllegalStateException If the field isn't of format {@link com.google.android.gms.fitness.data.Field#FORMAT_FLOAT}.
*/
@NonNull
public Builder setField(@NonNull com.google.android.gms.fitness.data.Field field, float value) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.getValue(field).setFloat(value);
return this;
}
/**
* Sets the map value of the given {@code field} to {@code value}.
*
* @throws IllegalArgumentException If the given index is out of the range for this data type.
* @throws IllegalStateException If the field isn't of format {@link com.google.android.gms.fitness.data.Field#FORMAT_MAP}.
*/
@NonNull
public Builder setField(@NonNull com.google.android.gms.fitness.data.Field field, @NonNull Map<String, Float> map) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.getValue(field).setMap(map);
return this;
}
/**
* Sets the integer value of the given {@code field} to {@code value}.
*
* @throws IllegalArgumentException If the given index is out of the range for this data type.
* @throws IllegalStateException If the field isn't of format {@link com.google.android.gms.fitness.data.Field#FORMAT_INT32}.
*/
@NonNull
public Builder setField(@NonNull com.google.android.gms.fitness.data.Field field, int value) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.getValue(field).setInt(value);
return this;
}
/**
* Sets the string value of the given {@code field} to {@code value}.
*
* @throws IllegalArgumentException If the given index is out of the range for this data type.
* @throws IllegalStateException If the field isn't of format {@link com.google.android.gms.fitness.data.Field#FORMAT_STRING}.
*/
@NonNull
public Builder setField(@NonNull com.google.android.gms.fitness.data.Field field, @NonNull String value) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.getValue(field).setString(value);
return this;
}
/**
* Sets the values of the data point, where the format for all of its values is float.
*
* @param values The value for each field of the data point, in order.
*/
@NonNull
public Builder setFloatValues(@NonNull float... values) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.setFloatValues(values);
return this;
}
/**
* Sets the values of the data point, where the format for all of its values is int.
*
* @param values The value for each field of the data point, in order.
*/
@NonNull
public Builder setIntValues(@NonNull int... values) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.setIntValues(values);
return this;
}
/**
* Sets the time interval of a data point that represents an interval of time. For data points that represent instantaneous readings,
* {@link #setTimestamp(long, TimeUnit)} should be used.
*
* @param startTime The start time in the given unit, representing elapsed time since epoch.
* @param endTime The end time in the given unit, representing elapsed time since epoch.
* @param timeUnit The time unit of both start and end timestamps.
*/
@NonNull
public Builder setTimeInterval(long startTime, long endTime, @NonNull TimeUnit timeUnit) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.setTimeInterval(startTime, endTime, timeUnit);
return this;
}
/**
* Sets the timestamp of a data point that represent an instantaneous reading, measurement, or input. For data points that represent intervals,
* {@link #setTimeInterval(long, long, TimeUnit)} should be used.
*
* @param timestamp The timestamp in the given unit, representing elapsed time since epoch.
* @param timeUnit The unit of the given timestamp.
*/
@NonNull
public Builder setTimestamp(long timestamp, @NonNull TimeUnit timeUnit) {
if (built) throw new IllegalStateException("DataPoint already built");
this.dataPoint.setTimestamp(timestamp, timeUnit);
return this;
}
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataPoint> CREATOR = findCreator(DataPoint.class);
}

View file

@ -0,0 +1,211 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Represents a fixed set of data points in a data type's stream from a particular data source. A data set usually represents data at
* fixed time boundaries, and can be used both for batch data insertion and as a result of read requests.
*/
@SafeParcelable.Class
public class DataSet extends AbstractSafeParcelable {
@Field(1000)
final int versionCode;
@Field(value = 1, getterName = "getDataSource")
@NonNull
private final DataSource dataSource;
@Field(value = 3, getterName = "getRawDataPoints")
@NonNull
private final List<DataPoint> rawDataPoints;
@Field(value = 4, getterName = "getUniqueDataSources")
@NonNull
private final List<DataSource> uniqueDataSources;
@Constructor
DataSet(@Param(1000) int versionCode, @Param(1) @NonNull DataSource dataSource, @Param(3) @NonNull List<DataPoint> rawDataPoints, @Param(4) List<DataSource> uniqueDataSources) {
this.versionCode = versionCode;
this.dataSource = dataSource;
this.rawDataPoints = rawDataPoints;
this.uniqueDataSources = versionCode < 2 ? Collections.singletonList(dataSource) : uniqueDataSources;
}
DataSet(@NonNull DataSource dataSource) {
this.versionCode = 3;
this.dataSource = dataSource;
this.rawDataPoints = new ArrayList<>();
this.uniqueDataSources = new ArrayList<>();
uniqueDataSources.add(dataSource);
}
/**
* Adds a data point to this data set. The data points should be for the correct data type and data source, and should have its timestamp
* already set.
*
* @throws IllegalArgumentException If dataPoint has invalid data.
* @deprecated Build {@link DataSet} instances using the builder.
*/
@Deprecated
public void add(@NonNull DataPoint dataPoint) {
if (!dataPoint.getDataSource().getStreamIdentifier().equals(dataSource.getStreamIdentifier()))
throw new IllegalArgumentException("Conflicting data sources found");
// TODO
rawDataPoints.add(dataPoint);
}
/**
* Adds a list of data points to this data set in bulk. All data points should be for the correct data type and data source, and should have their
* timestamp already set.
*
* @deprecated Build {@link DataSet} instances using the builder.
*/
@Deprecated
public void addAll(@NonNull Iterable<DataPoint> iterable) {
for (DataPoint dataPoint : iterable) {
add(dataPoint);
}
}
/**
* Creates an empty data point for this data set's data source. The new data point is not added to the data set by this method. After the data
* point is initialized, {@link #add(DataPoint)} should be called.
*/
@NonNull
public DataPoint createDataPoint() {
return DataPoint.create(this.dataSource);
}
/**
* Returns the list of data points represented by this data set. The data points will preserve the same order in which they were inserted.
* <p>
* Certain APIs that return a DataSet might insert data points in chronological order, but this isn't enforced.
*/
@NonNull
public List<DataPoint> getDataPoints() {
return Collections.unmodifiableList(rawDataPoints);
}
/**
* Returns the data source which this data set represents. All of the data points in the data set are from this data source.
*/
@NonNull
public DataSource getDataSource() {
return dataSource;
}
/**
* Returns the data type this data set represents. All of the data points in the data set are of this data type.
*/
@NonNull
public DataType getDataType() {
return dataSource.getDataType();
}
@NonNull
List<DataPoint> getRawDataPoints() {
return rawDataPoints;
}
@NonNull
List<DataSource> getUniqueDataSources() {
return uniqueDataSources;
}
/**
* Creates a new builder for a {@link DataSet} with the given {@code dataSource}.
*
* @throws NullPointerException If specified data source is null.
*/
@NonNull
public static Builder builder(@NonNull DataSource dataSource) {
return new Builder(dataSource);
}
/**
* Creates a new data set to hold data points for the given {@code dataSource}.
* <p>
* Data points with the matching data source can be created using {@link #createDataPoint()}, and after having the values set added to the data set
* via {@link #add(DataPoint)}.
*
* @throws NullPointerException If specified data source is null.
*/
@NonNull
public static DataSet create(@NonNull DataSource dataSource) {
return new DataSet(dataSource);
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
/**
* Builder used to create new data sets.
*/
public static class Builder {
private final DataSet dataSet;
private boolean built = false;
Builder(DataSource dataSource) {
this.dataSet = DataSet.create(dataSource);
}
/**
* Adds a data point to this data set. The data points should be for the correct data type and data source, and should have its timestamp
* already set.
*
* @throws IllegalArgumentException If dataPoint has the wrong {@link DataSource}, or contain invalid data.
*/
@NonNull
public Builder add(@NonNull DataPoint dataPoint) {
if (built) throw new IllegalStateException("DataSet has already been built.");
this.dataSet.add(dataPoint);
return this;
}
/**
* Adds a list of data points to this data set in bulk. All data points should be for the correct data type and data source, and should have their
* timestamp already set.
*
* @throws IllegalArgumentException If the {@code dataPoints} have the wrong source, or contain invalid data.
*/
@NonNull
public Builder addAll(@NonNull Iterable<DataPoint> iterable) {
if (built) throw new IllegalStateException("DataSet has already been built.");
this.dataSet.addAll(iterable);
return this;
}
/**
* Finishes building and returns the {@link DataSet}.
*
* @throws IllegalStateException If called more than once.
*/
@NonNull
public DataSet build() {
if (built) throw new IllegalStateException("DataSet has already been built.");
this.built = true;
return this.dataSet;
}
}
public static final SafeParcelableCreatorAndWriter<DataSet> CREATOR = findCreator(DataSet.class);
}

View file

@ -0,0 +1,284 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.common.internal.safeparcel.SafeParcelableSerializer;
import org.microg.gms.common.Constants;
import org.microg.gms.utils.ToStringHelper;
/**
* Definition of a unique source of sensor data. Data sources can expose raw data coming from hardware sensors on local or companion
* devices. They can also expose derived data, created by transforming or merging other data sources. Multiple data sources can exist for the
* same data type. Every data point inserted into or read from Google Fit has an associated data source.
* <p>
* The data source contains enough information to uniquely identify its data, including the hardware device and the application that
* collected and/or transformed the data. It also holds useful metadata, such as a stream name and the device type.
* <p>
* The data source's data stream can be accessed in a live fashion by registering a data source listener, or via queries over fixed time intervals.
* <p>
* An end-user-visible name for the data stream can be set by calling {@link DataSource.Builder.setStreamName(String)} or otherwise computed
* from the device model and application name.
*/
@SafeParcelable.Class
public class DataSource extends AbstractSafeParcelable {
/**
* Name for the parcelable intent extra containing a data source. It can be extracted using {@link #extract(Intent)}.
*/
public static final String EXTRA_DATA_SOURCE = "vnd.google.fitness.data_source";
/**
* Type constant for a data source which exposes original, raw data from an external source such as a hardware sensor, a wearable device, or
* user input.
*/
public static final int TYPE_RAW = 0;
/**
* Type constant for a data source which exposes data which is derived from one or more existing data sources by performing
* transformations on the original data.
*/
public static final int TYPE_DERIVED = 1;
@Field(value = 1, getterName = "getDataType")
@NonNull
private final DataType dataType;
@Field(value = 3, getterName = "getType")
private final int type;
@Field(value = 4, getterName = "getDevice")
@Nullable
private final Device device;
@Field(value = 5, getterName = "getApplication")
@Nullable
final Application application;
@Field(value = 6, getterName = "getStreamName")
private final String streamName;
@Constructor
DataSource(@Param(1) @NonNull DataType dataType, @Param(3) int type, @Param(4) @Nullable Device device, @Param(5) @Nullable Application application, @Param(6) String streamName) {
this.dataType = dataType;
this.type = type;
this.device = device;
this.application = application;
this.streamName = streamName;
}
@Nullable
public Application getApplication() {
return application;
}
/**
* Returns the package name for the application responsible for setting the data, or {@code null} if unset/unknown. {@link PackageManager} can be used to
* query relevant information about the application, such as the name, icon, and logo.
* <p>
* Data coming from local sensors or BLE devices will not have a corresponding application.
*/
@Nullable
public String getAppPackageName() {
if (application == null) return null;
return application.getPackageName();
}
/**
* Returns the data type for data coming from this data source. Knowing the type of a data source can be useful to perform transformations on
* top of raw data without using sources that are themselves computed by transforming raw data.
*/
@NonNull
public DataType getDataType() {
return dataType;
}
/**
* Returns the device where data is being collected, or {@code null} if unset.
*/
@Nullable
public Device getDevice() {
return device;
}
/**
* Returns a unique identifier for the data stream produced by this data source. The identifier includes, in order:
* <ol>
* <li>the data source's type (raw or derived)</li>
* <li>the data source's data type</li>
* <li>the application's package name (unique for a given application)</li>
* <li>the physical device's manufacturer, model, and serial number (UID)</li>
* <li>the data source's stream name.</li>
* </ol>
*/
@NonNull
public String getStreamIdentifier() {
StringBuilder sb = new StringBuilder();
sb.append(type == TYPE_RAW ? "raw" : "derived");
sb.append(":").append(dataType.getName());
if (application != null) sb.append(":").append(application.getPackageName());
if (device != null) sb.append(":").append(device.getDeviceId());
if (streamName != null) sb.append(":").append(streamName);
return sb.toString();
}
/**
* Returns the specific stream name for the stream coming from this data source, or an empty string if unset.
*/
@NonNull
public String getStreamName() {
return streamName;
}
/**
* Returns the constant describing the type of this data source.
*
* @return One of the constant values ({@link #TYPE_DERIVED} or {@link #TYPE_RAW}), zero if unset. Values outside of this range should be treated as
* unset/unknown.
*/
public int getType() {
return type;
}
@Override
public int hashCode() {
return getStreamIdentifier().hashCode();
}
@NonNull
@Override
public String toString() {
return ToStringHelper.name("DataSource").value(getStreamIdentifier()).end();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
/**
* Extracts the data source extra from the given intent, such as an intent to view user's data.
*
* @return The data source, or {@code null} if not found.
*/
@Nullable
public static DataSource extract(@NonNull Intent intent) {
return SafeParcelableSerializer.deserializeFromBytes(intent.getByteArrayExtra(EXTRA_DATA_SOURCE), CREATOR);
}
/**
* A builder that can be used to construct new data source objects. In general, a built data source should be saved in memory to avoid the cost
* of re-constructing it for every request.
*/
public static class Builder {
private DataType dataType;
private Device device;
private Application application;
private int type = -1;
private String streamName = "";
/**
* Finishes building the data source and returns a DataSource object.
*
* @throws IllegalStateException If the builder didn't have enough data to build a valid data source.
*/
@NonNull
public DataSource build() {
if (dataType == null) throw new IllegalStateException("dataType must be set");
if (type < 0) throw new IllegalStateException("type must be set");
return new DataSource(dataType, type, device, application, streamName);
}
/**
* Sets the package name for the application that is recording or computing the data. Used for data sources that aren't built into the platform
* (local sensors and BLE sensors are built-in). It can be used to identify the data source, to disambiguate between data from different
* applications, and also to link back to the original application for a detailed view.
*/
@NonNull
public Builder setAppPackageName(@NonNull String packageName) {
Application application = Application.GMS_APP;
this.application = Constants.GMS_PACKAGE_NAME.equals(packageName) ? Application.GMS_APP : new Application(packageName);
return this;
}
/**
* Sets the package name for the application that is recording or computing the data based on the app's context. This method should be
* preferred when an application is creating a data source that represents its own data. When creating a data source to query data from other
* apps, {@link #setAppPackageName(String)} should be used.
*/
@NonNull
public Builder setAppPackageName(@NonNull Context appContext) {
setAppPackageName(appContext.getPackageName());
return this;
}
/**
* Sets the data type for the data source. Every data source is required to have a data type.
*
* @param dataType One of the data types defined in {@link DataType}, or a custom data type.
*/
@NonNull
public Builder setDataType(@NonNull DataType dataType) {
this.dataType = dataType;
return this;
}
/**
* Sets the integrated device where data is being recorded (for instance, a phone that has sensors, or a wearable). Can be useful to identify the
* data source, and to disambiguate between data from different devices. If the data is coming from the local device, use
* {@link Device#getLocalDevice(Context)}.
* <p>
* Note that it may be useful to set the device even if the data is not coming from a hardware sensor on the device. For instance, if the user
* installs an application which generates sensor data in two separate devices, the only way to differentiate the two data sources is using the
* device. This can be specially important if both devices are used at the same time.
*/
@NonNull
public Builder setDevice(@NonNull Device device) {
this.device = device;
return this;
}
/**
* The stream name uniquely identifies this particular data source among other data sources of the same type from the same underlying
* producer. Setting the stream name is optional, but should be done whenever an application exposes two streams for the same data type, or
* when a device has two equivalent sensors.
* <p>
* The stream name is used by {@link DataSource#getStreamIdentifier()} to make sure the different streams are properly separated when
* querying or persisting data.
*
* @throws IllegalArgumentException If the specified stream name is null.
*/
@NonNull
public Builder setStreamName(@NonNull String streamName) {
//noinspection ConstantValue
if (streamName == null) throw new IllegalArgumentException("streamName must be set");
this.streamName = streamName;
return this;
}
/**
* Sets the type of the data source. {@link DataSource#TYPE_DERIVED} should be used if any other data source is used in generating the data.
* {@link DataSource#TYPE_RAW} should be used if the data comes completely from outside of Google Fit.
*/
@NonNull
public Builder setType(int type) {
this.type = type;
return this;
}
}
public static final SafeParcelableCreatorAndWriter<DataSource> CREATOR = findCreator(DataSource.class);
}

View file

@ -0,0 +1,205 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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 java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static com.google.android.gms.fitness.data.Field.*;
/**
* The data type defines the schema for a stream of data being collected by, inserted into, or queried from Google Fit. The data type defines
* only the representation and format of the data, and not how it's being collected, the sensor being used, or the parameters of the collection.
* <p>
* A data type contains one or more fields. In case of multi-dimensional data (such as location with latitude, longitude, and accuracy) each
* field represents one dimension. Each data type field has a unique name which identifies it. The field also defines the format of the data
* (such as int or float).
* <p>
* The data types in the {@code com.google} namespace are shared with any app with the user consent. These are fixed and can only be updated in
* new releases of the platform. This class contains constants representing each of the {@code com.google} data types, each prefixed with {@code TYPE_}.
* Custom data types can be accessed via the {@link ConfigClient}.
* <p>
* Certain data types can represent aggregates, and can be computed as part of read requests by calling
* {@link DataReadRequest.Builder#aggregate(DataType)}. This class contains constants for all the valid aggregates, each prefixed with
* {@code AGGREGATE_}. The aggregates for each input type can be queried via {@link #getAggregatesForInput(DataType)}.
*/
@SafeParcelable.Class
public class DataType extends AbstractSafeParcelable {
/**
* The common prefix for data type MIME types, for use in intents. The MIME type for a particular data type will be this prefix followed by
* the data type name.
* <p>
* The data type's name is returned by {@link #getName()}. The full MIME type can be computed by {@link #getMimeType(DataType)}.
*/
public static final String MIME_TYPE_PREFIX = "vnd.google.fitness.data_type/";
public static final DataType TYPE_ACTIVITY_SEGMENT = new DataType("com.google.activity.segment", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_ACTIVITY);
public static final DataType TYPE_BASAL_METABOLIC_RATE = new DataType("com.google.calories.bmr", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_CALORIES);
public static final DataType TYPE_BODY_FAT_PERCENTAGE = new DataType("com.google.body.fat.percentage", "https://www.googleapis.com/auth/fitness.body.read", "https://www.googleapis.com/auth/fitness.body.write", FIELD_PERCENTAGE);
public static final DataType TYPE_CALORIES_EXPENDED = new DataType("com.google.calories.expended", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_CALORIES);
public static final DataType TYPE_CYCLING_PEDALING_CADENCE = new DataType("com.google.cycling.pedaling.cadence", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_RPM);
public static final DataType TYPE_CYCLING_PEDALING_CUMULATIVE = new DataType("com.google.cycling.pedaling.cumulative", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_REVOLUTIONS);
public static final DataType TYPE_CYCLING_WHEEL_REVOLUTION = new DataType("com.google.cycling.wheel_revolution.cumulative", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_REVOLUTIONS);
public static final DataType TYPE_CYCLING_WHEEL_RPM = new DataType("com.google.cycling.wheel_revolution.rpm", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_RPM);
public static final DataType TYPE_DISTANCE_DELTA = new DataType("com.google.distance.delta", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_DISTANCE);
public static final DataType TYPE_HEART_POINTS = new DataType("com.google.heart_minutes", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_INTENSITY);
public static final DataType TYPE_HEART_RATE_BPM = new DataType("com.google.heart_rate.bpm", "https://www.googleapis.com/auth/fitness.heart_rate.read", "https://www.googleapis.com/auth/fitness.heart_rate.write", FIELD_BPM);
public static final DataType TYPE_HEIGHT = new DataType("com.google.height", "https://www.googleapis.com/auth/fitness.body.read", "https://www.googleapis.com/auth/fitness.body.write", FIELD_HEIGHT);
public static final DataType TYPE_HYDRATION = new DataType("com.google.hydration", "https://www.googleapis.com/auth/fitness.nutrition.read", "https://www.googleapis.com/auth/fitness.nutrition.write", FIELD_VOLUME);
public static final DataType TYPE_LOCATION_SAMPLE = new DataType("com.google.location.sample", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_LATITUDE, FIELD_LONGITUDE, FIELD_ACCURACY, FIELD_ALTITUDE);
@Deprecated
public static final DataType TYPE_LOCATION_TRACK = new DataType("com.google.location.track", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_LATITUDE, FIELD_LONGITUDE, FIELD_ACCURACY, FIELD_ALTITUDE);
public static final DataType TYPE_MOVE_MINUTES = new DataType("com.google.active_minutes", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_DURATION);
public static final DataType TYPE_NUTRITION = new DataType("com.google.nutrition", "https://www.googleapis.com/auth/fitness.nutrition.read", "https://www.googleapis.com/auth/fitness.nutrition.write", FIELD_NUTRIENTS, FIELD_MEAL_TYPE, FIELD_FOOD_ITEM);
public static final DataType TYPE_POWER_SAMPLE = new DataType("com.google.power.sample", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_WATTS);
public static final DataType TYPE_SLEEP_SEGMENT = new DataType("com.google.sleep.segment", "https://www.googleapis.com/auth/fitness.sleep.read", "https://www.googleapis.com/auth/fitness.sleep.write", FIELD_SLEEP_SEGMENT_TYPE);
public static final DataType TYPE_SPEED = new DataType("com.google.speed", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_SPEED);
public static final DataType TYPE_STEP_COUNT_CADENCE = new DataType("com.google.step_count.cadence", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_RPM);
public static final DataType TYPE_STEP_COUNT_DELTA = new DataType("com.google.step_count.delta", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_STEPS);
public static final DataType TYPE_WEIGHT = new DataType("com.google.weight", "https://www.googleapis.com/auth/fitness.body.read", "https://www.googleapis.com/auth/fitness.body.write", FIELD_WEIGHT);
public static final DataType TYPE_WORKOUT_EXERCISE = new DataType("com.google.activity.exercise", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_EXERCISE, FIELD_REPETITIONS, FIELD_DURATION_OPTIONAL, FIELD_RESISTANCE_TYPE, FIELD_RESISTANCE);
public static final DataType TYPE_DEVICE_ON_BODY = new DataType("com.google.device_on_body", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_PROBABILITY);
public static final DataType TYPE_INTERNAL_GOAL = new DataType("com.google.internal.goal", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_FITNESS_GOAL_V2);
public static final DataType TYPE_MET = new DataType("com.google.internal.met", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_MET);
public static final DataType TYPE_PACED_WALKING_ATTRIBUTES = new DataType("com.google.internal.paced_walking_attributes", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_FITNESS_PACED_WALKING_ATTRIBUTES);
public static final DataType TYPE_RESPIRATORY_RATE = new DataType("com.google.respiratory_rate", "https://www.googleapis.com/auth/fitness.respiratory_rate.read", "https://www.googleapis.com/auth/fitness.respiratory_rate.write", FIELD_RESPIRATORY_RATE);
public static final DataType TYPE_SENSOR_EVENTS = new DataType("com.google.sensor.events", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_SENSOR_TYPE, FIELD_TIMESTAMPS, FIELD_SENSOR_VALUES);
public static final DataType TYPE_SLEEP_ATTRIBUTES = new DataType("com.google.internal.sleep_attributes", "https://www.googleapis.com/auth/fitness.sleep.read", "https://www.googleapis.com/auth/fitness.sleep.write", FIELD_FITNESS_SLEEP_ATTRIBUTES);
public static final DataType TYPE_SLEEP_SCHEDULE = new DataType("com.google.internal.sleep_schedule", "https://www.googleapis.com/auth/fitness.sleep.read", "https://www.googleapis.com/auth/fitness.sleep.write", FIELD_FITNESS_SLEEP_SCHEDULE);
public static final DataType TYPE_STEP_COUNT_CUMULATIVE = new DataType("com.google.step_count.cumulative", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_STEPS);
public static final DataType TYPE_TIME_ZONE_CHANGE = new DataType("com.google.time_zone_change", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_ZONE_ID);
public static final DataType TYPE_WORKOUT_SAMPLES = new DataType("com.google.activity.samples", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_ACTIVITY_CONFIDENCE);
public static final DataType AGGREGATE_ACTIVITY_SUMMARY = new DataType("com.google.activity.summary", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_ACTIVITY, FIELD_DURATION, FIELD_NUM_SEGMENTS);
public static final DataType AGGREGATE_BASAL_METABOLIC_RATE_SUMMARY = new DataType("com.google.calories.bmr.summary", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
public static final DataType AGGREGATE_BODY_FAT_PERCENTAGE_SUMMARY = new DataType("com.google.body.fat.percentage.summary", "https://www.googleapis.com/auth/fitness.body.read", "https://www.googleapis.com/auth/fitness.body.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
public static final DataType AGGREGATE_CALORIES_EXPENDED = TYPE_CALORIES_EXPENDED;
public static final DataType AGGREGATE_DISTANCE_DELTA = TYPE_DISTANCE_DELTA;
public static final DataType AGGREGATE_HEART_POINTS = new DataType("com.google.heart_minutes.summary", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_INTENSITY, FIELD_DURATION);
public static final DataType AGGREGATE_HEART_RATE_SUMMARY = new DataType("com.google.heart_rate.summary", "https://www.googleapis.com/auth/fitness.heart_rate.read", "https://www.googleapis.com/auth/fitness.heart_rate.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
public static final DataType AGGREGATE_HEIGHT_SUMMARY = new DataType("com.google.height.summary", "https://www.googleapis.com/auth/fitness.body.read", "https://www.googleapis.com/auth/fitness.body.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
public static final DataType AGGREGATE_HYDRATION = TYPE_HYDRATION;
public static final DataType AGGREGATE_LOCATION_BOUNDING_BOX = new DataType("com.google.location.bounding_box", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_LOW_LATITUDE, FIELD_LOW_LONGITUDE, FIELD_HIGH_LATITUDE, FIELD_HIGH_LONGITUDE);
public static final DataType AGGREGATE_MOVE_MINUTES = TYPE_MOVE_MINUTES;
public static final DataType AGGREGATE_NUTRITION_SUMMARY = new DataType("com.google.nutrition.summary", "https://www.googleapis.com/auth/fitness.nutrition.read", "https://www.googleapis.com/auth/fitness.nutrition.write", FIELD_NUTRIENTS, FIELD_MEAL_TYPE);
public static final DataType AGGREGATE_POWER_SUMMARY = new DataType("com.google.power.summary", "https://www.googleapis.com/auth/fitness.activity.read", "https://www.googleapis.com/auth/fitness.activity.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
public static final DataType AGGREGATE_SPEED_SUMMARY = new DataType("com.google.speed.summary", "https://www.googleapis.com/auth/fitness.location.read", "https://www.googleapis.com/auth/fitness.location.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
public static final DataType AGGREGATE_STEP_COUNT_DELTA = TYPE_STEP_COUNT_DELTA;
public static final DataType AGGREGATE_WEIGHT_SUMMARY = new DataType("com.google.weight.summary", "https://www.googleapis.com/auth/fitness.body.read", "https://www.googleapis.com/auth/fitness.body.write", FIELD_AVERAGE, FIELD_MAX, FIELD_MIN);
@Field(value = 1, getterName = "getName")
@NonNull
private final String name;
@Field(value = 2, getterName = "getFields")
@NonNull
private final List<com.google.android.gms.fitness.data.Field> fields;
@Field(3)
@Nullable
final String readScope;
@Field(4)
@Nullable
final String writeScope;
DataType(@NonNull String name, @Nullable String readScope, @Nullable String writeScope, com.google.android.gms.fitness.data.Field... fields) {
this.name = name;
this.readScope = readScope;
this.writeScope = writeScope;
this.fields = Collections.unmodifiableList(Arrays.asList(fields));
}
@Constructor
DataType(@Param(1) @NonNull String name, @Param(2) @NonNull List<com.google.android.gms.fitness.data.Field> fields, @Param(3) @Nullable String readScope, @Param(4) @Nullable String writeScope) {
this.name = name;
this.fields = fields;
this.readScope = readScope;
this.writeScope = writeScope;
}
/**
* Returns the aggregate output type for this type, or {@code null} if the type does not support aggregation.
* <p>
* To check if a data type is supported for aggregation, check that the returned type is non-null.
*/
@Nullable
public DataType getAggregateType() {
// TODO
return null;
}
/**
* Returns the ordered list of fields for the data type.
*/
@NonNull
public List<com.google.android.gms.fitness.data.Field> getFields() {
return fields;
}
/**
* Returns the namespaced name which uniquely identifies this data type.
*/
@NonNull
public String getName() {
return name;
}
/**
* Returns the index of a field.
*
* @throws IllegalArgumentException If field isn't defined for this data type.
*/
public int indexOf(@NonNull com.google.android.gms.fitness.data.Field field) {
int indexOf = this.fields.indexOf(field);
if (indexOf < 0) throw new IllegalArgumentException("Field not found");
return indexOf;
}
/**
* Returns a list of output aggregate data types for the specified {@code inputDataType}.
* <p>
* To check if a data type is supported for aggregation, check that the returned list is not empty
* {@code DataType.getAggregatesForInput(dataType).isEmpty()}.
*
* @deprecated Use {@link #getAggregateType()} instead.
*/
@NonNull
@Deprecated
public static List<DataType> getAggregatesForInput(@NonNull DataType inputDataType) {
DataType aggregateType = inputDataType.getAggregateType();
if (aggregateType == null) return Collections.emptyList();
return Collections.singletonList(aggregateType);
}
/**
* Returns the MIME type for a particular {@link DataType}. The MIME type is used in intents such as the data view intent.
*/
@NonNull
public static String getMimeType(@NonNull DataType dataType) {
return MIME_TYPE_PREFIX + dataType.getName();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataType> CREATOR = findCreator(DataType.class);
}

View file

@ -0,0 +1,177 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Parcel;
import android.provider.Settings;
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 org.microg.gms.utils.ToStringHelper;
import static android.os.Build.VERSION.SDK_INT;
/**
* Representation of an integrated device (such as a phone or a wearable) that can hold sensors. Each sensor is exposed as a {@link DataSource}.
*/
@SafeParcelable.Class
public class Device extends AbstractSafeParcelable {
/**
* Constant indicating the device type is not known.
*/
public static final int TYPE_UNKNOWN = 0;
/**
* Constant indicating the device is an Android phone.
*/
public static final int TYPE_PHONE = 1;
/**
* Constant indicating the device is an Android tablet.
*/
public static final int TYPE_TABLET = 2;
/**
* Constant indicating the device is a watch or other wrist-mounted band.
*/
public static final int TYPE_WATCH = 3;
/**
* Constant indicating the device is a chest strap.
*/
public static final int TYPE_CHEST_STRAP = 4;
/**
* Constant indicating the device is a scale or similar device the user steps on.
*/
public static final int TYPE_SCALE = 5;
/**
* Constant indicating the device is a headset, pair of glasses, or other head-mounted device
*/
public static final int TYPE_HEAD_MOUNTED = 6;
@Field(value = 1, getterName = "getManufacturer")
@NonNull
private final String manufacturer;
@Field(value = 2, getterName = "getModel")
@NonNull
private final String model;
@Field(value = 4, getterName = "getUid")
@NonNull
private final String uid;
@Field(value = 5, getterName = "getType")
private final int type;
@Field(value = 6, getterName = "getPlatformType")
private final int platformType;
@Constructor
Device(@NonNull @Param(1) String manufacturer, @NonNull @Param(2) String model, @NonNull @Param(4) String uid, @Param(5) int type, @Param(6) int platformType) {
this.manufacturer = manufacturer;
this.model = model;
this.uid = uid;
this.type = type;
this.platformType = platformType;
}
/**
* Creates a new device.
*
* @param manufacturer The manufacturer of the product/hardware.
* @param model The end-user-visible name for the end product.
* @param uid A serial number or other unique identifier for the particular device hardware.
* @param type The type of device. One of the type constants.
*/
public Device(@NonNull String manufacturer, @NonNull String model, @NonNull String uid, int type) {
this(manufacturer, model, uid, type, 0);
}
/**
* Returns the manufacturer of the product/hardware.
*/
@NonNull
public String getManufacturer() {
return manufacturer;
}
/**
* Returns the end-user-visible model name for the device.
*/
@NonNull
public String getModel() {
return model;
}
/**
* Returns the constant representing the type of the device. This will usually be one of the values from the type constants in this class, but it's
* not required to be. Any other value should be treated as {@link #TYPE_UNKNOWN}.
*/
public int getType() {
return type;
}
/**
* Returns the serial number or other unique ID for the hardware.
* <p>
* Device UIDs are obfuscated based on the calling application's package name. Different applications will see different UIDs for the same
* {@link Device}. If two {@link Device} instances have the same underlying UID, they'll also have the same obfuscated UID within each app (but not across
* apps).
*/
@NonNull
public String getUid() {
return uid;
}
String getDeviceId() {
return manufacturer + ":" + model + ":" + uid;
}
int getPlatformType() {
return platformType;
}
/**
* Returns the Device representation of the local device, which can be used when defining local data sources.
*
* @noinspection deprecation
*/
public static Device getLocalDevice(Context context) {
@SuppressLint("HardwareIds") String uid = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
int type = TYPE_PHONE;
Configuration configuration = context.getResources().getConfiguration();
PackageManager packageManager = context.getPackageManager();
if (SDK_INT >= 20 && packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
type = TYPE_WATCH;
else if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) || packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
type = TYPE_UNKNOWN; // TV
else if (packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE))
type = TYPE_UNKNOWN; // Car
else if ((configuration.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) > Configuration.SCREENLAYOUT_SIZE_LARGE && configuration.smallestScreenWidthDp >= 600)
type = TYPE_TABLET;
else if (android.os.Build.PRODUCT.startsWith("glass_"))
type = TYPE_HEAD_MOUNTED;
return new Device(android.os.Build.MANUFACTURER, android.os.Build.MODEL, uid, type, 2);
}
@NonNull
@Override
public String toString() {
return ToStringHelper.name("Device").value(getDeviceId() + ":" + type + ":" + platformType).end();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<Device> CREATOR = findCreator(Device.class);
}

View file

@ -0,0 +1,490 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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 org.microg.gms.common.Hide;
/**
* A field represents one dimension of a data type. It defines the name and format of data. Unlike data type names, field names are not
* namespaced, and only need to be unique within the data type.
* <p>
* This class contains constants representing the field names of common data types, each prefixed with {@code FIELD_}. These can be used to
* access and set the fields via {@link DataPoint#getValue(com.google.android.gms.fitness.data.Field)}.
* <p>
* Fields for custom data types can be created using {@link DataTypeCreateRequest.Builder#addField(String, int)}.
*/
@SafeParcelable.Class
public class Field extends AbstractSafeParcelable {
/**
* Format constant indicating the field holds integer values.
*/
public static final int FORMAT_INT32 = 1;
/**
* Format constant indicating the field holds float values.
*/
public static final int FORMAT_FLOAT = 2;
/**
* Format constant indicating the field holds string values. Strings should be kept small whenever possible. Data streams with large string
* values and high data frequency may be down sampled.
*/
public static final int FORMAT_STRING = 3;
/**
* Format constant indicating the field holds a map of string keys to values. The valid key space and units for the corresponding value should
* be documented as part of the data type definition.
* <p>
* Map values can be set using {@link DataPoint.Builder#setField(com.google.android.gms.fitness.data.Field, java.util.Map)}.
* <p>
* Keys should be kept small whenever possible. Data streams with large keys and high data frequency may be down sampled.
*/
public static final int FORMAT_MAP = 4;
public static final int FORMAT_LONG = 5;
public static final int FORMAT_DOUBLE = 6;
public static final int FORMAT_OBJECT = 7;
/**
* Meal type constant representing that the meal type is unknown.
*/
public static final int MEAL_TYPE_UNKNOWN = 0;
/**
* Meal type constant representing a breakfast meal.
*/
public static final int MEAL_TYPE_BREAKFAST = 1;
/**
* Meal type constant representing a lunch meal.
*/
public static final int MEAL_TYPE_LUNCH = 2;
/**
* Meal type constant representing a dinner meal.
*/
public static final int MEAL_TYPE_DINNER = 3;
/**
* Meal type constant representing a snack meal.
*/
public static final int MEAL_TYPE_SNACK = 4;
/**
* Calcium amount in milligrams.
*/
@NonNull
public static final String NUTRIENT_CALCIUM = "calcium";
/**
* Calories in kcal.
*/
@NonNull
public static final String NUTRIENT_CALORIES = "calories";
/**
* Cholesterol in milligrams.
*/
@NonNull
public static final String NUTRIENT_CHOLESTEROL = "cholesterol";
/**
* Dietary fiber in grams.
*/
@NonNull
public static final String NUTRIENT_DIETARY_FIBER = "dietary_fiber";
/**
* Iron amount in milligrams.
*/
@NonNull
public static final String NUTRIENT_IRON = "iron";
/**
* Monounsaturated fat in grams.
*/
@NonNull
public static final String NUTRIENT_MONOUNSATURATED_FAT = "fat.monounsaturated";
/**
* Polyunsaturated fat in grams.
*/
@NonNull
public static final String NUTRIENT_POLYUNSATURATED_FAT = "fat.polyunsaturated";
/**
* Potassium in milligrams.
*/
@NonNull
public static final String NUTRIENT_POTASSIUM = "potassium";
/**
* Protein amount in grams.
*/
@NonNull
public static final String NUTRIENT_PROTEIN = "protein";
/**
* Saturated fat in grams.
*/
@NonNull
public static final String NUTRIENT_SATURATED_FAT = "fat.saturated";
/**
* Sodium in milligrams.
*/
@NonNull
public static final String NUTRIENT_SODIUM = "sodium";
/**
* Sugar amount in grams.
*/
@NonNull
public static final String NUTRIENT_SUGAR = "sugar";
/**
* Total carbohydrates in grams.
*/
@NonNull
public static final String NUTRIENT_TOTAL_CARBS = "carbs.total";
/**
* Total fat in grams.
*/
@NonNull
public static final String NUTRIENT_TOTAL_FAT = "fat.total";
/**
* Trans fat in grams.
*/
@NonNull
public static final String NUTRIENT_TRANS_FAT = "fat.trans";
/**
* Unsaturated fat in grams.
*/
@NonNull
public static final String NUTRIENT_UNSATURATED_FAT = "fat.unsaturated";
/**
* Vitamin A amount in International Units (IU). For converting from daily percentages, the FDA recommended 5000 IUs Daily Value can be
* used.
*/
@NonNull
public static final String NUTRIENT_VITAMIN_A = "vitamin_a";
/**
* Vitamin C amount in milligrams.
*/
@NonNull
public static final String NUTRIENT_VITAMIN_C = "vitamin_c";
/**
* The resistance type is unknown, unspecified, or not represented by any canonical values.
*/
public static final int RESISTANCE_TYPE_UNKNOWN = 0;
/**
* The user is using a barbell for resistance. The specified resistance should include the weight of the bar, as well as weights added to both
* sides.
*/
public static final int RESISTANCE_TYPE_BARBELL = 1;
/**
* The user is using a cable for resistance. When two cables are being used (one for each arm), the specified resistance should include the
* weight being pulled by one cable.
*/
public static final int RESISTANCE_TYPE_CABLE = 2;
/**
* The user is using dumbells for resistance. The specified resistance should include the weight of a single dumbell.
*/
public static final int RESISTANCE_TYPE_DUMBBELL = 3;
/**
* The user is using a kettlebell for resistance.
*/
public static final int RESISTANCE_TYPE_KETTLEBELL = 4;
/**
* The user is performing the exercise in a machine. The specified resistance should match the weight specified by the machine.
*/
public static final int RESISTANCE_TYPE_MACHINE = 5;
/**
* The user is using their own body weight for resistance.
*/
public static final int RESISTANCE_TYPE_BODY = 6;
/**
* The accuracy of an accompanied value (such as location).
*/
public static final com.google.android.gms.fitness.data.Field FIELD_ACCURACY = createFloatField("accuracy");
/**
* An activity type of {@link FitnessActivities}, encoded as an integer for efficiency. The activity value should be stored using
* {@link DataPoint.Builder#setActivityField(Field, String)}.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_ACTIVITY = createIntField("activity");
/**
* An altitude of a location represented as a float, in meters above sea level. Some location samples don't have an altitude value so this field
* might not be set.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_ALTITUDE = createOptionalFloatField("altitude");
/**
* An average value.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_AVERAGE = createFloatField("average");
/**
* A heart rate in beats per minute.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_BPM = createFloatField("bpm");
/**
* Calories in kcal.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_CALORIES = createFloatField("calories");
/**
* Circumference of a body part, in centimeters.
*
* @deprecated There is no applicable replacement field.
*/
@Deprecated
public static final com.google.android.gms.fitness.data.Field FIELD_CIRCUMFERENCE = createFloatField("circumference");
/**
* The confidence of an accompanied value, specified as a value between 0.0 and 100.0.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_CONFIDENCE = createFloatField("confidence");
/**
* A distance in meters.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_DISTANCE = createFloatField("distance");
/**
* A field containing duration. The units of the field are defined by the outer data type.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_DURATION = createIntField("duration");
/**
* A workout exercise, as represented by one of the constants in {@link WorkoutExercises}.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_EXERCISE = createStringField("exercise");
/**
* The corresponding food item for a nutrition entry.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_FOOD_ITEM = createOptionalStringField("food_item");
/**
* A height in meters.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_HEIGHT = createFloatField("height");
/**
* A high latitude of a location bounding box represented as a float, in degrees.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_HIGH_LATITUDE = createFloatField("high_latitude");
/**
* A high longitude of a location bounding box represented as a float, in degrees.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_HIGH_LONGITUDE = createFloatField("high_longitude");
/**
* Intensity of user activity, represented as a float.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_INTENSITY = createFloatField("intensity");
/**
* A latitude of a location represented as a float, in degrees.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_LATITUDE = createFloatField("latitude");
/**
* A longitude of a location represented as a float, in degrees.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_LONGITUDE = createFloatField("longitude");
/**
* A low latitude of a location bounding box represented as a float, in degrees.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_LOW_LATITUDE = createFloatField("low_latitude");
/**
* A low longitude of a location bounding box represented as a float, in degrees.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_LOW_LONGITUDE = createFloatField("low_longitude");
/**
* A maximum value.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_MAX = createFloatField("max");
/**
* A maximum int value.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_MAX_INT = createIntField("max");
/**
* Type of meal, represented as the appropriate int constant.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_MEAL_TYPE = createOptionalIntField("meal_type");
/**
* A minimum value.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_MIN = createFloatField("min");
/**
* A minimum int value.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_MIN_INT = createIntField("min");
/**
* A number of segments.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_NUM_SEGMENTS = createIntField("num_segments");
/**
* Nutrients ingested by the user, represented as a float map of nutrient key to quantity. The valid keys of the map are listed in this class using
* the {@code NUTRIENT_} prefix. The documentation for each key describes the unit of its value.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_NUTRIENTS = createMapField("nutrients");
/**
* How many occurrences of an event there were in a time range. For sample data types this should not be set to more than one.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_OCCURRENCES = createIntField("occurrences");
/**
* A percentage value, between 0 and 100.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_PERCENTAGE = createFloatField("percentage");
/**
* A count of repetitions for a single set of a workout exercise.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_REPETITIONS = createOptionalIntField("repetitions");
/**
* The resistance of the exercise (or weight), in kg.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_RESISTANCE = createOptionalFloatField("resistance");
/**
* The type of resistance used in this exercise, represented as the appropriate int constant.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_RESISTANCE_TYPE = createOptionalIntField("resistance_type");
/**
* A count of revolutions.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_REVOLUTIONS = createIntField("revolutions");
/**
* Revolutions per minute or rate per minute.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_RPM = createFloatField("rpm");
/**
* Sleep Segment type defined in {@link SleepStages}.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_SLEEP_SEGMENT_TYPE = createIntField("sleep_segment_type");
/**
* A speed in meter/sec.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_SPEED = createFloatField("speed");
/**
* A count of steps.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_STEPS = createIntField("steps");
/**
* Distance between steps in meters.
*
* @deprecated There is no applicable replacement field.
*/
@Deprecated
public static final com.google.android.gms.fitness.data.Field FIELD_STEP_LENGTH = createFloatField("step_length");
/**
* Volume in liters.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_VOLUME = createFloatField("volume");
/**
* Power in watts.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_WATTS = createFloatField("watts");
/**
* A weight in kilograms.
*/
public static final com.google.android.gms.fitness.data.Field FIELD_WEIGHT = createFloatField("weight");
public static final com.google.android.gms.fitness.data.Field FIELD_ACTIVITY_CONFIDENCE = createMapField("activity_confidence");
public static final com.google.android.gms.fitness.data.Field FIELD_ACTIVITY_DURATION_ASCENDING = createMapField("activity_duration.ascending");
public static final com.google.android.gms.fitness.data.Field FIELD_ACTIVITY_DURATION_DESCENDING = createMapField("activity_duration.descending");
public static final com.google.android.gms.fitness.data.Field FIELD_DURATION_OPTIONAL = createOptionalIntField("duration");
public static final com.google.android.gms.fitness.data.Field FIELD_FITNESS_DEVICE = createObjectField("google.android.fitness.Device");
public static final com.google.android.gms.fitness.data.Field FIELD_FITNESS_GOAL_V2 = createObjectField("google.android.fitness.GoalV2");
public static final com.google.android.gms.fitness.data.Field FIELD_FITNESS_SLEEP_ATTRIBUTES = createObjectField("google.android.fitness.SleepAttributes");
public static final com.google.android.gms.fitness.data.Field FIELD_FITNESS_SLEEP_SCHEDULE = createObjectField("google.android.fitness.SleepSchedule");
public static final com.google.android.gms.fitness.data.Field FIELD_FITNESS_PACED_WALKING_ATTRIBUTES = createObjectField("google.android.fitness.PacedWalkingAttributes");
public static final com.google.android.gms.fitness.data.Field FIELD_MET = createFloatField("met");
public static final com.google.android.gms.fitness.data.Field FIELD_PROBABILITY = createFloatField("probability");
public static final com.google.android.gms.fitness.data.Field FIELD_RESPIRATORY_RATE = createFloatField("respiratory_rate");
public static final com.google.android.gms.fitness.data.Field FIELD_SENSOR_TYPE = createIntField("sensor_type");
public static final com.google.android.gms.fitness.data.Field FIELD_SENSOR_VALUES = createDoubleField("sensor_values");
public static final com.google.android.gms.fitness.data.Field FIELD_TIMESTAMPS = createLongField("timestamps");
public static final com.google.android.gms.fitness.data.Field FIELD_ZONE_ID = createStringField("zone_id");
@Field(value = 1, getterName = "getName")
@NonNull
private final String name;
@Field(value = 2, getterName = "getFormat")
private final int format;
@Field(value = 3, getterName = "isOptional")
@Nullable
private final Boolean optional;
@Constructor
public Field(@Param(1) @NonNull String name, @Param(2) int format, @Param(3) @Nullable Boolean optional) {
this.name = name;
this.format = format;
this.optional = optional;
}
public Field(@NonNull String name, int format) {
this(name, format, null);
}
/**
* Returns the format of the field, as one of the format constant values.
*/
public int getFormat() {
return format;
}
/**
* Returns the name of the field.
*/
public String getName() {
return name;
}
public Boolean isOptional() {
return optional;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public final boolean equals(Object o) {
if (!(o instanceof com.google.android.gms.fitness.data.Field)) return false;
com.google.android.gms.fitness.data.Field field = (com.google.android.gms.fitness.data.Field) o;
return format == field.format && name.equals(field.name);
}
public static com.google.android.gms.fitness.data.Field createIntField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_INT32);
}
public static com.google.android.gms.fitness.data.Field createFloatField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_FLOAT);
}
public static com.google.android.gms.fitness.data.Field createStringField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_STRING);
}
public static com.google.android.gms.fitness.data.Field createMapField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_MAP);
}
public static com.google.android.gms.fitness.data.Field createLongField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_LONG);
}
public static com.google.android.gms.fitness.data.Field createDoubleField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_DOUBLE);
}
public static com.google.android.gms.fitness.data.Field createObjectField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_OBJECT);
}
public static com.google.android.gms.fitness.data.Field createOptionalIntField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_INT32, true);
}
public static com.google.android.gms.fitness.data.Field createOptionalFloatField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_FLOAT, true);
}
public static com.google.android.gms.fitness.data.Field createOptionalStringField(String name) {
return new com.google.android.gms.fitness.data.Field(name, FORMAT_STRING, true);
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<com.google.android.gms.fitness.data.Field> CREATOR = findCreator(com.google.android.gms.fitness.data.Field.class);
}

View file

@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2024 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;
import org.microg.gms.common.Hide;
import static com.google.android.gms.fitness.data.Field.FORMAT_FLOAT;
@Hide
@SafeParcelable.Class
public class MapValue extends AbstractSafeParcelable {
@Field(value = 1, getterName = "getFormat")
private final int format;
@Field(value = 2, getterName = "getValue")
private final float value;
@Constructor
public MapValue(@Param(1) int format, @Param(2) float value) {
this.format = format;
this.value = value;
}
@NonNull
public static MapValue ofFloat(float value) {
return new MapValue(FORMAT_FLOAT, value);
}
public int getFormat() {
return format;
}
float getValue() {
return value;
}
public float asFloat() {
if (format != FORMAT_FLOAT) throw new IllegalStateException("MapValue is not a float");
return value;
}
@Override
public int hashCode() {
return (int) value;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<MapValue> CREATOR = findCreator(MapValue.class);
}

View file

@ -0,0 +1,212 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.common.internal.safeparcel.SafeParcelableSerializer;
import java.util.concurrent.TimeUnit;
/**
* A Session represents a time interval with associated metadata. Sessions provide a mechanism to store user-visible groups of related
* stream data in a useful and shareable manner, and allows for easy querying of the data in a detailed or aggregated fashion. The start and
* end times for sessions will be controlled by applications, and can be used to represent user-friendly groupings of activities, such as "bike
* ride", "marathon training run". Any data in Google Fit which falls within this time range is implicitly associated with the session.
*/
@SafeParcelable.Class
public class Session extends AbstractSafeParcelable {
/**
* Name for the parcelable intent extra containing a session. It can be extracted using {@link #extract(Intent)}.
*/
@NonNull
public static final String EXTRA_SESSION = "vnd.google.fitness.session";
/**
* The common prefix for session MIME types. The MIME type for a particular session will be this prefix followed by the session's activity
* name.
* <p>
* The session's activity type is returned by {@link #getActivity()}. The MIME type can be computed from the activity using {@link #getMimeType(String)}
*/
@NonNull
public static final String MIME_TYPE_PREFIX = "vnd.google.fitness.session/";
@Field(value = 1, getterName = "getStartTimeMillis")
private final long startTimeMillis;
@Field(value = 2, getterName = "getEndTimeMillis")
private final long endTimeMillis;
@Field(value = 3, getterName = "getName")
@Nullable
private final String name;
@Field(value = 4, getterName = "getIdentifier")
@NonNull
private final String identifier;
@Field(value = 5, getterName = "getDescription")
@NonNull
private final String description;
@Field(value = 7, getterName = "getActivityType")
private final int activityType;
@Field(value = 8, getterName = "getApplication")
private final Application application;
@Field(value = 9, getterName = "getActiveTimeMillis")
@Nullable
private final Long activeTimeMillis;
@Constructor
Session(@Param(1) long startTimeMillis, @Param(2) long endTimeMillis, @Param(3) @Nullable String name, @Param(4) @NonNull String identifier, @Param(5) @NonNull String description, @Param(7) int activityType, @Param(8) Application application, @Param(9) @Nullable Long activeTimeMillis) {
this.startTimeMillis = startTimeMillis;
this.endTimeMillis = endTimeMillis;
this.name = name;
this.identifier = identifier;
this.description = description;
this.activityType = activityType;
this.application = application;
this.activeTimeMillis = activeTimeMillis;
}
/**
* Returns the active time period of the session.
* <p>
* Make sure to use {@link #hasActiveTime()} before using this method.
*
* @throws IllegalStateException {@link #hasActiveTime()} returns false.
*/
public long getActiveTime(@NonNull TimeUnit timeUnit) {
if (activeTimeMillis == null) throw new IllegalStateException("Active time is not set");
return timeUnit.convert(activeTimeMillis, TimeUnit.MILLISECONDS);
}
/**
* Returns the activity associated with this session, if set. Else returns {@link FitnessActivities#UNKNOWN}.
*/
@NonNull
public String getActivity() {
return null; // TODO
}
/**
* Returns the package name for the application responsible for adding the session. or {@code null} if unset/unknown. The {@link PackageManager} can be
* used to query relevant data on the application, such as the name, icon, or logo.
*/
@Nullable
public String getAppPackageName() {
if (application == null) return null;
return application.getPackageName();
}
/**
* Returns the description for this session.
*/
@NonNull
public String getDescription() {
return description;
}
/**
* Returns the end time for the session, in the given unit since epoch. If the session is ongoing (it hasn't ended yet), this will return 0.
*/
public long getEndTime(@NonNull TimeUnit timeUnit) {
return timeUnit.convert(endTimeMillis, TimeUnit.MILLISECONDS);
}
/**
* Returns the identifier for this session.
*/
@NonNull
public String getIdentifier() {
return identifier;
}
/**
* Returns the name for this session, if set.
*/
@Nullable
public String getName() {
return name;
}
/**
* Returns the start time for the session, in the given time unit since epoch. A valid start time is always set.
*/
public long getStartTime(@NonNull TimeUnit timeUnit) {
return timeUnit.convert(startTimeMillis, TimeUnit.MILLISECONDS);
}
/**
* Returns whether the session active time is set.
*/
public boolean hasActiveTime() {
return activeTimeMillis != null;
}
/**
* Returns whether the session is ongoing. If the session has ended, this will return false.
*/
public boolean isOngoing() {
return endTimeMillis == 0;
}
Application getApplication() {
return application;
}
int getActivityType() {
return activityType;
}
long getStartTimeMillis() {
return startTimeMillis;
}
long getEndTimeMillis() {
return endTimeMillis;
}
@Nullable
Long getActiveTimeMillis() {
return activeTimeMillis;
}
/**
* Extracts the session extra from the given intent, such as a callback intent received after registering to session start/end notifications, or an intent to view a session.
*
* @param intent The extracted Session, or {@code null} if the given intent does not contain a Session.
*/
@Nullable
public static Session extract(@NonNull Intent intent) {
return SafeParcelableSerializer.deserializeFromBytes(intent.getByteArrayExtra(EXTRA_SESSION), CREATOR);
}
/**
* Returns the MIME type which describes a Session for a particular activity. The MIME type is used in intents such as the session view
* intent.
*
* @param activity One of the activities in {@link FitnessActivities}.
*/
@NonNull
public static String getMimeType(@NonNull String activity) {
return MIME_TYPE_PREFIX + activity;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<Session> CREATOR = findCreator(Session.class);
}

View file

@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2024 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;
import org.microg.gms.common.Hide;
@SafeParcelable.Class
@Hide
public class SessionDataSet extends AbstractSafeParcelable {
public static final SafeParcelableCreatorAndWriter<SessionDataSet> CREATOR = findCreator(SessionDataSet.class);
@Field(1)
public final Session session;
@Field(2)
public final DataSet dataSet;
@Constructor
public SessionDataSet(@Param(1) Session session, @Param(2) DataSet dataSet) {
this.session = session;
this.dataSet = dataSet;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
}

View file

@ -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<Subscription> CREATOR = findCreator(Subscription.class);
}

View file

@ -0,0 +1,270 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.fitness.data;
import android.os.Bundle;
import android.os.Build.VERSION;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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 java.util.Map;
import static com.google.android.gms.fitness.data.Field.*;
/**
* Holder object for the value of a single field in a data point. Values are not constructed directly; a value for each field of the data type
* is created for each data point.
* <p>
* A field value has a particular format, and should be set and read using the format-specific methods. For instance, a float value should be set
* via {@link #setFloat(float)} and read via {@link #asFloat()}. Formats are defined as constants in {@link com.google.android.gms.fitness.data.Field}.
*/
@SafeParcelable.Class
public final class Value extends AbstractSafeParcelable {
@Field(value = 1, getterName = "getFormat")
public int format;
@Field(value = 2, getterName = "isSet")
public boolean set;
@Field(value = 3, getterName = "getValue")
public float value;
@Field(value = 4, getterName = "getStringValue")
public String stringValue;
@Field(value = 5, getterName = "getMapValue")
@Nullable
public Bundle mapValue;
@Field(value = 6, getterName = "getIntArrayValue")
public int[] intArrayValue;
@Field(value = 7, getterName = "getFloatArrayValue")
public float[] floatArrayValue;
@Field(value = 8, getterName = "getBlob")
public byte[] blob;
@Constructor
public Value(@Param(1) int format, @Param(2) boolean set, @Param(3) float value, @Param(4) String stringValue, @Param(5) @Nullable Bundle mapValue, @Param(6) int[] intArrayValue, @Param(7) float[] floatArrayValue, @Param(8) byte[] blob) {
this.format = format;
this.set = set;
this.value = value;
this.stringValue = stringValue;
this.mapValue = mapValue;
this.intArrayValue = intArrayValue;
this.floatArrayValue = floatArrayValue;
this.blob = blob;
}
Value(int format) {
this(format, false, 0f, null, null, null, null, null);
}
/**
* Returns the value of this object as an activity. The integer representation of the activity is converted to a String prior to returning.
*
* @return One of the constants from {@link FitnessActivities}; {@link FitnessActivities#UNKNOWN} if the object does not hold a valid activity
* representation
* @throws IllegalStateException If this {@link Value} does not correspond to a {@link com.google.android.gms.fitness.data.Field#FORMAT_INT32}
*/
public String asActivity() {
return null; // TODO
}
/**
* Returns the value of this object as a float.
*
* @throws IllegalStateException If this {@link Value} does not correspond to a {@link com.google.android.gms.fitness.data.Field#FORMAT_FLOAT}
*/
public float asFloat() {
if (format != FORMAT_FLOAT) throw new IllegalStateException("Value is not a float.");
return value;
}
/**
* Returns the value of this object as a int.
*
* @throws IllegalStateException If this {@link Value} does not correspond to a {@link com.google.android.gms.fitness.data.Field#FORMAT_INT32}
*/
public int asInt() {
if (format != FORMAT_INT32) throw new IllegalStateException("Value is not a int.");
return Float.floatToRawIntBits(this.value);
}
/**
* Returns the value of this object as a string.
*
* @throws IllegalStateException If this {@link Value} does not correspond to a {@link com.google.android.gms.fitness.data.Field#FORMAT_STRING}
*/
@NonNull
public String asString() {
if (format != FORMAT_STRING) throw new IllegalStateException("Value is not a string.");
if (stringValue == null) return "";
return stringValue;
}
/**
* Clears any value currently associated with the given {@code key} in the map. This method can be used only on map values.
*
* @param key The key you're modifying.
* @deprecated Use {@link DataPoint.Builder} to construct new {@link DataPoint} instances.
*/
@Deprecated
public void clearKey(String key) {
if (format != FORMAT_MAP) throw new IllegalStateException("Value is not a map.");
if (mapValue != null) {
mapValue.remove(key);
}
}
/**
* Returns the format of this value, which matches the appropriate field in the data type definition.
*
* @return One of the format constants from {@link com.google.android.gms.fitness.data.Field}.
*/
public int getFormat() {
return format;
}
/**
* Returns the value of the given key in the map as a {@link Float}.
*
* @return {@code null} if the key doesn't have a set value in the map.
* @throws IllegalStateException If this {@link Value} does not correspond to a {@link com.google.android.gms.fitness.data.Field#FORMAT_MAP}
*/
@Nullable
public Float getKeyValue(@NonNull String key) {
if (format != FORMAT_MAP) throw new IllegalStateException("Value is not a map.");
if (mapValue == null || !mapValue.containsKey(key)) {
return null;
}
mapValue.setClassLoader(MapValue.class.getClassLoader());
if (VERSION.SDK_INT >= 33) {
return mapValue.getParcelable(key, MapValue.class).asFloat();
} else {
//noinspection deprecation
return ((MapValue) mapValue.getParcelable(key)).asFloat();
}
}
/**
* Returns {@code true} if this object's value has been set by calling one of the setters.
*/
public boolean isSet() {
return set;
}
float getValue() {
return value;
}
String getStringValue() {
return stringValue;
}
@Nullable
Bundle getMapValue() {
return mapValue;
}
int[] getIntArrayValue() {
return intArrayValue;
}
float[] getFloatArrayValue() {
return floatArrayValue;
}
byte[] getBlob() {
return blob;
}
/**
* Updates this value object to represent an activity value. Activities are internally represented as integers for storage.
*
* @param activity One of the activities from {@link FitnessActivities}
* @deprecated Use {@link DataPoint.Builder} to construct new {@link DataPoint} instances.
*/
public void setActivity(String activity) {
setInt(0); // TODO
}
/**
* Updates this value object to represent a float value. Any previous values associated with this object are erased.
*
* @param value The new value that this objects holds.
* @deprecated Use {@link DataPoint.Builder} to construct new {@link DataPoint} instances.
*/
public void setFloat(float value) {
if (format != FORMAT_FLOAT) throw new IllegalStateException("Value is not a float.");
this.set = true;
this.value = value;
}
/**
* Updates this value object to represent an int value. Any previous values are erased.
*
* @param value The new value that this object holds.
* @deprecated Use {@link DataPoint.Builder} to construct new {@link DataPoint} instances.
*/
public void setInt(int value) {
if (format != FORMAT_INT32) throw new IllegalStateException("Value is not a int.");
this.set = true;
this.value = Float.intBitsToFloat(value);
}
/**
* Updates the value for a given key in the map to the given float value. Any previous values associated with the key are erased. This method
* can be used only on map values.
* <p>
* Key values should be kept small whenever possible. This is specially important for high frequency streams, since large keys may result in
* down sampling.
*
* @param key The key you're modifying.
* @param value The new value for the given key.
* @deprecated Use {@link DataPoint.Builder} to construct new {@link DataPoint} instances.
*/
public void setKeyValue(String key, float value) {
if (format != FORMAT_MAP) throw new IllegalStateException("Value is not a map.");
this.set = true;
if (mapValue == null) mapValue = new Bundle();
mapValue.putParcelable(key, MapValue.ofFloat(value));
}
void setMap(@NonNull Map<String, Float> value) {
if (format != FORMAT_MAP) throw new IllegalStateException("Value is not a map.");
this.set = true;
if (mapValue == null) mapValue = new Bundle();
for (String key : value.keySet()) {
mapValue.putParcelable(key, MapValue.ofFloat(value.get(key)));
}
}
/**
* Updates this value object to represent a string value. Any previous values associated with this object are erased.
* <p>
* String values should be kept small whenever possible. This is specially important for high frequency streams, since large values may result
* in down sampling.
*
* @param value The new value that this objects holds.
* @deprecated Use {@link DataPoint.Builder} to construct new {@link DataPoint} instances.
*/
public void setString(String value) {
if (format != FORMAT_STRING) throw new IllegalStateException("Value is not a string.");
this.set = true;
this.stringValue = value;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<Value> CREATOR = findCreator(Value.class);
}

View file

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2025 microG Project Team
* SPDX-License-Identifier: CC-BY-4.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
/**
* Contains the Google Fit data model.
*/
package com.google.android.gms.fitness.data;

View file

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2025 microG Project Team
* SPDX-License-Identifier: CC-BY-4.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
/**
* Contains the Google Fit APIs.
*/
package com.google.android.gms.fitness;

View file

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2023 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.IDailyTotalCallback;
@SafeParcelable.Class
public class DailyTotalRequest extends AbstractSafeParcelable {
@Field(1)
public IDailyTotalCallback callback;
@Field(2)
public DataType dataType;
@Field(4)
public Boolean unknownBool4;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DailyTotalRequest> CREATOR = findCreator(DailyTotalRequest.class);
}

View file

@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: 2023 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.data.Session;
import com.google.android.gms.fitness.internal.IStatusCallback;
import org.microg.gms.utils.ToStringHelper;
import java.util.List;
@SafeParcelable.Class
public class DataDeleteRequest extends AbstractSafeParcelable {
@Field(1)
public long startTimeMillis;
@Field(2)
public long endTimeMillis;
@Field(3)
public List<DataSource> dataSources;
@Field(4)
public List<DataType> dataTypes;
@Field(5)
public List<Session> sessions;
@Field(6)
public boolean deleteAllData;
@Field(7)
public boolean deleteAllSessions;
@Field(8)
public IStatusCallback callback;
@Field(10)
public boolean deleteByTimeRange;
@Field(11)
public boolean enableLocationCleanup;
@NonNull
@Override
public String toString() {
return ToStringHelper.name("DataDeleteRequest")
.field("startTimeMillis", startTimeMillis)
.field("endTimeMillis", endTimeMillis)
.field("dataSources", dataSources)
.field("dataTypes", dataTypes)
.field("sessions", sessions)
.field("deleteAllData", deleteAllData)
.field("deleteAllSessions", deleteAllSessions)
.field("callback", callback)
.field("deleteByTimeRange", deleteByTimeRange)
.field("enableLocationCleanup", enableLocationCleanup)
.end();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataDeleteRequest> CREATOR = findCreator(DataDeleteRequest.class);
}

View file

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2023 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.DataSet;
import com.google.android.gms.fitness.internal.IStatusCallback;
@SafeParcelable.Class
public class DataInsertRequest extends AbstractSafeParcelable {
@Field(1)
public DataSet dataSet;
@Field(2)
public IStatusCallback callback;
@Field(4)
public boolean isPrimary;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataInsertRequest> CREATOR = findCreator(DataInsertRequest.class);
}

View file

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.IDataPointChangesCallback;
@SafeParcelable.Class
public class DataPointChangesRequest extends AbstractSafeParcelable {
@Field(1)
public IDataPointChangesCallback callback;
@Field(2)
public Long unknownLong2;
@Field(3)
public int unknownInt3;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataPointChangesRequest> CREATOR = findCreator(DataPointChangesRequest.class);
}

View file

@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: 2023 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.IDataReadCallback;
import java.util.List;
@SafeParcelable.Class
public class DataReadRequest extends AbstractSafeParcelable {
@Field(1)
public List<DataType> dataTypes;
@Field(2)
public List<DataSource> dataSources;
@Field(3)
public long startTimeMillis;
@Field(4)
public long endTimeMillis;
@Field(5)
public List<DataType> aggregatedDataTypes;
@Field(6)
public List<DataSource> aggregatedDataSources;
@Field(7)
public int bucketType;
@Field(8)
public long bucketDurationMillis;
@Field(9)
public DataSource activityDataSource;
@Field(10)
public int limit;
@Field(12)
public boolean flushBufferBeforeRead;
@Field(13)
public boolean areServerQueriesEnabled;
@Field(14)
public IDataReadCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataReadRequest> CREATOR = findCreator(DataReadRequest.class);
}

View file

@ -0,0 +1,42 @@
/*
* SPDX-FileCopyrightText: 2023 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.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.Bucket;
import com.google.android.gms.fitness.data.DataSet;
import java.util.List;
@SafeParcelable.Class
public class DataReadResult extends AbstractSafeParcelable {
@Field(1)
public List<DataSet> rawDataSets;
@Field(2)
public Status status;
@Field(3)
public List<Bucket> rawBuckets;
@Field(5)
public int batchCount;
@Field(6)
public List<DataSet> uniqueDataSources;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataReadResult> CREATOR = findCreator(DataReadResult.class);
}

View file

@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2023 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;
@SafeParcelable.Class
public class DataSourceQueryParams extends AbstractSafeParcelable {
@Field(1)
public DataSource dataSource;
@Field(3)
public long unknownLong3;
@Field(4)
public long unknownLong4;
@Field(5)
public int unknownInt5;
@Field(6)
public int unknownInt6;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataSourceQueryParams> CREATOR = findCreator(DataSourceQueryParams.class);
}

View file

@ -0,0 +1,35 @@
/**
* SPDX-FileCopyrightText: 2024 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.internal.IDataTypeCallback;
import java.util.List;
@SafeParcelable.Class
public class DataTypeCreateRequest extends AbstractSafeParcelable {
public static final SafeParcelableCreatorAndWriter<DataTypeCreateRequest> CREATOR = findCreator(DataTypeCreateRequest.class);
@Field(1)
public String name;
@Field(2)
public List<com.google.android.gms.fitness.data.Field> fields;
@Field(3)
public IDataTypeCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
}

View file

@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
import android.app.PendingIntent;
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 DataUpdateListenerRegistrationRequest extends AbstractSafeParcelable {
@Field(1)
public DataSource dataSource;
@Field(2)
public DataType dataType;
@Field(3)
public PendingIntent pendingIntent;
@Field(4)
public IStatusCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataUpdateListenerRegistrationRequest> CREATOR = findCreator(DataUpdateListenerRegistrationRequest.class);
}

View file

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
import android.app.PendingIntent;
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.internal.IStatusCallback;
@SafeParcelable.Class
public class DataUpdateListenerUnregistrationRequest extends AbstractSafeParcelable {
@Field(1)
public PendingIntent pendingIntent;
@Field(2)
public IStatusCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataUpdateListenerUnregistrationRequest> CREATOR = findCreator(DataUpdateListenerUnregistrationRequest.class);
}

View file

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2023 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.DataSet;
import com.google.android.gms.fitness.internal.IStatusCallback;
@SafeParcelable.Class
public class DataUpdateRequest extends AbstractSafeParcelable {
@Field(1)
public Long startTimeMillis;
@Field(2)
public Long endTimeMillis;
@Field(3)
public DataSet dataSet;
@Field(4)
public IStatusCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DataUpdateRequest> CREATOR = findCreator(DataUpdateRequest.class);
}

View file

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.IDebugInfoCallback;
@SafeParcelable.Class
public class DebugInfoRequest extends AbstractSafeParcelable {
@Field(1)
public IDebugInfoCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<DebugInfoRequest> CREATOR = findCreator(DebugInfoRequest.class);
}

View file

@ -0,0 +1,29 @@
/**
* SPDX-FileCopyrightText: 2024 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.internal.IStatusCallback;
@SafeParcelable.Class
public class DisableFitRequest extends AbstractSafeParcelable {
public static final SafeParcelableCreatorAndWriter<DisableFitRequest> CREATOR = findCreator(DisableFitRequest.class);
@Field(1)
public IStatusCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
}

View file

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.IFileUriCallback;
@SafeParcelable.Class
public class GetFileUriRequest extends AbstractSafeParcelable {
@Field(1)
public IFileUriCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<GetFileUriRequest> CREATOR = findCreator(GetFileUriRequest.class);
}

View file

@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.ISyncInfoCallback;
@SafeParcelable.Class
public class GetSyncInfoRequest extends AbstractSafeParcelable {
@Field(1)
public ISyncInfoCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<GetSyncInfoRequest> CREATOR = findCreator(GetSyncInfoRequest.class);
}

View file

@ -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<ListSubscriptionsRequest> CREATOR = findCreator(ListSubscriptionsRequest.class);
}

View file

@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.IDataTypeCallback;
@SafeParcelable.Class
public class ReadDataTypeRequest extends AbstractSafeParcelable {
public static final SafeParcelableCreatorAndWriter<ReadDataTypeRequest> CREATOR = findCreator(ReadDataTypeRequest.class);
@Field(1)
public String name;
@Field(3)
public IDataTypeCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
}

View file

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.IReadRawCallback;
import java.util.List;
@SafeParcelable.Class
public class ReadRawRequest extends AbstractSafeParcelable {
@Field(1)
public IReadRawCallback callback;
@Field(3)
public List<DataSourceQueryParams> dataSourceQueryParams;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<ReadRawRequest> CREATOR = findCreator(ReadRawRequest.class);
}

View file

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.IReadStatsCallback;
import java.util.List;
@SafeParcelable.Class
public class ReadStatsRequest extends AbstractSafeParcelable {
@Field(1000)
public int versionCode;
@Field(1)
public IReadStatsCallback callback;
@Field(3)
public List<DataSource> dataSources;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<ReadStatsRequest> CREATOR = findCreator(ReadStatsRequest.class);
}

View file

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: 2023 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.internal.ISessionChangesCallback;
@SafeParcelable.Class
public class SessionChangesRequest extends AbstractSafeParcelable {
@Field(1)
public ISessionChangesCallback callback;
@Field(2)
public Long unknownLong2;
@Field(3)
public int unknownInt3;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<SessionChangesRequest> CREATOR = findCreator(SessionChangesRequest.class);
}

View file

@ -0,0 +1,42 @@
/*
* SPDX-FileCopyrightText: 2024 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.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.Session;
import com.google.android.gms.fitness.internal.IStatusCallback;
import java.util.List;
@SafeParcelable.Class
public class SessionInsertRequest extends AbstractSafeParcelable {
@Field(1)
public Session seesion;
@Field(2)
public List<DataSet> dataSets;
@Field(3)
public List<DataPoint> aggregateDataPoints;
@Field(4)
public IStatusCallback callback;
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<SessionInsertRequest> CREATOR = findCreator(SessionInsertRequest.class);
}

View file

@ -0,0 +1,54 @@
/*
* SPDX-FileCopyrightText: 2024 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.ISessionReadCallback;
import java.util.List;
@SafeParcelable.Class
public class SessionReadRequest extends AbstractSafeParcelable {
@Field(1)
public String sessionName;
@Field(2)
public String sessionId;
@Field(3)
public long StartTimeMillis;
@Field(4)
public long EndTimeMillis;
@Field(5)
public List<DataType> dataTypes;
@Field(6)
public List<DataSource> dataSources;
@Field(7)
public boolean includeSessionsFromAllApps;
@Field(8)
public boolean areServerQueriesEnabled;
@Field(9)
public List<String> excludedPackages;
@Field(10)
public ISessionReadCallback callback;
@Field(value = 12, defaultValue = "true")
public boolean areActivitySessionsIncluded;
@Field(value = 13, defaultValue = "false")
public boolean areSleepSessionsIncluded;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<SessionReadRequest> CREATOR = findCreator(SessionReadRequest.class);
}

View file

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.fitness.request;
import android.app.PendingIntent;
import android.os.Parcel;
import androidx.annotation.NonNull;
import com.google.android.gms.common.api.internal.IStatusCallback;
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 SessionRegistrationRequest extends AbstractSafeParcelable {
@Field(1)
public PendingIntent intent;
@Field(2)
public IStatusCallback callback;
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<SessionRegistrationRequest> CREATOR = findCreator(SessionRegistrationRequest.class);
}

Some files were not shown because too many files have changed in this diff Show more