Skip to content

[Bug]: PhonePermissionStrategy.checkServiceStatus calls completionHandler twice, causing crashes #1565

Description

@ryanaidilp

Please check the following before submitting a new issue.

Please select affected platform(s)

  • Android
  • iOS
  • Windows

Steps to reproduce

  1. Call Permission.phone.serviceStatus (or anything that triggers checkServiceStatus for the phone permission) on a device/simulator where [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]] returns NO (e.g. iPad, or a device without telephony capability).
  2. In PhonePermissionStrategy.m, the if (![app canOpenURL:telURL]) branch calls completionHandler(ServiceStatusNotApplicable) but does not return, so execution falls through and calls completionHandler(...) a second time with the enabled/disabled status.
  3. The Flutter method channel result callback backing completionHandler is only expected to be invoked once; the second invocation raises an exception/crash.

We noticed this because checkServiceStatus/PhonePermissionStrategy shows up as one of the top crashes in our production consumer app in Firebase Crashlytics, affecting users on devices where canOpenURL: returns NO for tel://.

Expected results

completionHandler should be invoked exactly once per call to checkServiceStatus.

Actual results

completionHandler is invoked twice when the device cannot open tel:// URLs, which can crash the app.

Code sample

Code sample
// permission_handler_apple/ios/permission_handler_apple/Sources/permission_handler_apple/strategies/PhonePermissionStrategy.m

- (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(ServiceStatusHandler)completionHandler {
  UIApplication *app = [UIApplication sharedApplication];
  NSURL *telURL = [NSURL URLWithString:@"tel://"];
  if (![app canOpenURL:telURL]) {
      completionHandler(ServiceStatusNotApplicable);
      // missing `return;` here — falls through and calls completionHandler again below
  }
  completionHandler([self canDevicePlaceAPhoneCall] ? ServiceStatusEnabled : ServiceStatusDisabled);
}

Screenshots or video

Screenshots or video demonstration

Crashlytics shows this as a top crash in our production app; no visual repro available since it's a native-side double-callback crash.

Version

9.6.1 (permission_handler_apple)

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.47.4, on macOS 26.6.2 25G83 darwin-arm64, locale en-ID) [2.1s]
    • Flutter version 3.47.4 on channel stable at /Users/ryanaidilp/fvm/versions/3.47.0
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 9584c6713b (6 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,082ms]
    • Android SDK at Library/Android/sdk
    • Emulator version 37.1.11.0 (build_id 15917651) (CL:N/A)
    • Platform android-36, build-tools 36.0.0
    • ANDROID_HOME = /Library/Android/sdk
    • Java binary at: /Users/ryanaidilp/.sdkman/candidates/java/current/bin/java
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment Temurin-17.0.4.1+1 (build 17.0.4.1+1)
    • All Android licenses accepted.

[!] Xcode - develop for iOS and macOS (Xcode 27.0) [1,277ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 27A266a
    ! iOS 27.0 Simulator not installed; this may be necessary for iOS and macOS development.
      To download and install the platform, open Xcode, select Xcode > Settings > Components,
      and click the GET button for the required platform.

      For more information, please visit:
        https://developer.apple.com/documentation/xcode/installing-additional-simulator-runtimes
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [7ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Connected device (2 available) [6.6s]
    • macOS (desktop) • macos  • darwin-arm64   • macOS 26.6.2 25G83 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 152.0.7977.84

[✓] Network resources [800ms]
    • All expected network resources are available.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions