Skip to content

[AuthTab] Rework Common to provider-based strategy selection (Option 1B, no browser 1.9 APIs), Fixes AB#3561426#3093

Merged
p3dr0rv merged 15 commits into
devfrom
copilot/ab-3561426-rework-authtab-strategy-again
May 21, 2026
Merged

[AuthTab] Rework Common to provider-based strategy selection (Option 1B, no browser 1.9 APIs), Fixes AB#3561426#3093
p3dr0rv merged 15 commits into
devfrom
copilot/ab-3561426-rework-authtab-strategy-again

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 22, 2026

Summary

This PR implements the Common-side of Auth Tab support for the switch-browser flow using Option 1B — a provider-based architecture that keeps Common free of browser:1.9.0 dependencies.

Companion PR: Broker #157 implements the concrete Auth Tab classes that register with this provider.

Why Option 1B?

Common uses androidx.browser:browser:1.7.0. Auth Tab requires browser:1.9.0. Bumping Common to 1.9.0 would cascade to MSAL, OneAuth, and ADAL. Instead, Common defines interfaces and a registry; Broker (which already has browser:1.9.0) provides the implementation at runtime.

This supersedes the closed PR #3078 which attempted to put Auth Tab implementation directly in Common (Option 1).


Architecture

graph TB
    subgraph "Common module · browser:1.7.0"
        SBA["SwitchBrowserActivity"]
        ATSP["AuthTabStrategyProvider\n(singleton registry)"]
        BLS["«interface»\nBrowserLaunchStrategy"]
        CTLS["CustomTabsLaunchStrategy\n(fallback)"]
        
        SBA -->|"1. isAuthTabSupported?"| ATSP
        SBA -->|"2. createStrategy() or fallback"| ATSP
        ATSP -.->|"delegates to registered impl"| BLS
        SBA -->|"fallback"| CTLS
        CTLS -.->|implements| BLS
    end
    
    subgraph "Broker module · browser:1.9.0"
        ATLS["AuthTabLaunchStrategy"]
        ATM["AuthTabManager"]
        REG["AuthTabRegistration"]
        
        ATLS -.->|implements| BLS
        ATLS -->|uses| ATM
        ATM -->|"wraps"| ATI["AuthTabIntent API\n(browser 1.9.0)"]
        REG -->|"register(factory, isSupported)"| ATSP
    end
    
    BCP["BrokerContentProvider\n.onCreate()"] -->|"calls at process init"| REG

    style ATSP fill:#4a9eff,color:#fff
    style BLS fill:#2d7d46,color:#fff
    style CTLS fill:#2d7d46,color:#fff
    style ATLS fill:#c75000,color:#fff
    style ATM fill:#c75000,color:#fff
    style REG fill:#c75000,color:#fff
Loading

Runtime Flow

sequenceDiagram
    participant BCP as BrokerContentProvider
    participant REG as AuthTabRegistration
    participant ATSP as AuthTabStrategyProvider
    participant SBA as SwitchBrowserActivity
    participant ATLS as AuthTabLaunchStrategy
    participant CTLS as CustomTabsLaunchStrategy

    Note over BCP: App process starts
    BCP->>REG: onCreate()
    REG->>ATSP: register(factory, isSupported)
    
    Note over SBA: eSTS returns switch_browser
    SBA->>ATSP: isAuthTabSupported(ctx, browserPkg)?
    
    alt Auth Tab supported
        ATSP-->>SBA: true
        SBA->>ATSP: createStrategy(activity, onResult)
        ATSP-->>SBA: AuthTabLaunchStrategy
        SBA->>ATLS: launch()
        ATLS-->>SBA: result via callback
    else Auth Tab not supported / not registered
        ATSP-->>SBA: false
        SBA->>CTLS: new CustomTabsLaunchStrategy()
        SBA->>CTLS: launch()
        Note over SBA: Handles cancel via onResume
    end
Loading

What Changed

New Files

File Purpose
AuthTabStrategyProvider.kt Singleton registry — Broker registers its Auth Tab factory + support checker here at process init
BrowserLaunchStrategy.kt Interface contract: launch(), handlesCancellationOnResume(), cleanup()
CustomTabsLaunchStrategy.kt Wraps existing Custom Tabs behavior behind BrowserLaunchStrategy interface (fallback path)
AuthTabStrategyProviderTest.kt Tests for registration, delegation, availability, and thread-safety
SwitchBrowserActivityTest.kt Tests for provider-driven strategy selection + Custom Tabs fallback

Modified Files

File Change
SwitchBrowserActivity.kt Refactored onCreate() to query AuthTabStrategyProvider for strategy selection instead of hardcoded Custom Tabs path
SwitchBrowserChallenge.kt Extended to carry feature flag and browser package for Auth Tab decision
SwitchBrowserRequestHandler.kt Passes feature flag state and browser package into SwitchBrowserChallenge
SwitchBrowserUriHelper.kt Added buildResumeBrowserUri() helper for constructing the redirect URI used by Auth Tab
SwitchBrowserProtocolCoordinator.kt Removed duplicate URI building logic (moved to SwitchBrowserUriHelper)
SpanName.java Added telemetry span names for Auth Tab flows

