Skip to content

[url_launcher] supportsCloseForLaunchMode calls supportsMode, so it answers "can this mode be launched" instead of "can it be closed" #192758

Closed
flutter/packages
#12926

Description

@stephane-segning

Steps to reproduce

url_launcher's supportsCloseForLaunchMode is documented as reporting whether closeInAppWebView() will work for a given mode, but its body is identical to supportsLaunchMode's — both call the platform interface's supportsMode. The platform interface declares a separate supportsCloseForMode, which is what it should call, and which the platform implementations do implement differently.

packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart (v6.3.2, the current release):

Future<bool> supportsLaunchMode(LaunchMode mode) {
  return UrlLauncherPlatform.instance.supportsMode(convertLaunchMode(mode));
}

/// Returns true if [closeInAppWebView] is supported for [mode] in the current
/// platform implementation.
///
/// If this returns false, [closeInAppWebView] will not work when launching
/// URLs with [mode].
Future<bool> supportsCloseForLaunchMode(LaunchMode mode) {
  return UrlLauncherPlatform.instance.supportsMode(convertLaunchMode(mode));  // <-- should be supportsCloseForMode
}

The two implementations genuinely disagree, which is what makes this observable rather than cosmetic. On Android (url_launcher_android 6.3.33):

Future<bool> supportsMode(PreferredLaunchMode mode) async {
  switch (mode) {
    ...
    case PreferredLaunchMode.inAppBrowserView:
      return _hostApi.supportsCustomTabs();   // true on a device with Chrome
    ...
  }
}

Future<bool> supportsCloseForMode(PreferredLaunchMode mode) async {
  return mode == PreferredLaunchMode.inAppWebView;   // false for inAppBrowserView
}

So on Android:

final canClose = await supportsCloseForLaunchMode(LaunchMode.inAppBrowserView);
// canClose == true  (it actually answered supportsCustomTabs())

await launchUrl(uri, mode: LaunchMode.inAppBrowserView);
await closeInAppWebView();
// nothing closes — a Custom Tab is not closable, which is exactly what
// supportsCloseForMode was telling the caller and what the public API hid.

url_launcher_ios 6.4.2 draws the same distinction the other way round (its supportsCloseForMode returns true for both inAppWebView and inAppBrowserView), so the two methods are meaningfully different on every platform — the public API just never asks the right one.

Expected results

supportsCloseForLaunchMode(LaunchMode.inAppBrowserView) reports whether closeInAppWebView() can close that mode — false on Android, per url_launcher_android's own supportsCloseForMode.

Actual results

It reports whether that mode can be launched — true on any Android device with Chrome — so a caller that branches on it does the opposite of what the documentation promises.

Suggested fix

One line:

Future<bool> supportsCloseForLaunchMode(LaunchMode mode) {
  return UrlLauncherPlatform.instance.supportsCloseForMode(convertLaunchMode(mode));
}

Worth a regression test asserting the two public methods can disagree, since they currently cannot: a fake platform returning true from supportsMode and false from supportsCloseForMode would have caught this and would keep catching it.

Code sample

Code sample
import 'package:url_launcher/url_launcher.dart';

Future<void> main() async {
  final uri = Uri.parse('https://flutter.dev');
  // On Android, with Chrome installed:
  print(await supportsLaunchMode(LaunchMode.inAppBrowserView));      // true
  print(await supportsCloseForLaunchMode(LaunchMode.inAppBrowserView)); // true  <-- expected false
}

Version / environment

  • url_launcher 6.3.2 (latest on pub.dev at time of filing, published 2025-07-10)
  • url_launcher_platform_interface 2.3.2 — declares supportsCloseForMode at lib/src/url_launcher_platform.dart:114
  • url_launcher_android 6.3.33, url_launcher_ios 6.4.2

Found by reading the sources while choosing a browser hand-off strategy; our own code calls closeInAppWebView() unconditionally and swallows the result, so we are not affected — filing because the next caller who trusts the documented method will be.

Activity

  1. suryaKommana2662 commented on Sep 15, 2026

    @suryaKommana2662
    Contributor

    @stephane-segning Thanks for the detailed report. I was able to reproduce the issue locally on Android and iOS. Using LaunchMode.inAppBrowserView, I observed:

    supportsLaunchMode: true
    supportsCloseForLaunchMode: true
    

    Reproduced locally on Flutter 3.47.4 stable with url_launcher using an Android 17 (API 37) emulator with Chrome/Custom Tabs available. Routing to team-ecosystem for further investigation.

    Flutter Doctor Output

    [✓] Flutter (Channel stable, 3.47.4, on macOS 26.4 25E246 darwin-arm64, locale en-IN) [333ms]
        • Flutter version 3.47.4 on channel stable at /Users/suryakommana/develop/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 9584c6713b (4 days ago), 2026-09-10 15:25:10 -0700
        • Engine revision 06a2e2a110
        • Dart version 3.13.3
        • DevTools version 2.60.0
        • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets,
          enable-record-use, enable-swift-package-manager, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [1,685ms]
        • Android SDK at /Users/suryakommana/Library/Android/sdk
        • Emulator version 37.1.11.0 (build_id 15917651) (CL:N/A)
        • Platform android-37.0, build-tools 36.0.0
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
          This is the JDK bundled with the latest Android Studio installation on this machine.
          To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 25.0.2+-15348964-b329.117)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 26.6) [777ms]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 17F113
        • CocoaPods version 1.17.0
    
    [✓] Chrome - develop for the web [6ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Connected device (4 available) [5.8s]
        • sdk gphone16k arm64 (mobile) • emulator-5554                        • android-arm64  • Android 17 (API 37) (emulator)
        • iPhone 17 pro (mobile)       • DB7548B3-163D-4C89-A357-B948B8CE1F16 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-26-5 (simulator)
        • macOS (desktop)              • macos                                • darwin-arm64   • macOS 26.4 25E246 darwin-arm64
        • Chrome (web)                 • chrome                               • web-javascript • Google Chrome 152.0.7977.83
    
    [✓] Network resources [464ms]
        • All expected network resources are available.
    
    • No issues found!
  2. added
    platform-androidAndroid applications specifically
    platform-iosiOS applications specifically
    p: url_launcherPlugin to launch external applications
    packageflutter/packages repository. See also p: labels.
    and removed
    in triagePresently being triaged by the triage team
    on Sep 15, 2026
  3. added
    P2Important issues not at the top of the work list
    platform-androidAndroid applications specifically
    platform-iosiOS applications specifically
    p: url_launcherPlugin to launch external applications
    packageflutter/packages repository. See also p: labels.
    and removed
    platform-androidAndroid applications specifically
    platform-iosiOS applications specifically
    p: url_launcherPlugin to launch external applications
    packageflutter/packages repository. See also p: labels.
    P2Important issues not at the top of the work list
    on Sep 29, 2026
  4. github-actions commented on Oct 16, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  5. locked as resolved and limited conversation to collaborators on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listp: url_launcherPlugin to launch external applicationspackageflutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyplatform-iosiOS applications specificallyteam-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions