I think I have a better idea of what happened, at least at the CoreAudio level.
When the app's audio session category is solo-ambient, the music app's play event triggers an audio session interruption similar to an alarm clock or a phone call. This
will trigger app's audio session interruption listener callback with the "enter-interruption" state.
However, the music app's pause event does not trigger the listener callback with the "exit-interruption" state, as one would expect. This missing exit call effectively freezes our app's audio session. Quitting the control centre does not trigger it either. Same thing applies to a physical remote-control, except that the physical remote-control can be blocked using the firstResponder trick said in my last email. It does not work with Control Centre.
Unless I'm missing something obvious, I am more convinced that there are two bugs in either CoreAudio or other frameworks in the chain of command.
Bug 1: Audio session interruption listener's exit call cannot be made from music remote control if the entrance call is made first there.
Bug 2: Control Centre's music remote control does not conform to remote-control event mechanism.
I'm just surprised that no one ever reported this.
I think I'm going to file a bug report unless someone suggests differently.
======
- Subject: iOS7 control center and audio session
-
From: Beinan Li <email@hidden>
-
Before iOS7 came, we noticed an issue:
Music remote-control from earbud or springboard can hijack our audio session even if we set the category to solo-ambient or another exclusive mode. We thus tried a few things:
1. We tried to snatch the audio session back. But this requires that our audio code knows when to snatch it back that and from whom. We thought we can let the app code become the first responder to remote-control events, do our stuff, and then pass the events on to the music app. However, we found that the events got detained by the first responder and there is no way to push it back to the chain of commands.
2. We then tried to become first-resonder and block remote-control events all together when we are in solo-ambient. This worked fine with iOS6, still works with earbud control in iOS7, but fails with iOS7's control centre. The control centre seems to bypass the remote-control event handler (remoteControlReceivedWithEvent:) completely, where we put our blocking code.
I read something elsewhere that:
"""
you can't block the music app. your app can become one though (apple won't like that) and then the control center would control yours.
"""
But I found no documentation whatsoever about control centre.
And as said above, control centre does not enter the normal remote control hooks even if an app is the first responder.
Another quote
"""
Remote Control Event handling is so your app can be controlled by Control Center, the earbuds, ets... it is not so that your app can eat said controls, preventing control of other apps from said sources. It only worked in iOS6 because of a bug in iOS, now fixed in iOS7
"""
Is it that what had been working for us was due to a bug? I find it hard to believe because we got the solution on this list and the Xcode mailing list so I assume that was an accepted solution.
Now we really wonder if we are missing something from the very beginning:
Is solo-ambient really an exclusive mode for audio session or is it that music app is an exception to that exclusivity?
How can our app live in harmony with the remote-control, and control centre?
Where can we find up-to-date documentation of remote-control and control centre?
Thanks a lot!