Key Design Decisions

  1. Atomic registrationAuthTabStrategyProvider stores the factory + support checker in a single @Volatile data class reference, preventing half-registered states in multi-threaded scenarios
  2. No browser 1.9.0 imports — Common only uses android.content.Context, FragmentActivity, and Bundle in its provider API. All AuthTabIntent / CustomTabsClient.isAuthTabSupported calls live in Broker
  3. Fallback guarantee — If the provider is not registered (e.g., older Broker) or the browser doesn't support Auth Tab, SwitchBrowserActivity falls back to CustomTabsLaunchStrategy automatically

Fixes AB#3561426

@github-actions
Copy link
Copy Markdown

✅ Work item link check complete. Description contains link AB#3561426 to an Azure Boards work item.

@github-actions github-actions Bot changed the title [WIP] Rework AuthTab implementation for Option 1B [WIP] Rework AuthTab implementation for Option 1B, Fixes AB#3561426 Apr 22, 2026
Copilot AI changed the title [WIP] Rework AuthTab implementation for Option 1B, Fixes AB#3561426 [AuthTab] Rework Common to provider-based strategy selection (Option 1B, no browser 1.9 APIs) Apr 22, 2026
Copilot AI requested a review from p3dr0rv April 22, 2026 00:12
@github-actions github-actions Bot changed the title [AuthTab] Rework Common to provider-based strategy selection (Option 1B, no browser 1.9 APIs) [AuthTab] Rework Common to provider-based strategy selection (Option 1B, no browser 1.9 APIs), Fixes AB#3561426 Apr 22, 2026
@p3dr0rv
Copy link
Copy Markdown
Contributor

p3dr0rv commented Apr 22, 2026

@copilot
e: file:///D:/a/1/s/common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/AuthTabStrategyProvider.kt:42:5 Nested and local type aliases are not supported
e: file:///D:/a/1/s/common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/AuthTabStrategyProvider.kt:47:5 Nested and local type aliases are not supported

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 22, 2026

@copilot
e: file:///D:/a/1/s/common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/AuthTabStrategyProvider.kt:42:5 Nested and local type aliases are not supported
e: file:///...

Fixed in 40930ec. I removed the nested typealiases in AuthTabStrategyProvider and replaced them with equivalent function-type properties so it compiles with the current Kotlin setup.

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
    • Triggering command: /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
    • Triggering command: /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)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Switch Browser (AuthTab) integration in Common to avoid androidx.browser:browser:1.9+ APIs by selecting browser launch behavior via an externally-registered provider, while keeping a Custom Tabs fallback strategy within Common.

Changes:

  • Introduces a provider registry (AuthTabStrategyProvider) for Auth Tab support checks + strategy creation (no browser 1.9 APIs in Common).
  • Adds a BrowserLaunchStrategy abstraction and a CustomTabsLaunchStrategy implementation to encapsulate existing Custom Tabs launch/cleanup logic.
  • Updates SwitchBrowserActivity to select AuthTab via provider when supported, otherwise fall back to Custom Tabs; adds focused Robolectric tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/AuthTabStrategyProvider.kt Adds singleton registry for externally-provided AuthTab strategy/support checks.
common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/BrowserLaunchStrategy.kt Adds strategy interface for browser launch, cancellation behavior, and cleanup.
common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/CustomTabsLaunchStrategy.kt Extracts Custom Tabs launch/cleanup behavior behind the strategy interface.
common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/SwitchBrowserActivity.kt Switches to provider-driven strategy selection + delegates lifecycle cleanup to strategy.
common/src/test/java/com/microsoft/identity/common/internal/providers/oauth2/AuthTabStrategyProviderTest.kt Adds tests for provider registration, delegation, and default/unavailable behavior.
common/src/test/java/com/microsoft/identity/common/internal/providers/oauth2/SwitchBrowserActivityTest.kt Adds tests for strategy selection (provider path + Custom Tabs fallback).
common/build.gradle Updates MockK test dependency version.

Comment thread common/build.gradle
p3dr0rv added 4 commits May 1, 2026 09:58
…n object for strategy and support checker, enhancing thread safety. Update tests to verify behavior with fallback strategies.
…ctivity creation, ensuring accurate verification of strategy launches.
@p3dr0rv p3dr0rv added the Skip-Consumers-Check Only include this if making a breaking change purposefully, and there is an MSAL/ADAL/Broker PR label May 1, 2026
p3dr0rv added 2 commits May 1, 2026 13:38
…or across environments by using a mock flights provider. Remove unnecessary looper idling during activity creation.
…or deterministic flight behavior across environments, replacing the previous MockCommonFlightsManager implementation.
@p3dr0rv
Copy link
Copy Markdown
Contributor

p3dr0rv commented May 1, 2026

@copilot UPDATE CHANGELOG

Copilot AI requested a review from a team as a code owner May 1, 2026 22:22
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 1, 2026

@copilot UPDATE CHANGELOG

Updated in 161b5a0. Added the vNext changelog entry for the AuthTab provider-based strategy selection rework.

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
    • Triggering command: /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
    • Triggering command: /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)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of p3dr0rv May 1, 2026 22:23
@p3dr0rv p3dr0rv merged commit c217af2 into dev May 21, 2026
23 of 24 checks passed
@p3dr0rv p3dr0rv deleted the copilot/ab-3561426-rework-authtab-strategy-again branch May 21, 2026 00:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Skip-Consumers-Check Only include this if making a breaking change purposefully, and there is an MSAL/ADAL/Broker PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants