diff --git a/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt b/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt index e321ffcf2..8514e2bde 100644 --- a/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt +++ b/auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUI.kt @@ -93,13 +93,13 @@ class FirebaseAuthUI private constructor( */ internal val pendingReauth = MutableStateFlow(null) - /** How many composed [FirebaseAuthScreen]s can currently drive a reauthentication request. */ - + @Volatile @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) - var testCredentialManagerProvider: AuthProvider.Google.CredentialManagerProvider? = null + internal var testCredentialManagerProvider: AuthProvider.Google.CredentialManagerProvider? = null + @Volatile @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) - var testLoginManagerProvider: AuthProvider.Facebook.LoginManagerProvider? = null + internal var testLoginManagerProvider: AuthProvider.Facebook.LoginManagerProvider? = null /** * Checks whether a user is currently signed in. @@ -723,7 +723,7 @@ class FirebaseAuthUI private constructor( */ @JvmStatic @RestrictTo(RestrictTo.Scope.TESTS) - fun clearInstanceCache() { + internal fun clearInstanceCache() { instanceCache.clear() } diff --git a/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredential.kt b/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredential.kt index 535ace99d..1c22736d7 100644 --- a/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredential.kt +++ b/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredential.kt @@ -14,13 +14,16 @@ package com.firebase.ui.auth.credentialmanager +import androidx.annotation.RestrictTo + /** * Represents a password credential retrieved from the system credential manager. * * @property username The username/identifier associated with the credential * @property password The password associated with the credential */ -data class PasswordCredential( +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal data class PasswordCredential( val username: String, val password: String ) diff --git a/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredentialHandler.kt b/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredentialHandler.kt index c83f9a280..f70ab8261 100644 --- a/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredentialHandler.kt +++ b/auth/src/main/java/com/firebase/ui/auth/credentialmanager/PasswordCredentialHandler.kt @@ -22,6 +22,7 @@ import androidx.credentials.GetPasswordOption import androidx.credentials.PasswordCredential as AndroidPasswordCredential import androidx.credentials.exceptions.CreateCredentialCancellationException import androidx.credentials.exceptions.CreateCredentialException +import androidx.annotation.RestrictTo import androidx.credentials.exceptions.GetCredentialCancellationException import androidx.credentials.exceptions.GetCredentialException import androidx.credentials.exceptions.NoCredentialException @@ -31,14 +32,16 @@ import com.firebase.ui.auth.util.CredentialPersistenceManager * Provider interface for obtaining CredentialManager instances. * This allows test code to inject mock CredentialManager instances. */ -interface CredentialManagerProvider { +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal interface CredentialManagerProvider { fun getCredentialManager(context: Context): CredentialManager } /** * Default implementation that creates a real CredentialManager instance. */ -class DefaultCredentialManagerProvider : CredentialManagerProvider { +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal class DefaultCredentialManagerProvider : CredentialManagerProvider { override fun getCredentialManager(context: Context): CredentialManager { return CredentialManager.create(context) } @@ -53,23 +56,17 @@ class DefaultCredentialManagerProvider : CredentialManagerProvider { * @property context The Android context used for credential operations * @property provider Optional provider for testing purposes */ -class PasswordCredentialHandler( +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal class PasswordCredentialHandler( private val context: Context, provider: CredentialManagerProvider? = null ) { companion object { /** * Test-only provider for injecting mock CredentialManager instances. - * Set this in your test setup to override the default CredentialManager. - * - * Example: - * ``` - * PasswordCredentialHandler.testCredentialManagerProvider = object : CredentialManagerProvider { - * override fun getCredentialManager(context: Context) = mockCredentialManager - * } - * ``` */ @Volatile + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) var testCredentialManagerProvider: CredentialManagerProvider? = null /** @@ -178,7 +175,8 @@ class PasswordCredentialHandler( /** * Base exception for password credential operations. */ -open class PasswordCredentialException( +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal open class PasswordCredentialException( message: String, cause: Throwable? = null ) : Exception(message, cause) @@ -186,7 +184,8 @@ open class PasswordCredentialException( /** * Exception thrown when a password credential operation is cancelled by the user. */ -class PasswordCredentialCancelledException( +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal class PasswordCredentialCancelledException( message: String, cause: Throwable? = null ) : PasswordCredentialException(message, cause) @@ -194,7 +193,8 @@ class PasswordCredentialCancelledException( /** * Exception thrown when no password credentials are found. */ -class PasswordCredentialNotFoundException( +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal class PasswordCredentialNotFoundException( message: String, cause: Throwable? = null ) : PasswordCredentialException(message, cause) diff --git a/e2eTest/build.gradle.kts b/e2eTest/build.gradle.kts index b7b294807..d8880b900 100644 --- a/e2eTest/build.gradle.kts +++ b/e2eTest/build.gradle.kts @@ -85,4 +85,25 @@ tasks.register("e2eTest") { classpath = debug.classpath doNotTrackState("Always run e2e emulator tests to mirror Android Studio") -} \ No newline at end of file +} + +// Give this module's unit-test compilations friend access to `:auth` internals, so the e2e +// tests can drive test seams that are `internal` rather than forcing those seams to stay +// public API. Deliberately scoped to the unit-test tasks: the production source set has no +// reason to reach into `:auth`. +// +// `libraries` is filtered rather than naming the jar it resolves to, because that jar lives +// under AGP's `intermediates` tree, which is an implementation detail and moves on an AGP bump. +// `layout.settingsDirectory` addresses `:auth`'s build directory without going through +// `project(":auth")`, which would be cross-project model access. +// +// Appending `-Xfriend-paths` to `compilerOptions.freeCompilerArgs` does not work: KGP generates +// that flag itself from the typed `friendPaths` property, so a hand-appended copy is ignored. +// Pointing at `auth/build/tmp/kotlin-classes/debug` does not work either, because `:e2eTest` +// never sees that directory. +val authBuildDir = layout.settingsDirectory.dir("auth/build").asFile.absolutePath + File.separator +tasks.withType() + .matching { it.name.contains("UnitTest") } + .configureEach { + friendPaths.from(libraries.filter { it.absolutePath.startsWith(authBuildDir) }) + }