mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Android: Fix ContentSharer crash on Android 14
This commit is contained in:
parent
fa0c91ddee
commit
b800890ec6
2 changed files with 74 additions and 14 deletions
|
|
@ -31,8 +31,15 @@ template <typename JavaType>
|
||||||
class LocalRef
|
class LocalRef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LocalRef() noexcept : obj (nullptr) {}
|
LocalRef() noexcept = default;
|
||||||
explicit LocalRef (JavaType o) noexcept : obj (o) {}
|
|
||||||
|
/* This constructor must not be used to wrap local references that were not created through
|
||||||
|
JNI, i.e. for native function callback parameters.
|
||||||
|
*/
|
||||||
|
explicit LocalRef (JavaType o) noexcept
|
||||||
|
: LocalRef (o, false)
|
||||||
|
{}
|
||||||
|
|
||||||
LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {}
|
LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {}
|
||||||
LocalRef (LocalRef&& other) noexcept : obj (nullptr) { std::swap (obj, other.obj); }
|
LocalRef (LocalRef&& other) noexcept : obj (nullptr) { std::swap (obj, other.obj); }
|
||||||
~LocalRef() { clear(); }
|
~LocalRef() { clear(); }
|
||||||
|
|
@ -48,31 +55,83 @@ public:
|
||||||
|
|
||||||
LocalRef& operator= (const LocalRef& other)
|
LocalRef& operator= (const LocalRef& other)
|
||||||
{
|
{
|
||||||
JavaType newObj = retain (other.obj);
|
auto tmp = other;
|
||||||
clear();
|
std::swap (tmp.obj, obj);
|
||||||
obj = newObj;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalRef& operator= (LocalRef&& other)
|
LocalRef& operator= (LocalRef&& other) noexcept
|
||||||
{
|
{
|
||||||
clear();
|
auto tmp = std::move (other);
|
||||||
std::swap (other.obj, obj);
|
std::swap (tmp.obj, obj);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator== (std::nullptr_t) const noexcept { return obj == nullptr; }
|
||||||
|
bool operator!= (std::nullptr_t) const noexcept { return obj != nullptr; }
|
||||||
|
|
||||||
operator JavaType() const noexcept { return obj; }
|
operator JavaType() const noexcept { return obj; }
|
||||||
|
|
||||||
JavaType get() const noexcept { return obj; }
|
JavaType get() const noexcept { return obj; }
|
||||||
|
|
||||||
private:
|
auto release()
|
||||||
JavaType obj;
|
{
|
||||||
|
return std::exchange (obj, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a new internal local reference. */
|
||||||
|
static auto addOwner (JavaType o)
|
||||||
|
{
|
||||||
|
return LocalRef { o, true };
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Takes ownership of the passed in local reference, and deletes it when the LocalRef goes out
|
||||||
|
of scope.
|
||||||
|
*/
|
||||||
|
static auto becomeOwner (JavaType o)
|
||||||
|
{
|
||||||
|
return LocalRef { o, false };
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
static JavaType retain (JavaType obj)
|
static JavaType retain (JavaType obj)
|
||||||
{
|
{
|
||||||
return obj == nullptr ? nullptr : (JavaType) getEnv()->NewLocalRef (obj);
|
return obj == nullptr ? nullptr : (JavaType) getEnv()->NewLocalRef (obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We cannot delete local references that were not created by JNI, e.g. references that were
|
||||||
|
created by the VM and passed into the native function.
|
||||||
|
|
||||||
|
For these references we should use createNewLocalRef = true, which will create a new
|
||||||
|
local reference that this wrapper is allowed to delete.
|
||||||
|
|
||||||
|
Doing otherwise will result in an "Attempt to remove non-JNI local reference" warning in the
|
||||||
|
VM, which could even cause crashes in future VM implementations.
|
||||||
|
*/
|
||||||
|
LocalRef (JavaType o, bool createNewLocalRef) noexcept
|
||||||
|
: obj (createNewLocalRef ? retain (o) : o)
|
||||||
|
{}
|
||||||
|
|
||||||
|
JavaType obj = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Creates a new local reference that shares ownership with the passed in pointer.
|
||||||
|
|
||||||
|
Can be used for wrapping function parameters that were created outside the JNI.
|
||||||
|
*/
|
||||||
|
template <class JavaType>
|
||||||
|
auto addLocalRefOwner (JavaType t)
|
||||||
|
{
|
||||||
|
return LocalRef<JavaType>::addOwner (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wraps a local reference and destroys it when it goes out of scope. */
|
||||||
|
template <class JavaType>
|
||||||
|
auto becomeLocalRefOwner (JavaType t)
|
||||||
|
{
|
||||||
|
return LocalRef<JavaType>::becomeOwner (t);
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
template <typename JavaType>
|
template <typename JavaType>
|
||||||
class GlobalRefImpl
|
class GlobalRefImpl
|
||||||
|
|
@ -846,7 +905,7 @@ namespace
|
||||||
javaString ("").get()));
|
javaString ("").get()));
|
||||||
|
|
||||||
for (int i = 0; i < juceArray.size(); ++i)
|
for (int i = 0; i < juceArray.size(); ++i)
|
||||||
env->SetObjectArrayElement (result, i, javaString (juceArray [i]).get());
|
env->SetObjectArrayElement (result.get(), i, javaString (juceArray [i]).get());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,8 +336,8 @@ public:
|
||||||
|
|
||||||
static jobjectArray JNICALL contentSharerGetStreamTypes (JNIEnv*, jobject /*contentProvider*/, jobject uri, jstring mimeTypeFilter)
|
static jobjectArray JNICALL contentSharerGetStreamTypes (JNIEnv*, jobject /*contentProvider*/, jobject uri, jstring mimeTypeFilter)
|
||||||
{
|
{
|
||||||
return getInstance().getStreamTypes (LocalRef<jobject> (static_cast<jobject> (uri)),
|
return getInstance().getStreamTypes (addLocalRefOwner (uri),
|
||||||
LocalRef<jstring> (static_cast<jstring> (mimeTypeFilter)));
|
addLocalRefOwner (mimeTypeFilter));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -482,7 +482,8 @@ private:
|
||||||
if (extension.isEmpty())
|
if (extension.isEmpty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return juceStringArrayToJava (filterMimeTypes (detail::MimeTypeTable::getMimeTypesForFileExtension (extension), juceString (mimeTypeFilter.get())));
|
return juceStringArrayToJava (filterMimeTypes (detail::MimeTypeTable::getMimeTypesForFileExtension (extension),
|
||||||
|
juceString (mimeTypeFilter.get()))).release();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ActivityLauncher> doIntent (const LocalRef<jobject>& intent,
|
std::unique_ptr<ActivityLauncher> doIntent (const LocalRef<jobject>& intent,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue