AuthTab: Common Infrastructure (feature flag + AuthTabManager + dep bump + parameters), Fixes AB#3533465#2993
Draft
AuthTab: Common Infrastructure (feature flag + AuthTabManager + dep bump + parameters), Fixes AB#3533465#2993
Conversation
|
✅ Work item link check complete. Description contains link AB#3533465 to an Azure Boards work item. |
…ger, dep bump, parameters Co-authored-by: shahzaibj <37125644+shahzaibj@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add feature flag and AuthTabManager implementation, Fixes AB#3533465
AuthTab: Common Infrastructure (feature flag + AuthTabManager + dep bump + parameters)
Mar 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lays the groundwork for AuthTab support — a Chrome 137+ API that delivers auth results via an in-process
ActivityResultLaunchercallback, eliminating the fragile intent-redirect mechanism used by Custom Tabs. This PR adds the foundational artifacts only; fragment/strategy wiring is a separate PBI.Changes
CommonFlight.ENABLE_AUTH_TAB— New feature flag inCommonFlight.java, defaults tofalse.AuthTabManager.kt— New class (non-singleton; one per fragment) encapsulating all AuthTab API interactions:isAuthTabSupported(context)— static, wrapsCustomTabsClient.isAuthTabSupported()with safe fallbackregisterLauncher(caller, onResult)— must be called on main thread before fragment CREATED state; returnsthisfor chaininglaunch(authUrl, redirectScheme)/launchWithHttpsRedirect(authUrl, host, path)— throwIllegalStateExceptionif launcher not registeredmapAuthResultToRawResult(authResult)— maps allAuthTabIntent.AuthResultcodes toRawAuthorizationResultResult mapping:
AuthTabIntentresultRawAuthorizationResultRESULT_OK+ non-null URIfromRedirectUri(uri)RESULT_OK+ null URIfromException(ClientException("authorization_result_not_found", …))RESULT_CANCELEDfromResultCode(CANCELLED)RESULT_VERIFICATION_FAILEDfromException(ClientException("auth_tab_verification_failed", …))RESULT_VERIFICATION_TIMED_OUTfromException(ClientException("auth_tab_verification_timed_out", …))fromException(ClientException("auth_tab_unknown_result", …))AuthorizationActivityParameters.kt— Addedval useAuthTab: Boolean = false(last constructor param,@JvmOverloads-safe) andcompanion object { const val USE_AUTH_TAB = "com.microsoft.identity.USE_AUTH_TAB" }.gradle/versions.gradle—browserVersionbumped1.7.0→1.9.0to unlock theAuthTabIntentAPI. Existing Custom Tabs paths are unaffected.AuthTabManagerTest.kt— 12 Robolectric + MockK tests covering:isAuthTabSupported(true/false/exception), allmapAuthResultToRawResultbranches including unknown codes,launchguard, launcher field wiring, and end-to-end callback delivery.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
dl.google.com/usr/bin/curl curl -s REDACTED(dns block)/usr/bin/wget wget -q -O /tmp/browser-meta.xml REDACTED(dns block)/usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Xmx3072m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant(dns block)identitydivision.pkgs.visualstudio.com/usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Xmx3072m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant(dns block)www.puppycrawl.com/opt/hostedtoolcache/CodeQL/2.24.2/x64/codeql/tools/linux64/java/bin/java /opt/hostedtoolcache/CodeQL/2.24.2/x64/codeql/tools/linux64/java/bin/java -jar /opt/hostedtoolcache/CodeQL/2.24.2/x64/codeql/xml/tools/xml-extractor.jar --fileList=/tmp/codeql-scratch-b2678d0398b00160/dbs/java/working/files-to-index17484626772427144413.list --sourceArchiveDir=/tmp/codeql-scratch-b2678d0398b00160/dbs/java/src --outputDir=/tmp/codeql-scratch-b2678d0398b00160/dbs/java/trap/java(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
AuthTab: Common Infrastructure (feature flag + AuthTabManager + dep bump + parameters)
Fixes AB#3533465
Follow .github/copilot-instructions.md strictly.
Objective
Lay the groundwork for AuthTab support by adding the feature flag, the new AuthTabManager class, bumping the androidx.browser dependency to 1.9.0, and adding useAuthTab to AuthorizationActivityParameters.
Why
AuthTab is a new Chrome API (Chrome 137+, androidx.browser:browser:1.9.0) that replaces Custom Tabs for authentication flows. It delivers results via an in-process ActivityResultLauncher callback instead of intent-redirect chains, eliminating the fragile static-field/intent-filter redirect mechanism. This PBI creates the foundational artifacts that the integration PBI will wire into the fragment/strategy classes.
What to build
1. CommonFlight.ENABLE_AUTH_TAB
Add a new enum value to CommonFlight.java in common4j.
File: common4j/src/main/com/microsoft/identity/common/java/flighting/CommonFlight.java
Add the following entry to the enum (follow the existing pattern - each entry has a Javadoc comment, a string key, and a default value):
`java
/**
*/
ENABLE_AUTH_TAB("EnableAuthTab", false),
`
2. AuthTabManager.kt
Create a new Kotlin class.
File: common/src/main/java/com/microsoft/identity/common/internal/ui/browser/AuthTabManager.kt
Package: com.microsoft.identity.common.internal.ui.browser
This class encapsulates all AuthTab API interactions:
Companion object method isAuthTabSupported(context: Context): Boolean - Calls CustomTabsClient.isAuthTabSupported(context). Wraps in try/catch returning false on failure. Logs via Logger.warn() on error. Thread-safe, can be called from any thread.
Instance field mLauncher: ActivityResultLauncher? - Holds the registered launcher.
registerLauncher(caller: ActivityResultCaller, onResult: (RawAuthorizationResult) -> Unit): AuthTabManager - Calls AuthTabIntent.registerActivityResultLauncher(caller) { authResult -> ... }. Inside the lambda, calls mapAuthResultToRawResult(authResult) and invokes onResult. Returns this for chaining. Logs registration. MUST be called on main thread before fragment CREATED state.
launch(authUrl: Uri, redirectScheme: String) - Throws IllegalStateException if mLauncher is null. Builds AuthTabIntent.Builder().build() and calls authTabIntent.launch(launcher, authUrl, redirectScheme).
launchWithHttpsRedirect(authUrl: Uri, redirectHost: String, redirectPath: String) - Same pattern for HTTPS redirects.
mapAuthResultToRawResult(authResult: AuthTabIntent.AuthResult): RawAuthorizationResult - Maps result codes:
Imports needed:
DO NOT make this a singleton. Each fragment instance gets its own AuthTabManager. DO NOT store Context as a field. Add MIT license header matching the project convention.
3. AuthorizationActivityParameters.kt
File: common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/AuthorizationActivityParameters.kt
This is a Kotlin data class with a @jvmoverloads constructor. Add a new constructor parameter:
kotlin val useAuthTab: Boolean = false,Add it at the end of the constructor parameters. Also add a companion object constant:
kotlin companion object { const val USE_AUTH_TAB = "com.microsoft.identity.USE_AUTH_TAB" }4. versions.gradle - dependency bump
File: gradle/versions.gradle
Change: browserVersion = "1.7.0"
To: browserVersion = "1.9.0"
This is safe and backward-compatible. The new AuthTabIntent class is never referenced unless the feature flag is enabled.
5. Unit tests for AuthTabManager
File: common/src/test/java...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.