Issues with JUCE on Oculus

My team is hitting some roadblocks running JUCE on Oculus, and we believe it is generally an issue with our Android integration and not necessarily Oculus specific.

From one of our devs:

We’re running into numerous roadblocks to get audio playing on Oculus. Most of the ones I’m struggling to get past involve the low-level JUCE/Android integration. For example, right now we’re forcing our audio system to run on the main thread (rather than split one off, like it does on other platforms) because of issues enabling the Looper object. We’re also hitting issues when requesting mic permissions related to some Activity and Fragment stuff not being properly set-up. As best as I can tell, it seems this is all related to how JUCE is trying to communicate with the JNI/Android OS. We don’t necessarily need this permission right now, but not requesting the permission causes us to fail elsewhere. Furthermore, it’s not certain to me that fixing these issues I’ve mentioned will get us to the point where we’re actually hearing our test sound; I expect there could be more issues of a similar nature. I don’t have the low-level knowledge with JUCE or Android to be able to hack past these blocks very efficiently or without gutting other functionality that we need.

The error with the Looper object when trying to run audio on a separate thread is:
JNI DETECTED ERROR IN APPLICATION: JNI CallBooleanMethodV called with pending exception java.lang.RuntimeException: Can't create handler inside thread Thread[Thread-7,5,main] that has not called Looper.prepare()

Which we believe may be related to this thread but we don’t have sufficient context to use the solution described therein. It may be that a clarifier there is all we need.

Any help is greatly appreciated!

Would it be possible to provide a minimal working example that produces the error? Does the same code work on other Android platforms?

Hello; I’m the developer mentioned in this post.

We haven’t had an opportunity to test on other Android platforms, but I was able to get things working with a few hacks to the JUCE source.

This code exists in this weird intersection of JUCE and Unity. It seems like the way Unity’s Android implementation works does some odd stuff with the Looper. Essentially, I was able to get things working by borrowing Unity’s main looper and passing it to the Handlers that JUCE makes. I’ll still see some assertion failures coming from MessageManager; the system tries to post messages from different threads, since the java object callbacks are on a different thread than we’re running JUCE/tracktion on. But our audio seems to run as expected in spite of these warnings for the time being.