Skip to content

Remove back button interception from SilentWebViewAuthorizationFragment, Fixes AB#3547597#3030

Merged
mohitc1 merged 6 commits intodevfrom
copilot/ab-3547597-remove-back-button-handling
Mar 19, 2026
Merged

Remove back button interception from SilentWebViewAuthorizationFragment, Fixes AB#3547597#3030
mohitc1 merged 6 commits intodevfrom
copilot/ab-3547597-remove-back-button-handling

Conversation

Copy link
Contributor

Copilot AI commented Mar 18, 2026

SilentWebViewAuthorizationFragment inherited AuthorizationFragment.onViewCreated(), which registers an enabled OnBackPressedCallback. During silent/invisible flows (SWAG), this caused the invisible fragment to intercept device back presses — either navigating within a hidden WebView or cancelling authorization unexpectedly — breaking host app back navigation.

Changes

SilentWebViewAuthorizationFragment.kt

  • Override onViewCreated() without calling super.onViewCreated(), skipping the OnBackPressedCallback registration in AuthorizationFragment
  • cancelAuthorizationOnTimeOut() is retained as private; timeout behavior is unaffected

SilentWebViewAuthorizationFragmentTest.kt

  • Robolectric-based test verifies that no OnBackPressedCallback is registered after onViewCreated() by launching a real SilentAuthorizationActivity and asserting onBackPressedDispatcher.hasEnabledCallbacks() returns false

changelog.txt

  • Added [PATCH] entry for this fix under vNext
Original prompt

Remove back button event handling for SilentWebViewAuthorizationFragment

Fixes AB#3547597

Problem

SilentWebViewAuthorizationFragment (in common/common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/) inherits back button handling from its parent chain: WebViewAuthorizationFragment -> AuthorizationFragment.

In AuthorizationFragment.onViewCreated(), an OnBackPressedCallback is registered via requireActivity().getOnBackPressedDispatcher().addCallback() that calls handleBackButtonPressed().

WebViewAuthorizationFragment.handleBackButtonPressed() checks mWebView.canGoBack() -- if true, it navigates back in the WebView; otherwise it calls cancelAuthorization(true).

Issue

SilentWebViewAuthorizationFragment is designed for silent, invisible flows (view is View.GONE, background transparent). It is used for SWAG (Sign-in-with Apple/Google) flows where the user should not see or interact with the WebView. However, because it inherits the back button callback registration from AuthorizationFragment.onViewCreated(), pressing the device back button during a silent flow will be intercepted by this invisible fragment -- either navigating back within an invisible WebView or canceling the authorization unexpectedly. This interferes with the host app's normal back navigation.

Solution

Override onViewCreated() in SilentWebViewAuthorizationFragment and skip the super.onViewCreated() call. This prevents AuthorizationFragment.onViewCreated() from ever registering the OnBackPressedCallback, so the silent fragment never intercepts back button events. The timeout logic (cancelAuthorizationOnTimeOut) is already invoked in the existing onViewCreated() override so it continues to work.

Files to modify

  • common/common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/SilentWebViewAuthorizationFragment.kt

Acceptance Criteria

  1. SilentWebViewAuthorizationFragment.onViewCreated() does NOT call super.onViewCreated()
  2. The cancelAuthorizationOnTimeOut timeout logic still fires correctly
  3. Back button presses during silent flows pass through to the host activity (not intercepted)
  4. Add a unit test verifying that onViewCreated() does not register an OnBackPressedCallback
  5. Existing silent flow behavior (timeout, transparent view, etc.) is preserved

Instructions

Follow .github/copilot-instructions.md strictly. Write new code in Kotlin. Use the Logger class for logging.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@github-actions
Copy link

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

@github-actions github-actions bot changed the title [WIP] [AB#3547597] Remove back button event handling for SilentWebViewAuthorizationFragment [WIP] [AB#3547597] Remove back button event handling for SilentWebViewAuthorizationFragment, Fixes AB#3547597 Mar 18, 2026
- Skip super.onViewCreated() call to prevent OnBackPressedCallback registration
- Add Robolectric unit test verifying no back press callback is registered

Co-authored-by: mohitc1 <22034758+mohitc1@users.noreply.github.com>
Copilot AI changed the title [WIP] [AB#3547597] Remove back button event handling for SilentWebViewAuthorizationFragment, Fixes AB#3547597 Remove back button interception from SilentWebViewAuthorizationFragment Mar 18, 2026
Copilot AI requested a review from mohitc1 March 18, 2026 23:29
@github-actions
Copy link

❌ Invalid work item number: AB#3547597

. Work item number must be a valid integer.

Click here to learn more.

1 similar comment
@github-actions
Copy link

❌ Invalid work item number: AB#3547597

. Work item number must be a valid integer.

Click here to learn more.

@github-actions github-actions bot changed the title Remove back button interception from SilentWebViewAuthorizationFragment Remove back button interception from SilentWebViewAuthorizationFragment, Fixes AB#3547597 Mar 18, 2026
@mohitc1
Copy link
Contributor

mohitc1 commented Mar 18, 2026

@copilot add changelog

Co-authored-by: mohitc1 <22034758+mohitc1@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 18, 2026

@copilot add changelog

Added changelog entry in 22ca1de:

- [PATCH] Remove back button interception from SilentWebViewAuthorizationFragment (#3030)

@mohitc1
Copy link
Contributor

mohitc1 commented Mar 19, 2026

@copilot update test to run without robolectic and activity. Just use kotlin mockito.

…ewAuthorizationFragment

Co-authored-by: mohitc1 <22034758+mohitc1@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 19, 2026

@copilot update test to run without robolectic and activity. Just use kotlin mockito.

Done in 63af79e. Replaced the Robolectric+Activity test with a plain mockito-kotlin spy test — no @RunWith, no Robolectric, no Activity required.

Key change to enable spying: cancelAuthorizationOnTimeOut was widened from private to @VisibleForTesting internal so Mockito can stub it.

The test:

  1. Creates a spy(SilentWebViewAuthorizationFragment())
  2. Stubs cancelAuthorizationOnTimeOut with doNothing() (so viewLifecycleOwner isn't needed)
  3. Calls onViewCreated(mockView, null) — if super.onViewCreated() were reached, requireActivity() would throw IllegalStateException, failing the test
  4. Verifies cancelAuthorizationOnTimeOut was called once

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:&#43;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:&#43;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:

@mohitc1
Copy link
Contributor

mohitc1 commented Mar 19, 2026

@copilot revert last commit

Co-authored-by: mohitc1 <22034758+mohitc1@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 19, 2026

@copilot revert last commit

Done in ac4d002. Reverted the mockito-kotlin spy test — both SilentWebViewAuthorizationFragmentTest.kt and SilentWebViewAuthorizationFragment.kt are back to their state from commit 22ca1de (Robolectric test restored, cancelAuthorizationOnTimeOut back to private).

@mohitc1 mohitc1 marked this pull request as ready for review March 19, 2026 00:32
@mohitc1 mohitc1 requested review from a team as code owners March 19, 2026 00:32
Copilot AI review requested due to automatic review settings March 19, 2026 00:32
Copy link
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

This PR prevents SilentWebViewAuthorizationFragment (used for silent/invisible WebView auth flows) from intercepting device back presses by skipping the OnBackPressedCallback registration inherited from AuthorizationFragment.

Changes:

  • Override SilentWebViewAuthorizationFragment.onViewCreated() to avoid registering the parent OnBackPressedCallback.
  • Add a Robolectric unit test intended to verify no enabled back-pressed callbacks are registered.
  • Add a vNext changelog entry documenting the fix.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/SilentWebViewAuthorizationFragment.kt Skips parent onViewCreated() to prevent silent fragment from registering a back-press callback.
common/src/test/java/com/microsoft/identity/common/internal/providers/oauth2/SilentWebViewAuthorizationFragmentTest.kt Adds a Robolectric test to assert no enabled OnBackPressedCallback is registered.
changelog.txt Adds a [PATCH] vNext entry for the back button interception fix.

You can also share your feedback on Copilot code review. Take the survey.

@mohitc1 mohitc1 merged commit ef19856 into dev Mar 19, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants