From 14c7b50c54e112f4fc201365e8984867b09e016d Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 17 Dec 2025 07:25:38 -0500 Subject: [PATCH 1/2] Create authentication snippets --- gradle/libs.versions.toml | 4 +- wear/.gitignore | 3 +- wear/build.gradle.kts | 12 +- wear/src/main/AndroidManifest.xml | 12 ++ .../wear/snippets/auth/CredentialManager.kt | 130 ++++++++++++++++++ .../example/wear/snippets/auth/OAuthDAG.kt | 81 +++++++++++ .../example/wear/snippets/auth/OAuthPKCE.kt | 114 +++++++++++++++ .../snippets/auth/WristDetectionUtility.kt | 39 ++++++ .../snippets/datalayer/DataLayerActivity.kt | 14 ++ .../snippets/datalayer/DataLayerService.kt | 25 ++++ 10 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt create mode 100644 wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt create mode 100644 wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt create mode 100644 wear/src/main/java/com/example/wear/snippets/auth/WristDetectionUtility.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e5a5196db..f3afdb4df 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ accompanist = "0.36.0" activityKtx = "1.12.1" android-googleid = "1.1.1" -androidGradlePlugin = "8.13.1" +androidGradlePlugin = "8.13.2" androidx-activity-compose = "1.12.1" androidx-appcompat = "1.7.0" androidx-compose-bom = "2025.12.00" @@ -96,6 +96,7 @@ wearOngoing = "1.1.0" wearToolingPreview = "1.0.0" webkit = "1.14.0" wearPhoneInteractions = "1.1.0" +wearRemoteInteractions = "1.1.0" [libraries] accompanist-adaptive = "com.google.accompanist:accompanist-adaptive:0.37.3" @@ -237,6 +238,7 @@ validator-push = { module = "com.google.android.wearable.watchface.validator:val wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearComposeMaterial" } wear-compose-material3 = { module = "androidx.wear.compose:compose-material3", version.ref = "wearComposeMaterial3" } androidx-wear-phone-interactions = { group = "androidx.wear", name = "wear-phone-interactions", version.ref = "wearPhoneInteractions" } +androidx-wear-remote-interactions = { group = "androidx.wear", name = "wear-remote-interactions", version.ref = "wearRemoteInteractions" } [plugins] android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } diff --git a/wear/.gitignore b/wear/.gitignore index 42afabfd2..9f014db8c 100644 --- a/wear/.gitignore +++ b/wear/.gitignore @@ -1 +1,2 @@ -/build \ No newline at end of file +/build +local.properties diff --git a/wear/build.gradle.kts b/wear/build.gradle.kts index 23efcf637..f27403e35 100644 --- a/wear/build.gradle.kts +++ b/wear/build.gradle.kts @@ -38,6 +38,9 @@ android { } kotlin { jvmToolchain(21) + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21) + } } buildFeatures { @@ -49,10 +52,6 @@ android { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } - kotlinOptions { - jvmTarget = "21" - } - testOptions { unitTests { isIncludeAndroidResources = true @@ -62,9 +61,14 @@ android { dependencies { implementation(libs.androidx.core.ktx) + implementation(libs.androidx.credentials) + implementation((libs.androidx.credentials.play.services.auth)) implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.ui) implementation(libs.androidx.wear.input) + implementation(libs.androidx.wear.phone.interactions) + implementation(libs.android.identity.googleid) + implementation(libs.androidx.wear.remote.interactions) val composeBom = platform(libs.androidx.compose.bom) implementation(composeBom) androidTestImplementation(composeBom) diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index ea4f18966..87f3bdffa 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -376,6 +376,18 @@ + + + + + + + diff --git a/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt b/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt new file mode 100644 index 000000000..9a9babb8a --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt @@ -0,0 +1,130 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.wear.snippets.auth + +import android.app.Activity +import android.content.Context +import android.os.Bundle +import androidx.credentials.Credential +import androidx.credentials.CredentialManager +import androidx.credentials.CustomCredential +import androidx.credentials.exceptions.GetCredentialCancellationException +import androidx.credentials.GetCredentialRequest +import androidx.credentials.GetCredentialResponse +import androidx.credentials.GetPasswordOption +import androidx.credentials.GetPublicKeyCredentialOption +import androidx.credentials.PasswordCredential +import androidx.credentials.PublicKeyCredential +import com.google.android.libraries.identity.googleid.GetGoogleIdOption + +/** + * Handles authentication operations using the Android Credential Manager API. + * + * This class interacts with an [AuthenticationServer] to facilitate sign-in processes + * using Passkeys, Passwords, and Sign-In With Google credentials. + * + * @param context The Android [Context] used to create the [CredentialManager]. + * @param authenticationServer The [AuthenticationServer] responsible for handling authentication requests. + */ +class CredentialManagerAuthenticator( + applicationContext: Context, + private val authenticationServer: AuthenticationServer, +) { + private val credentialManager: CredentialManager = CredentialManager.create(applicationContext) + + internal suspend fun signInWithCredentialManager(activity: Activity): Boolean { + // [START android_wear_credential_manager_secondary_fallback] + try { + val getCredentialResponse: GetCredentialResponse = + credentialManager.getCredential(activity, createGetCredentialRequest()) + return authenticate(getCredentialResponse.credential) + } catch (_: GetCredentialCancellationException) { + navigateToSecondaryAuthentication() + } + // [END android_wear_credential_manager_secondary_fallback] + return false + } + + +/**signInRequest + * Creates a [GetCredentialRequest] with standard Wear Credential types. + * + * @return A configured [GetCredentialRequest] ready to be used with [CredentialManager.getCredential]. + */ +private fun createGetCredentialRequest(): GetCredentialRequest { + return GetCredentialRequest( + credentialOptions = listOf( + GetPublicKeyCredentialOption(authenticationServer.getPublicKeyRequestOptions()), + GetPasswordOption(), + GetGoogleIdOption.Builder() + .setServerClientId(" { + return authenticationServer.loginWithPasskey(credential.authenticationResponseJson) + } + + is PasswordCredential -> { + return authenticationServer.loginWithPassword( + credential.id, + credential.password, + ) + } + + is CustomCredential -> { + return authenticationServer.loginWithCustomCredential( + credential.type, + credential.data, + ) + } + + else -> { + return false + } + } +} +} + + +/** Dummy authentication server would make network calls to your authentication server.*/ +class AuthenticationServer { + + /** Retrieves the public key credential request options from the authentication server.*/ + internal fun getPublicKeyRequestOptions(): String { return "result of network call" } + + fun loginWithPasskey(passkeyResponseJSON: String): Boolean { return true } + + fun loginWithPassword(username: String, password: String): Boolean { return true } + + fun loginWithCustomCredential(type: String, data: Bundle) : Boolean { return true } + +} + +/** Dummy navigation function. */ +fun navigateToSecondaryAuthentication() { +} diff --git a/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt b/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt new file mode 100644 index 000000000..cfd00f7d1 --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.wear.snippets.auth + +import android.content.Context +import android.content.Intent +import android.net.Uri +import androidx.wear.remote.interactions.RemoteActivityHelper + + +class DeviceGrantManager(private val context: Context) { + + /** Executes the full Device Grant flow. */ + suspend fun startAuthFlow(): Result { + // 1: Get device info from server + val deviceVerificationInfo = getFakeVerificationInfo() + + // 2: Show user code UI and open URL on phone + verifyDeviceAuthGrant(deviceVerificationInfo.verificationUri) + + // 3: Fetch for the DAG token + val token = fetchToken(deviceVerificationInfo.deviceCode) + + // Step 3: Use token to get profile + return retrieveUserProfile(token) + } + + // The response data when retrieving the verification + data class VerificationInfo( + val verificationUri: String, + val userCode: String, + val deviceCode: String, + ) + + /* A fake server call to retrieve */ + private fun getFakeVerificationInfo(): VerificationInfo{ + // An example of a verificationURI w + return VerificationInfo( + "your client backend", + userCode = "dummyUser", + deviceCode = "myDeviceCode", + ) + } + + // [START android_wear_auth_oauth_dag_authorize_device] + // Request access from the authorization server and receive Device Authorization Response. + private fun verifyDeviceAuthGrant(verificationUri: String) { + RemoteActivityHelper(context).startRemoteActivity( + Intent(Intent.ACTION_VIEW).apply { + addCategory(Intent.CATEGORY_BROWSABLE) + data = Uri.parse(verificationUri) + }, + null + ) + } + // [END android_wear_auth_oauth_dag_authorize_device] + + + private fun fetchToken(deviceCode: String): Result { + return Result.success("dummyToken") + + } + + private fun retrieveUserProfile(token: Result): Result { + return Result.success("dummyProfile") + + } +} diff --git a/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt b/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt new file mode 100644 index 000000000..5fd3e7ab7 --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.wear.snippets.auth + +import android.content.Context +import android.net.Uri +import androidx.wear.phone.interactions.authentication.CodeChallenge +import androidx.wear.phone.interactions.authentication.CodeVerifier +import androidx.wear.phone.interactions.authentication.OAuthRequest +import androidx.wear.phone.interactions.authentication.OAuthResponse +import androidx.wear.phone.interactions.authentication.RemoteAuthClient +import java.io.IOException +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +private const val CLIENT_ID = "my_fake_client_id" +private const val GOOGLE_OAUTH_BACKEND = "https://accounts.google.com/o/oauth2/v2/auth" +private const val GOOGLE_USER_INFO_SCOPE = "https://www.googleapis.com/auth/userinfo.profile" + +class WearOAuthPKCEManager(private val context: Context) { + + /** Start the authentication flow. */ + suspend fun startAuthFlow() { + val codeChallenge = CodeChallenge(CodeVerifier()) + + // Create the authorization Uri that will be shown to the user on the phone. This will + // be different depending on the OAuth backend your app uses, we use the google backend. + val uri = Uri.Builder() + .encodedPath(GOOGLE_OAUTH_BACKEND) + .appendQueryParameter("scope", GOOGLE_USER_INFO_SCOPE) + .build() + + // [START android_wear_auth_oauth_pkce_create_request] + val oauthRequest = OAuthRequest.Builder(context) + .setAuthProviderUrl(uri) + .setCodeChallenge(codeChallenge) + .setClientId(CLIENT_ID) + .build() + // [END android_wear_auth_oauth_pkce_create_request] + + // 1. Retrieve oauth code + val code = retrieveOAuthCode(oauthRequest, context).getOrElse {} + + // 2. Retrieve auth token from your backend. + val token = retrieveToken(code as String, oauthRequest).getOrElse {} + + // 3. Request user profile from your backend + retrieveUserProfile(token as String).getOrElse {} + } + + /** + * Use the [RemoteAuthClient] class to authorize the user. The library will handle the + * communication with the paired device, where the user can log in. + */ + private suspend fun retrieveOAuthCode( + oauthRequest: OAuthRequest, + context: Context + ): Result { + return suspendCoroutine { continuation -> + // [START android_wear_auth_oauth_pkce_send_request] + RemoteAuthClient.create(context).sendAuthorizationRequest( + request = oauthRequest, + executor = { command -> command?.run() }, + clientCallback = object : RemoteAuthClient.Callback() { + override fun onAuthorizationResponse( + request: OAuthRequest, + response: OAuthResponse + ) { + // Extract the token from the response, store it, and use it in requests. + continuation.resume(parseCodeFromResponse(response)) + } + override fun onAuthorizationError(request: OAuthRequest, errorCode: Int) { + // Handle Errors + continuation.resume(Result.failure(IOException("Authorization failed"))) + } + } + ) + // [END android_wear_auth_oauth_pkce_send_request] + } + } + + private fun parseCodeFromResponse(response: OAuthResponse): Result { + val responseUrl = response.responseUrl + val code = responseUrl?.getQueryParameter("code") + return if (code.isNullOrBlank()) { + Result.failure(IOException("Authorization failed")) + } else { + Result.success(code) + } + } + + /** Dummy token retrieval function. */ + private fun retrieveToken(code: String, oauthRequest: OAuthRequest): Result { + return Result.success("dummyToken") + } + + /** Dummy user profile retrieval. */ + private fun retrieveUserProfile(token: String): Result { + return Result.success("dummyProfile") + } +} diff --git a/wear/src/main/java/com/example/wear/snippets/auth/WristDetectionUtility.kt b/wear/src/main/java/com/example/wear/snippets/auth/WristDetectionUtility.kt new file mode 100644 index 000000000..12a636aa5 --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/auth/WristDetectionUtility.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import android.app.KeyguardManager +import android.content.Context +import androidx.core.content.getSystemService + +// This setting differs across OEMs, so you may want to check several in your detection function +// This one works for the pixel watch. +private const val PIXEL_WRIST_AUTOLOCK_SETTING_STATE = "wrist_detection_auto_locking_enabled" + +// [START android_wear_auth_wrist_detection] +fun isWristDetectionAutoLockingEnabled(context: Context): Boolean { + // [END android_wear_auth_wrist_detection] + // Use the keyguard manager to check for the presence of a lock mechanism + val keyguardManager = context.getSystemService() + val isSecured = keyguardManager?.isDeviceSecure == true + + // Use OEM-specific system settings to verify that on-body autolock is enabled. + val isWristDetectionOn = android.provider.Settings.Global.getInt( + context.contentResolver, PIXEL_WRIST_AUTOLOCK_SETTING_STATE, + 0 + ) == 1 + + return isSecured && isWristDetectionOn +} diff --git a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt index ecf3ff7e3..a0aebf591 100644 --- a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt +++ b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt @@ -124,6 +124,20 @@ private fun Context.sendImagePutDataMapRequest(): Task { } // [END android_wear_datalayer_imageputdatamap] +private fun Context.sendAuthTokenPutDataMapRequest(): Task { + // [START android_wear_datalayer_auth_token_sharing] + + val token = "..." // Auth token to transmit to the Wear OS device. + val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run { + dataMap.putString("token", token) + asPutDataRequest() + } + val putDataTask: Task = Wearable.getDataClient(this).putDataItem(putDataReq) + // [END android_wear_datalayer_auth_token_sharing] + + return putDataTask +} + class DataLayerActivity2 : ComponentActivity(), DataClient.OnDataChangedListener { // [START android_wear_datalayer_ondatachanged_assetextract] override fun onDataChanged(dataEvents: DataEventBuffer) { diff --git a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt index c69d5114b..0afe41824 100644 --- a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt +++ b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt @@ -21,6 +21,8 @@ import android.util.Log import com.google.android.gms.wearable.DataClient import com.google.android.gms.wearable.DataEvent import com.google.android.gms.wearable.DataEventBuffer +import com.google.android.gms.wearable.DataItem +import com.google.android.gms.wearable.DataMapItem import com.google.android.gms.wearable.Wearable import com.google.android.gms.wearable.WearableListenerService @@ -58,6 +60,29 @@ class DataLayerListenerService : WearableListenerService() { } // [END android_wear_datalayer_datalayerlistenerservice] +// [START android_wear_datalayer_auth_token_sharing_listener] +class AuthDataListenerService : WearableListenerService() { + override fun onDataChanged(dataEvents: DataEventBuffer) { + dataEvents.forEach { event -> + if (event.type == DataEvent.TYPE_CHANGED) { + val dataItemPath = event.dataItem.uri.path ?: "" + + if (dataItemPath.startsWith("/auth")) { + val token = DataMapItem.fromDataItem(event.dataItem) + .dataMap + .getString("token") + // Display an interstitial screen to notify the user that they're being signed + // in. Then, store the token and use it in network requests. +// [END android_wear_datalayer_auth_token_sharing_listener] + handleSignInSequence(token) + } + } + } + } + /** Dummy sign in handler. */ + fun handleSignInSequence(token: String?) {} +} + // [START android_wear_datalayer_ondatachangedlisteneer] class MainActivity : Activity(), DataClient.OnDataChangedListener { From f5a8d61ff73ebdec7650f2a4fd7a28c296e629f4 Mon Sep 17 00:00:00 2001 From: JohnZoellerG <122633070+JohnZoellerG@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:30:54 +0000 Subject: [PATCH 2/2] Apply Spotless --- .../wear/snippets/auth/CredentialManager.kt | 107 +++++++++--------- .../example/wear/snippets/auth/OAuthDAG.kt | 7 +- .../example/wear/snippets/auth/OAuthPKCE.kt | 1 + .../snippets/datalayer/DataLayerService.kt | 1 - 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt b/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt index 9a9babb8a..37148cf02 100644 --- a/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt +++ b/wear/src/main/java/com/example/wear/snippets/auth/CredentialManager.kt @@ -22,13 +22,13 @@ import android.os.Bundle import androidx.credentials.Credential import androidx.credentials.CredentialManager import androidx.credentials.CustomCredential -import androidx.credentials.exceptions.GetCredentialCancellationException import androidx.credentials.GetCredentialRequest import androidx.credentials.GetCredentialResponse import androidx.credentials.GetPasswordOption import androidx.credentials.GetPublicKeyCredentialOption import androidx.credentials.PasswordCredential import androidx.credentials.PublicKeyCredential +import androidx.credentials.exceptions.GetCredentialCancellationException import com.google.android.libraries.identity.googleid.GetGoogleIdOption /** @@ -59,70 +59,75 @@ class CredentialManagerAuthenticator( return false } - /**signInRequest - * Creates a [GetCredentialRequest] with standard Wear Credential types. - * - * @return A configured [GetCredentialRequest] ready to be used with [CredentialManager.getCredential]. - */ -private fun createGetCredentialRequest(): GetCredentialRequest { - return GetCredentialRequest( - credentialOptions = listOf( - GetPublicKeyCredentialOption(authenticationServer.getPublicKeyRequestOptions()), - GetPasswordOption(), - GetGoogleIdOption.Builder() - .setServerClientId(" { - return authenticationServer.loginWithPasskey(credential.authenticationResponseJson) - } - - is PasswordCredential -> { - return authenticationServer.loginWithPassword( - credential.id, - credential.password, - ) - } - - is CustomCredential -> { - return authenticationServer.loginWithCustomCredential( - credential.type, - credential.data, - ) - } - - else -> { - return false + * Routes the credential received from `getCredential` to the appropriate authentication + * type handler on the [AuthenticationServer]. + * + * @param credential The selected cre + * @return `true` if the credential was successfully processed and authenticated, else 'false'. + */ + private fun authenticate(credential: Credential): Boolean { + when (credential) { + is PublicKeyCredential -> { + return authenticationServer.loginWithPasskey(credential.authenticationResponseJson) + } + + is PasswordCredential -> { + return authenticationServer.loginWithPassword( + credential.id, + credential.password, + ) + } + + is CustomCredential -> { + return authenticationServer.loginWithCustomCredential( + credential.type, + credential.data, + ) + } + + else -> { + return false + } } } } -} - /** Dummy authentication server would make network calls to your authentication server.*/ class AuthenticationServer { /** Retrieves the public key credential request options from the authentication server.*/ - internal fun getPublicKeyRequestOptions(): String { return "result of network call" } - - fun loginWithPasskey(passkeyResponseJSON: String): Boolean { return true } + internal fun getPublicKeyRequestOptions(): String { + return "result of network call" + } - fun loginWithPassword(username: String, password: String): Boolean { return true } + fun loginWithPasskey(passkeyResponseJSON: String): Boolean { + return true + } - fun loginWithCustomCredential(type: String, data: Bundle) : Boolean { return true } + fun loginWithPassword(username: String, password: String): Boolean { + return true + } + fun loginWithCustomCredential(type: String, data: Bundle): Boolean { + return true + } } /** Dummy navigation function. */ diff --git a/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt b/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt index cfd00f7d1..eda42b27e 100644 --- a/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt +++ b/wear/src/main/java/com/example/wear/snippets/auth/OAuthDAG.kt @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.example.wear.snippets.auth import android.content.Context @@ -20,7 +21,6 @@ import android.content.Intent import android.net.Uri import androidx.wear.remote.interactions.RemoteActivityHelper - class DeviceGrantManager(private val context: Context) { /** Executes the full Device Grant flow. */ @@ -46,7 +46,7 @@ class DeviceGrantManager(private val context: Context) { ) /* A fake server call to retrieve */ - private fun getFakeVerificationInfo(): VerificationInfo{ + private fun getFakeVerificationInfo(): VerificationInfo { // An example of a verificationURI w return VerificationInfo( "your client backend", @@ -68,14 +68,11 @@ class DeviceGrantManager(private val context: Context) { } // [END android_wear_auth_oauth_dag_authorize_device] - private fun fetchToken(deviceCode: String): Result { return Result.success("dummyToken") - } private fun retrieveUserProfile(token: Result): Result { return Result.success("dummyProfile") - } } diff --git a/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt b/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt index 5fd3e7ab7..f5e583393 100644 --- a/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt +++ b/wear/src/main/java/com/example/wear/snippets/auth/OAuthPKCE.kt @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.example.wear.snippets.auth import android.content.Context diff --git a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt index 0afe41824..6affbdc46 100644 --- a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt +++ b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerService.kt @@ -21,7 +21,6 @@ import android.util.Log import com.google.android.gms.wearable.DataClient import com.google.android.gms.wearable.DataEvent import com.google.android.gms.wearable.DataEventBuffer -import com.google.android.gms.wearable.DataItem import com.google.android.gms.wearable.DataMapItem import com.google.android.gms.wearable.Wearable import com.google.android.gms.wearable.WearableListenerService