Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect static value usage in JNI array methods #2178

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions core/platform/android/GLViewImpl-android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Rect GLViewImpl::getSafeAreaRect() const
float insetLeft = 0.0f;
float insetRight = 0.0f;

static int* cornerRadii =
static axstd::pod_vector<int32_t> cornerRadii =
JniHelper::callStaticIntArrayMethod("org/axmol/lib/AxmolEngine", "getDeviceCornerRadii");

if (isScreenRound)
Expand All @@ -172,13 +172,13 @@ Rect GLViewImpl::getSafeAreaRect() const
// landscape: no changes with X-coords
}
}
else if (deviceAspectRatio >= WIDE_SCREEN_ASPECT_RATIO_ANDROID || cornerRadii != nullptr)
else if (deviceAspectRatio >= WIDE_SCREEN_ASPECT_RATIO_ANDROID || cornerRadii.size() >= 4)
{
// almost all devices on the market have round corners if
// deviceAspectRatio more than 2 (@see "android.max_aspect" parameter in AndroidManifest.xml)

// cornerRadii is only available in API31+ (Android 12+)
if (cornerRadii != nullptr)
if (cornerRadii.size() >= 4)
{
float radiiBottom = cornerRadii[0] / _scaleY;
float radiiLeft = cornerRadii[1] / _scaleX;
Expand Down Expand Up @@ -240,9 +240,10 @@ Rect GLViewImpl::getSafeAreaRect() const
if (isCutoutEnabled)
{
// screen with enabled cutout area (ex. Google Pixel 3 XL, Huawei P20, Asus ZenFone 5, etc)
static int* safeInsets =
JniHelper::callStaticIntArrayMethod("org/axmol/lib/AxmolEngine", "getSafeInsets");
if (safeInsets != nullptr)
static axstd::pod_vector<int32_t> safeInsets =
JniHelper::callStaticIntArrayMethod("org/axmol/lib/AxmolEngine", "getSafeInsets");

if (safeInsets.size() >= 4)
{
float safeInsetBottom = safeInsets[0] / _scaleY;
float safeInsetLeft = safeInsets[1] / _scaleX;
Expand Down
51 changes: 23 additions & 28 deletions core/platform/android/jni/JniHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ THE SOFTWARE.
#include "platform/PlatformMacros.h"
#include "math/Vec3.h"
#include "jni/jni.hpp"
#include "base/axstd.h"

namespace jni
{
Expand Down Expand Up @@ -221,12 +222,11 @@ class AX_DLL JniHelper

/**
@brief Call of Java static float* method
@return address of JniMethodInfo if there are proper JniMethodInfo; otherwise nullptr.
@return axstd::pod_vector
*/
template <typename... Ts>
static float* callStaticFloatArrayMethod(const char* className, const char* methodName, Ts&&... xs)
static axstd::pod_vector<float> callStaticFloatArrayMethod(const char* className, const char* methodName, Ts&&... xs)
{
static float ret[32];
ax::JniMethodInfo t;
const char* signature = jni::TypeSignature<jni::Array<jfloat>(std::decay_t<Ts>...)>{}();
if (ax::JniHelper::getStaticMethodInfo(t, className, methodName, signature))
Expand All @@ -239,38 +239,35 @@ class AX_DLL JniHelper
{
t.env->DeleteLocalRef(t.classID);
deleteLocalRefs(t.env, localRefs);
return nullptr;
return {};
}

jsize len = t.env->GetArrayLength(array);
if (len <= 32)
axstd::pod_vector<float> result(len);
jfloat* elems = t.env->GetFloatArrayElements(array, 0);
if (elems)
{
jfloat* elems = t.env->GetFloatArrayElements(array, 0);
if (elems)
{
memcpy(ret, elems, sizeof(float) * len);
t.env->ReleaseFloatArrayElements(array, elems, 0);
};
}
memcpy(result.data(), elems, sizeof(float) * len);
t.env->ReleaseFloatArrayElements(array, elems, 0);
};
t.env->DeleteLocalRef(t.classID);
deleteLocalRefs(t.env, localRefs);
return &ret[0];
return result;
}
else
{
reportError(className, methodName, signature);
}
return nullptr;
return {};
}

/**
@brief Call of Java static int* method
@return address of JniMethodInfo if there are proper JniMethodInfo; otherwise nullptr.
@return axstd::pod_vector
*/
template <typename... Ts>
static int* callStaticIntArrayMethod(const char* className, const char* methodName, Ts&&... xs)
static axstd::pod_vector<int32_t> callStaticIntArrayMethod(const char* className, const char* methodName, Ts&&... xs)
{
static int ret[32];
ax::JniMethodInfo t;
const char* signature = jni::TypeSignature<jni::Array<jint>(std::decay_t<Ts>...)>{}();
if (ax::JniHelper::getStaticMethodInfo(t, className, methodName, signature))
Expand All @@ -283,28 +280,26 @@ class AX_DLL JniHelper
{
t.env->DeleteLocalRef(t.classID);
deleteLocalRefs(t.env, localRefs);
return nullptr;
return {};
}

jsize len = t.env->GetArrayLength(array);
if (len <= 32)
axstd::pod_vector<int32_t> result(len);
jint* elems = t.env->GetIntArrayElements(array, 0);
if (elems)
{
jint* elems = t.env->GetIntArrayElements(array, 0);
if (elems)
{
memcpy(ret, elems, sizeof(int) * len);
t.env->ReleaseIntArrayElements(array, elems, 0);
};
}
memcpy(result.data(), elems, sizeof(int32_t) * len);
t.env->ReleaseIntArrayElements(array, elems, 0);
};
t.env->DeleteLocalRef(t.classID);
deleteLocalRefs(t.env, localRefs);
return &ret[0];
return result;
}
else
{
reportError(className, methodName, signature);
}
return nullptr;
return {};
}

/**
Expand Down