9

我正在开发基于示例 developer.apple.com/library/mac/samplecode/AudioDriverExamples/Introduction/Intro.html 的 coreaudio 用户空间 hal 插件

在插件实现中,我打算从另一个进程即CFMessagePort获取音频数据

但是,我在控制台中尝试创建端口 CFMessagePortCreateLocal 时出现以下错误...

sandboxd[251]: ([2597]) coreaudiod(2597) 拒绝 mach-register com.mycompnay.audio

我做了一些谷歌搜索并来到这篇文章

技术问答 QA1811 https://developer.apple.com/library/mac/qa/qa1811/_index.html 关于在 plist 中添加 AudioServerPlugIn_MachServices 但仍然没有成功。

我还需要做些什么来完成这项工作(比如添加权利、代码签名)或者这不是正确的方法。?我不确定 MessagePort 机制在沙箱下是否可以工作。XPC 服务是否可行?

非常感谢您的宝贵时间。任何帮助是极大的赞赏


更新1:

我应该在音频插件中创建一个远程端口而不是本地端口。话虽如此,使用 plist 中的 AudioServerPlugIn_MachServices 属性。现在没有sandboxd[559]: ([552]) coreaudiod(552)在控制台中拒绝 mach-lookup / register 消息。

但是,在我的音频 hal 插件(客户端)中,我有

CFStringRef port_name = CFSTR("com.mycompany.audio.XPCService"); CFMessagePortRef port = CFMessagePortCreateRemote(kCFAllocatorDefault, port_name); 端口返回值 0。我在不同的应用程序中尝试过这个,它工作得很好。

这是我的服务器端:

CFStringRef port_name = CFSTR("com.mycompany.audio.XPCService");
CFMessagePortRef  port = CFMessagePortCreateLocal(kCFAllocatorDefault, port_name, &callback, NULL, NULL);
CFRunLoopSourceRef runLoopSource =
CFMessagePortCreateRunLoopSource(nil, port, 0);

CFRunLoopAddSource(CFRunLoopGetCurrent(),
                   runLoopSource,
                   kCFRunLoopCommonModes);
CFRunLoopRun();

我确实收到了关于此的控制台消息。

com.apple.audio.DriverHelper[1314]:名为 SimpleAudioPlugIn.driver 的插件需要扩展名为 com.mycompnay.audio.XPCService 的 mach 服务的沙箱

有谁知道为什么??


更新 2

我注意到,当我将调试模式与 coreaudiod 一起使用时,它确实成功获取了 mach 服务的对象引用。(当我尝试 xpc_service 方法时发生了同样的事情) 项目方案设置

任何人??

4

1 回答 1

6

我很确定我在 AudioServerPlugIn 中遇到了同样的问题。我可以查找并使用我尝试过的每一个 Mach 服务,除了我创建的那些。我创建的那些从常规过程中正常工作。

最终,我阅读了 Daemonnomicon并发现coreaudiod(托管 HAL 插件的)正在使用全局引导命名空间,但我的服务是在每个用户的引导命名空间中注册的。而且由于“使用全局命名空间的进程只能看到全局命名空间中的服务”,所以我的插件看不到我的服务。

您可以launchctl通过让它运行注册您的服务的程序来测试它,但使用与coreaudiod. 您可能需要禁用无根。

# launchctl bsexec $(pgrep coreaudiod) your_service_executable

运行后,再次尝试从您的插件连接。

从 Daemonnomicon 中的表 2,您可以看到只有 launchd 守护程序使用全局引导命名空间。这就解释了为什么coreaudiod使用它。而且我认为这意味着您的 Mach 服务需要由 launchd 守护程序创建。

要制作一个,请为您的服务创建一个launchd.plist/Library/LaunchDaemons。将其所有者设置为root:wheel并使其只能由所有者写入。在其中设置MachServices密钥并添加服务名称:

<key>MachServices</key>
<dict>
    <key>com.mycompany.audio.XPCService</key>
    <true/>
</dict>

然后注册它:

# launchctl bootstrap system /Library/LaunchDaemons/com.mycompany.audio.XPCService.plist

这就是我最终得到的结果:com.bearsdriving.BGM.XPCHelper.plist.template。请注意,如果没有UserName/GroupName键,您的守护程序将以 root 身份运行。(我的服务插件的代码也在那个仓库中,以防万一。)

不幸的是,我最终不得不使用 XPC,但我首先尝试了 CFMessagePort,它运行良好。

无论插件是否签名,它似乎都可以正常工作。不过,正如您所说,您确实需要AudioServerPlugIn_MachServicesInfo.plist 中的密钥。

于 2016-04-15T13:05:27.907 回答