Skip to content

fix: microphone permission for MacOS#3183

Merged
CloudyPadmal merged 3 commits into
fossasia:flutterfrom
ctrlVnt:flutter
Apr 19, 2026
Merged

fix: microphone permission for MacOS#3183
CloudyPadmal merged 3 commits into
fossasia:flutterfrom
ctrlVnt:flutter

Conversation

@ctrlVnt

@ctrlVnt ctrlVnt commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #3181

Changes

Add exclusion for MacOS platform in permission handler because permission_handler library doesn't support MacOS. Microphone permissions is already managed by the record library, as marked in documentation.

Screenshots / Recordings

N/A

Checklist:

  • No hard coding: I have used values from constants.dart or localization files instead of hard-coded values.
  • No end of file edits: No modifications done at end of resource files.
  • Code reformatting: I have formatted the code using dart format or the IDE formatter.
  • Code analysis: My code passes checks run in flutter analyze and tests run in flutter test.

Summary by Sourcery

Handle microphone permission behavior differently on macOS to align with platform support and existing recording library handling.

Bug Fixes:

  • Avoid requesting microphone permission via permission_handler on macOS where the plugin is unsupported.

Enhancements:

  • Declare macOS microphone usage description in Info.plist for oscilloscope functionality.

@sourcery-ai

sourcery-ai Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds a platform check to skip using the permission_handler microphone permission request on macOS, relying instead on the record package’s own permission handling, and declares the required microphone usage description in the macOS Info.plist.

Sequence diagram for updated microphone permission handling

sequenceDiagram
    actor User
    participant ChannelParametersWidget
    participant PermissionHandler
    participant RecordPlugin
    participant MacOSSystem
    participant OtherOSSystem

    User->>ChannelParametersWidget: Tap inBuiltMIC option
    activate ChannelParametersWidget
    ChannelParametersWidget->>ChannelParametersWidget: onChangedMicSelection(value)
    alt Platform isMacOS
        ChannelParametersWidget-->>PermissionHandler: Skip microphone.request()
        ChannelParametersWidget->>RecordPlugin: StartRecording()
        RecordPlugin->>MacOSSystem: RequestMicrophoneAccess
        MacOSSystem-->>RecordPlugin: GrantOrDeny
        RecordPlugin-->>ChannelParametersWidget: RecordingStatus
    else Platform is not MacOS
        ChannelParametersWidget->>PermissionHandler: Permission.microphone.request()
        PermissionHandler-->>OtherOSSystem: RequestMicrophoneAccess
        OtherOSSystem-->>PermissionHandler: GrantOrDeny
        PermissionHandler-->>ChannelParametersWidget: PermissionStatus
        ChannelParametersWidget->>RecordPlugin: StartRecording()
        RecordPlugin-->>ChannelParametersWidget: RecordingStatus
    end
    deactivate ChannelParametersWidget
Loading

Class diagram for ChannelParametersWidget microphone permission change

classDiagram
    class ChannelParametersWidget {
    }

    class _ChannelParametersState {
        +bool isInBuiltMICSelected
        +void onChangedInBuiltMic(bool value)
    }

    ChannelParametersWidget --> _ChannelParametersState : creates

    class Platform {
        +static bool isMacOS
    }

    class Permission {
        +static Permission microphone
        +Future request()
    }

    class RecordPlugin {
        +Future startRecording()
    }

    _ChannelParametersState ..> Platform : checks_platform
    _ChannelParametersState ..> Permission : requests_mic_permission_non_macos
    _ChannelParametersState ..> RecordPlugin : starts_recording

    note for _ChannelParametersState "onChangedInBuiltMic(value) {
  if (!Platform.isMacOS) {
    await Permission.microphone.request()
  }
  setState(updateMicSelection)
}"
Loading

File-Level Changes

Change Details Files
Guard microphone permission request so it does not run on macOS.
  • Import dart:io to access Platform APIs.
  • Wrap Permission.microphone.request() in a Platform.isMacOS check so it only runs on non-macOS platforms.
  • Keep the existing state update and MIC selection logic unchanged aside from the permission check.
lib/view/widgets/channel_parameters_widget.dart
Declare microphone usage permission for the macOS app bundle.
  • Add NSMicrophoneUsageDescription key with a user-facing explanation string to Info.plist.
  • Leave macOS entitlements files unchanged aside from any generated diffs (no new capabilities explicitly added).
macos/Runner/Info.plist
macos/Runner/DebugProfile.entitlements
macos/Runner/Release.entitlements

Assessment against linked issues

Issue Objective Addressed Explanation
#3181 Ensure the In-built Mic option in the oscilloscope works on macOS without throwing a MissingPluginException from the permission_handler plugin.
#3181 Properly handle microphone permission on macOS by relying on the record plugin and configuring required macOS app permissions.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The platform check around Permission.microphone.request() is hardcoded to only skip macOS; consider centralizing permission handling (e.g., in a service or utility) so that platform-specific behavior is defined in one place instead of directly inside the widget.
  • The result of Permission.microphone.request() is ignored; if this affects UI behavior (e.g., enabling the oscilloscope), consider handling denied/permanentlyDenied states so the widget can react appropriately when permission is not granted.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The platform check around `Permission.microphone.request()` is hardcoded to only skip macOS; consider centralizing permission handling (e.g., in a service or utility) so that platform-specific behavior is defined in one place instead of directly inside the widget.
- The result of `Permission.microphone.request()` is ignored; if this affects UI behavior (e.g., enabling the oscilloscope), consider handling denied/permanentlyDenied states so the widget can react appropriately when permission is not granted.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions

Copy link
Copy Markdown
Contributor

Build Status

Build successful. APKs to test: https://github.com/fossasia/pslab-app/actions/runs/24501238903/artifacts/6469666612.

Screenshots

Android Screenshots
iPhone Screenshots
iPad Screenshots

@ctrlVnt

ctrlVnt commented Apr 18, 2026

Copy link
Copy Markdown
Contributor Author

Platform.isMacOS is not supported by web version, so we check before if we aren't in web with !kIsWeb (so we use lazy evaluation of flutter) and after if we aren't in MacOS

Tested on MacOS and Web and it works

@CloudyPadmal CloudyPadmal merged commit e4ae6fa into fossasia:flutter Apr 19, 2026
13 of 14 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.

In-built Mic on MacOS doesn't work in oscilloscope

2 participants