JUCE
JUCE copied to clipboard
[Bug]: Android: TemporaryFile::TemporaryFile (const File&, const int) and anything that depends on it fail
Detailed steps on how to reproduce the bug
Currently JUCE TemporaryFile(const File&, const int)
constructor tries to create a new file next to the referent file (in the same directory), regardless of whether your process can read the directory or not, and this triggers wider range of JUCE APIs fail, for example, File::replaceWithText()
:
https://github.com/juce-framework/JUCE/blob/e265be5a031a3ab8552502c00926c4b8d0cdba13/modules/juce_core/files/juce_File.cpp#L788
due to TemporaryFile::overwriteTargetFileWithTemporary()
:
https://github.com/juce-framework/JUCE/blob/e265be5a031a3ab8552502c00926c4b8d0cdba13/modules/juce_core/files/juce_TemporaryFile.cpp#L99
It is because File::exists() returns false
on Android, because access()
to the "parent directory" of the referent temporary file fails (it is not readable by current app process for security reason).
File::replaceWithText()
is used by PluginDirecroryScanner::scanNextFile()
to manipulate DeadMansPedalFile, thus any attempt to build plugin host over juce_audio_plugin_client
will fail there.
I'm attaching the stacktrace that I have with master
, but should be almost identical to develop
as far as I observed the changes in juce_core
.
What is the expected behaviour?
TemporaryFile
instantiated by TemporaryFile(const File&, const int)
constructor should not cause any operation failures such as overwriteTargetFileWithTemporary()
.
Operating systems
Android
What versions of the operating systems?
Android 34
Architectures
ARM, 64-bit
Stacktrace
juce::TemporaryFile::overwriteTargetFileWithTemporary() const juce_TemporaryFile.cpp:114
juce::File::replaceWithText(const juce::String &, bool, bool, const char *) const juce_File.cpp:782
juce::PluginDirectoryScanner::setDeadMansPedalFile(const juce::StringArray &) juce_PluginDirectoryScanner.cpp:128
juce::PluginDirectoryScanner::scanNextFile(bool, juce::String &) juce_PluginDirectoryScanner.cpp:102
AUScanner::doNextScan() GraphEditorPanel.cpp:77
AUScanner::ScanJob::runJob() GraphEditorPanel.cpp:86
juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread &) juce_ThreadPool.cpp:377
juce::ThreadPool::ThreadPoolThread::run() juce_ThreadPool.cpp:38
juce::Thread::threadEntryPoint() juce_Thread.cpp:98
juce::juce_threadEntryPoint(void *) juce_Thread.cpp:120
$_0::operator()(void *) const juce_Threads_android.cpp:408
$_0::__invoke(void *) juce_Threads_android.cpp:402
juce::ThreadTargetRunnable2::invoke(_jobject *, _jobject *, _jobjectArray *) juce_Threads_android.cpp:392
juce::juce_invokeImplementer(_JNIEnv *, _jobject *, long, _jobject *, _jobject *, _jobjectArray *) juce_JNIHelpers_android.cpp:408
art_quick_generic_jni_trampoline 0x00000076edb77034
art_quick_invoke_stub 0x00000076edb605a8
art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread *, art::ArtMethod *, art::ShadowFrame *, unsigned short, art::JValue *) 0x00000076edbae364
art::interpreter::DoCall<…>(art::ArtMethod *, art::Thread *, art::ShadowFrame &, const art::Instruction *, unsigned short, bool, art::JValue *) 0x00000076edb98588
art::interpreter::ExecuteSwitchImplCpp<…>(art::interpreter::SwitchImplContext *) 0x00000076edd0cf30
ExecuteSwitchImplAsm 0x00000076edb797dc
art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.__uniq.112435418011751916792819755956732575238.llvm.1377403774332988508) 0x00000076edb7cde4
art::interpreter::DoCall<…>(art::ArtMethod *, art::Thread *, art::ShadowFrame &, const art::Instruction *, unsigned short, bool, art::JValue *) 0x00000076edc91210
art::interpreter::ExecuteSwitchImplCpp<…>(art::interpreter::SwitchImplContext *) 0x00000076edd0aca8
ExecuteSwitchImplAsm 0x00000076edb797dc
art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.__uniq.112435418011751916792819755956732575238.llvm.1377403774332988508) 0x00000076edb7cde4
artQuickToInterpreterBridge 0x00000076edb7c564
art_quick_to_interpreter_bridge 0x00000076edb7716c
art_quick_invoke_static_stub 0x00000076edb60884
art::InvokeProxyInvocationHandler(art::ScopedObjectAccessAlreadyRunnable &, const char *, _jobject *, _jobject *, std::vector<…> &) 0x00000076edb58b10
artQuickProxyInvokeHandler 0x00000076edb55478
art_quick_proxy_invoke_handler 0x00000076edb76c50
art_quick_invoke_stub 0x00000076edb605a8
art::interpreter::DoCall<…>(art::ArtMethod *, art::Thread *, art::ShadowFrame &, const art::Instruction *, unsigned short, bool, art::JValue *) 0x00000076edc906b8
art::interpreter::ExecuteSwitchImplCpp<…>(art::interpreter::SwitchImplContext *) 0x00000076edd0aca8
ExecuteSwitchImplAsm 0x00000076edb797dc
art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.__uniq.112435418011751916792819755956732575238.llvm.1377403774332988508) 0x00000076edb7cde4
artQuickToInterpreterBridge 0x00000076edb7c564
art_quick_to_interpreter_bridge 0x00000076edb7716c
art_quick_invoke_stub 0x00000076edb605a8
art::ArtMethod::Invoke(art::Thread *, unsigned int *, unsigned int, art::JValue *, const char *) 0x00000076edb4b8a8
art::Thread::CreateCallback(void *) 0x00000076edcf3e34
__pthread_start(void *) 0x00000079a32cd6ac
__start_thread 0x00000079a326a220
Plug-in formats (if applicable)
No response
Plug-in host applications (DAWs) (if applicable)
JUCE AudioPluginHost, modified for Android https://github.com/atsushieno/aap-juce-plugin-host-cmake
Testing on the develop
branch
The bug is present on the develop
branch
Code of Conduct
- [X] I agree to follow the Code of Conduct
I have the same issue with a Mac Standalone app
JUCE Assertion failure in juce_TemporaryFile.cpp:114