diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 57c1b6c7505f..cc65efcbb487 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -302,6 +302,7 @@ On Android devices: Returns the list of dangerous permissions that have been granted. On macOS: Returns the list of granted permissions and user selected folders accessible to the application (sandboxed applications only). Use the native file dialog to request folder access permission. + On iOS, VisionOS: Returns the list of granted permissions. @@ -781,8 +782,9 @@ - [code]OS.request_permission("android.permission.READ_EXTERNAL_STORAGE")[/code] - [code]OS.request_permission("android.permission.POST_NOTIFICATIONS")[/code] - [code]OS.request_permission("macos.permission.RECORD_SCREEN")[/code] + - [code]OS.request_permission("appleembedded.permission.AUDIO_RECORD")[/code] [b]Note:[/b] On Android, permission must be checked during export. - [b]Note:[/b] This method is implemented on Android and macOS. + [b]Note:[/b] This method is implemented on Android, macOS and visionOS platforms. diff --git a/drivers/apple_embedded/os_apple_embedded.h b/drivers/apple_embedded/os_apple_embedded.h index 6bbf31852315..16d1b4dafd6f 100644 --- a/drivers/apple_embedded/os_apple_embedded.h +++ b/drivers/apple_embedded/os_apple_embedded.h @@ -132,6 +132,9 @@ class OS_AppleEmbedded : public OS_Unix { void on_exit_background(); virtual Rect2 calculate_boot_screen_rect(const Size2 &p_window_size, const Size2 &p_imgrect_size) const override; + + virtual bool request_permission(const String &p_name) override; + virtual Vector get_granted_permissions() const override; }; #endif // APPLE_EMBEDDED_ENABLED diff --git a/drivers/apple_embedded/os_apple_embedded.mm b/drivers/apple_embedded/os_apple_embedded.mm index fa71c96e100f..69c93ef41264 100644 --- a/drivers/apple_embedded/os_apple_embedded.mm +++ b/drivers/apple_embedded/os_apple_embedded.mm @@ -48,6 +48,7 @@ #import #import #import +#import #import #include @@ -714,4 +715,35 @@ Rect2 fit_keep_aspect_covered(const Vector2 &p_container, const Vector2 &p_rect) } } +bool OS_AppleEmbedded::request_permission(const String &p_name) { + if (p_name == "appleembedded.permission.AUDIO_RECORD") { + if (@available(iOS 17.0, *)) { + AVAudioApplicationRecordPermission permission = [AVAudioApplication sharedInstance].recordPermission; + if (permission == AVAudioApplicationRecordPermissionGranted) { + // Permission already granted, you can start recording. + return true; + } else if (permission == AVAudioApplicationRecordPermissionDenied) { + // Permission denied, or not yet granted + return false; + } else { + // Request the permission, but for now return false as documented + [AVAudioApplication requestRecordPermissionWithCompletionHandler: ^(BOOL granted) { + get_main_loop()->emit_signal(SNAME("on_request_permissions_result"), p_name, granted); + }]; + } + }; + } + return false; +} + +Vector OS_AppleEmbedded::get_granted_permissions() const { + Vector ret; + + if (@available(iOS 17.0, *)) { + if ([AVAudioApplication sharedInstance].recordPermission == AVAudioApplicationRecordPermissionGranted) { + ret.push_back("appleembedded.permission.AUDIO_RECORD"); + } + } + return ret; +} #endif // APPLE_EMBEDDED_ENABLED diff --git a/drivers/coreaudio/audio_driver_coreaudio.mm b/drivers/coreaudio/audio_driver_coreaudio.mm index d9efa9c658eb..fb870e4740a7 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.mm +++ b/drivers/coreaudio/audio_driver_coreaudio.mm @@ -241,14 +241,16 @@ AudioBufferList bufferList; bufferList.mNumberBuffers = 1; - bufferList.mBuffers[0].mData = ad->input_buf.ptrw(); + bufferList.mBuffers[0].mData = nullptr; bufferList.mBuffers[0].mNumberChannels = ad->capture_channels; bufferList.mBuffers[0].mDataByteSize = ad->input_buf.size() * sizeof(int16_t); OSStatus result = AudioUnitRender(ad->input_unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList); + ad->input_buf.resize(inNumberFrames * ad->capture_channels); if (result == noErr) { + int16_t *data = (int16_t *)bufferList.mBuffers[0].mData; for (unsigned int i = 0; i < inNumberFrames * ad->capture_channels; i++) { - int32_t sample = ad->input_buf[i] << 16; + int32_t sample = data[i] << 16; ad->input_buffer_write(sample); if (ad->capture_channels == 1) { @@ -393,9 +395,6 @@ UInt32 flag = 1; result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); ERR_FAIL_COND_V(result != noErr, FAILED); - flag = 0; - result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); - ERR_FAIL_COND_V(result != noErr, FAILED); UInt32 size; #ifdef MACOS_ENABLED