7

I've run into a problem using the AudioFilePlayer audio unit with app sandboxing enabled on OS X 10.8. I have an AUGraph with only two nodes, consisting of an AudioFilePlayer unit connected to a DefaultOutput unit. The goal (right now) is to simply play a single audio file. If sandboxing is not enabled, everything works fine. If I enable sandboxing, AUGraphOpen() returns error -3000 (invalidComponentID). If I remove the file player node from the AUGraph, the error goes away, which at least implies that the audio file player is causing the problem.

Here's the code I use to set the file player node up:

OSStatus AddFileToGraph(AUGraph graph, NSURL *fileURL, AudioFileInfo *outFileInfo, AUNode *outFilePlayerNode)
{
    OSStatus error = noErr;

    if ((error = AudioFileOpenURL((__bridge CFURLRef)fileURL, kAudioFileReadPermission, 0, &outFileInfo->inputFile))) {
        NSLog(@"Could not open audio file at %@ (%ld)", fileURL, (long)error);
        return error;
    }

    // Get the audio data format from the file
    UInt32 propSize = sizeof(outFileInfo->inputFormat);
    if ((error = AudioFileGetProperty(outFileInfo->inputFile, kAudioFilePropertyDataFormat, &propSize, &outFileInfo->inputFormat))) {
        NSLog(@"Couldn't get format of input file %@", fileURL);
        return error;
    }

    // Add AUAudioFilePlayer node
    AudioComponentDescription fileplayercd = {0};
    fileplayercd.componentType = kAudioUnitType_Generator;
    fileplayercd.componentSubType = kAudioUnitSubType_AudioFilePlayer;
    fileplayercd.componentManufacturer = kAudioUnitManufacturer_Apple;
    fileplayercd.componentFlags = kAudioComponentFlag_SandboxSafe;
    if ((error = AUGraphAddNode(graph, &fileplayercd, outFilePlayerNode))) {
        NSLog(@"AUAudioFilePlayer node not found (%ld)", (long)error);
        return error;
    }

    return error;
}

Note that fileURL in the AudioFileOpenURL() call is a URL obtained from security scoped bookmark data, and is the URL to a file that has been dragged into the application by the user.

If I set the com.apple.security.temporary-exception.audio-unit-host sandboxing entitlement, when AUGraphOpen() is called, the user is prompted to lower security settings, and assuming they accept, playback again works fine (the sandbox is disabled).

So, this points to the AudioFilePlayer unit not being sandbox-safe/compatible. Is this true? It's difficult to believe that Apple wouldn't have fixed such an important part of the CoreAudio API to be sandbox compatible. Also note that I specify the kAudioComponentFlag_SandboxSafe flag in the description passed to AUGraphAddNode, and that call does not fail. Also, I can only find one reference to AudioFilePlayer not being sandbox-safe online, in the form of this post to the CoreAudio mailing list, and it didn't receive any replies. Perhaps I'm making some other subtle mistake that happens to cause a problem with sandboxing enabled, but not when it's off (I'm new to Core Audio)?

Andrew Madsen
  • 21,309
  • 5
  • 56
  • 97
  • I was pointed to this article discussing this exact issue. It turns out that there's another entitlement that's unfortunately not documented in the standard sandboxing documentation: com.apple.security.temporary-exception.audio-unit-host. This will allow audio units, like the DLSSynth, which require permissions greater than the host environment's sandboxing allows, to run in the host environment, provided that the user grants permission at run time. I'm not sure how long-term this solution is, given that this entitlement is also categorized as a temporary exception. – X-Factor Mar 02 '13 at 16:22
  • @X-Factor, thanks for the comment. I actually mention exactly this in my question (see the second to last paragraph). In this case, the app in question is entirely useless without AudioFilePlayer, as its entire purpose is to play audio. It doesn't make much sense to turn on sandboxing only to have it turned off by the user 100% of the time the app is run. All it means is an extra, scary user prompt... – Andrew Madsen Mar 02 '13 at 16:29
  • well tell me one thing i wanted to confrim about sandbox safe, did you checked "sandboxSafe" key in its description dictionary located in the info.plist exists ? – X-Factor Mar 02 '13 at 16:34
  • well if you add a temporary exception entitlement to enable read-write access to the user's entire home directory, this error will no longer occur, but i don't think this will be the solution, but still there is this solution. – X-Factor Mar 02 '13 at 16:36
  • We're talking about a system-provided audio unit, AUAudioFilePlayer, here. I don't think I have access to its info.plist. As shown in the code above, I am setting the `kAudioComponentFlag_SandboxSafe` flag in the AudioComponentDescription when fetching the unit, so in theory (unless I misunderstand that flag's purpose), the system shouldn't return the unit if it's not declared sandbox safe. – Andrew Madsen Mar 02 '13 at 16:36
  • Well, enabling read/write access to the user's home directly basically defeats the purpose of sandboxing, probably won't pass app store review, and won't work anyway, because we don't want to limit the user to playing only audio files that are stored in their home directory. – Andrew Madsen Mar 02 '13 at 16:37
  • have a visit to this technical note, it might help http://developer.apple.com/library/ios/#technotes/tn2247/_index.html Regards – X-Factor Mar 02 '13 at 16:38
  • @X-Factor, thanks for trying to help. I read through that tech note several times before asking this question. It doesn't contain the answer. – Andrew Madsen Mar 02 '13 at 17:14
  • I don't have a definitive answer but https://developer.apple.com/library/mac/technotes/tn2312/_index.html#//apple_ref/doc/uid/DTS40013335 seems to address this topic – sbooth Mar 16 '14 at 02:34
  • @sbooth, that technote doesn't really provide any useful information that wasn't already mentioned in my question. As I noted, if you add the com.apple.security.temporary-exception.audio-unit-host sandbox entitlement, you can use the AudioFilePlayer unit just fine. The problem is, this requires the dropping the app's sandbox (after user confirmation). It just seems silly that such a fundamental, system-supplied audio unit would not be sandbox safe after all this time. After a year, I still don't have a better answer. (We stopped using AudioFilePlayer in favor of a lower level solution). – Andrew Madsen Mar 16 '14 at 04:47
  • I reread the TN this morning and you're right that it is essentially useless and I couldn't agree more that it is absolutely ridiculous Apple's own system doesn't work in their sandbox. I think I remember someone burning a DTS incident over this but I couldn't find the thread on coreaudio-api. – sbooth Mar 16 '14 at 11:34

0 Answers0