no message

This commit is contained in:
gem
2025-02-18 15:21:31 +08:00
commit 2d133e56d7
1980 changed files with 465595 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/jni/JniHelper.h"
#if CC_PLATFORM == CC_PLATFORM_ANDROID
#include <android/keycodes.h>
#include <android/log.h>
#elif CC_PLATFORM == CC_PLATFORM_OHOS
#include <hilog/log.h>
#endif
#include <jni.h>
#include "engine/EngineEvents.h"
#include "platform/java/jni/glue/JniNativeGlue.h"
#include "platform/java/modules/SystemWindow.h"
namespace {
struct cc::KeyboardEvent keyboardEvent;
// key values in web, refer to http://docs.cocos.com/creator/api/en/enums/KEY.html
#if CC_PLATFORM == CC_PLATFORM_ANDROID
ccstd::unordered_map<int, int> keyCodeMap = {
{AKEYCODE_BACK, 6},
{AKEYCODE_ENTER, 13},
{AKEYCODE_MENU, 18},
{AKEYCODE_DPAD_UP, 1003},
{AKEYCODE_DPAD_DOWN, 1004},
{AKEYCODE_DPAD_LEFT, 1000},
{AKEYCODE_DPAD_RIGHT, 1001},
{AKEYCODE_DPAD_CENTER, 1005}};
#elif CC_PLATFORM == CC_PLATFORM_OHOS
ccstd::unordered_map<int, int> keyCodeMap = {};
#endif
//NOLINTNEXTLINE
static void dispatchKeyCodeEvent(int keyCode, cc::KeyboardEvent &event) {
if (keyCodeMap.count(keyCode) > 0) {
keyCode = keyCodeMap[keyCode];
} else {
keyCode = 0;
}
event.windowId = cc::ISystemWindow::mainWindowId;
event.key = keyCode;
cc::events::Keyboard::broadcast(event);
}
} // namespace
extern "C" {
//NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosKeyCodeHandler_handleKeyDown(JNIEnv *env, jobject obj, jint keyCode) {
keyboardEvent.action = cc::KeyboardEvent::Action::PRESS;
dispatchKeyCodeEvent(keyCode, keyboardEvent);
}
//NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosKeyCodeHandler_handleKeyUp(JNIEnv *env, jobject obj, jint keyCode) {
keyboardEvent.action = cc::KeyboardEvent::Action::RELEASE;
dispatchKeyCodeEvent(keyCode, keyboardEvent);
}
}

View File

@@ -0,0 +1,67 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include <jni.h>
#include "engine/EngineEvents.h"
#include "platform/interfaces/modules/Device.h"
#include "platform/java/jni/JniHelper.h"
#include "platform/java/jni/glue/JniNativeGlue.h"
#include "platform/java/modules/SystemWindow.h"
extern "C" {
// NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosOrientationHelper_nativeOnOrientationChanged(JNIEnv *env, jclass thiz, jint rotation) {
int orientation;
switch (rotation) {
case 0: // ROTATION_0
orientation = (int)cc::Device::Orientation::PORTRAIT;
case 1: // ROTATION_90
orientation = (int)cc::Device::Orientation::LANDSCAPE_RIGHT;
case 2: // ROTATION_180
orientation = (int)cc::Device::Orientation::PORTRAIT_UPSIDE_DOWN;
case 3: // ROTATION_270
orientation = (int)cc::Device::Orientation::LANDSCAPE_LEFT;
}
// run callbacks in game thread?
cc::events::Orientation::broadcast(orientation);
}
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onOrientationChangedNative(JNIEnv *env, jobject obj, jint orientation, jint width, jint height) { //NOLINT JNI function name
static jint pOrientation = 0;
static jint pWidth = 0;
static jint pHeight = 0;
if (pOrientation != orientation || pWidth != width || pHeight != height) {
cc::WindowEvent ev;
// TODO(qgh):The windows ID needs to be passed down from the jave, which is currently using the main window.
ev.windowId = cc::ISystemWindow::mainWindowId;
ev.type = cc::WindowEvent::Type::SIZE_CHANGED;
ev.width = width;
ev.height = height;
cc::events::WindowEvent::broadcast(ev);
pOrientation = orientation;
pHeight = height;
pWidth = width;
}
}
}

View File

@@ -0,0 +1,100 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include <jni.h>
#include "engine/EngineEvents.h"
#include "platform/java/jni/JniHelper.h"
#include "platform/java/jni/glue/JniNativeGlue.h"
#include "platform/java/modules/SystemWindow.h"
#include "platform/java/modules/SystemWindowManager.h"
namespace {
cc::TouchEvent touchEvent;
}
extern "C" {
//NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosTouchHandler_handleActionDown(JNIEnv *env, jobject obj, jint id,
jfloat x, jfloat y) {
// TODO(qgh):The windows ID needs to be passed down from the jave, which is currently using the main window.
touchEvent.windowId = cc::ISystemWindow::mainWindowId;
touchEvent.type = cc::TouchEvent::Type::BEGAN;
touchEvent.touches.emplace_back(x, y, id);
cc::events::Touch::broadcast(touchEvent);
touchEvent.touches.clear();
}
//NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosTouchHandler_handleActionUp(JNIEnv *env, jobject obj, jint id, jfloat x,
jfloat y) {
touchEvent.windowId = cc::ISystemWindow::mainWindowId;
touchEvent.type = cc::TouchEvent::Type::ENDED;
touchEvent.touches.emplace_back(x, y, id);
cc::events::Touch::broadcast(touchEvent);
touchEvent.touches.clear();
}
//NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosTouchHandler_handleActionMove(JNIEnv *env, jobject obj,
jintArray ids,
jfloatArray xs,
jfloatArray ys) {
touchEvent.type = cc::TouchEvent::Type::MOVED;
touchEvent.windowId = cc::ISystemWindow::mainWindowId;
int size = env->GetArrayLength(ids);
jint id[size];
jfloat x[size];
jfloat y[size];
env->GetIntArrayRegion(ids, 0, size, id);
env->GetFloatArrayRegion(xs, 0, size, x);
env->GetFloatArrayRegion(ys, 0, size, y);
for (int i = 0; i < size; i++) {
touchEvent.touches.emplace_back(x[i], y[i], id[i]);
}
cc::events::Touch::broadcast(touchEvent);
touchEvent.touches.clear();
}
//NOLINTNEXTLINE
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosTouchHandler_handleActionCancel(JNIEnv *env, jobject obj,
jintArray ids,
jfloatArray xs,
jfloatArray ys) {
touchEvent.type = cc::TouchEvent::Type::CANCELLED;
touchEvent.windowId = cc::ISystemWindow::mainWindowId;
int size = env->GetArrayLength(ids);
jint id[size];
jfloat x[size];
jfloat y[size];
env->GetIntArrayRegion(ids, 0, size, id);
env->GetFloatArrayRegion(xs, 0, size, x);
env->GetFloatArrayRegion(ys, 0, size, y);
for (int i = 0; i < size; i++) {
touchEvent.touches.emplace_back(x[i], y[i], id[i]);
}
cc::events::Touch::broadcast(touchEvent);
touchEvent.touches.clear();
}
}

View File

@@ -0,0 +1,447 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/jni/JniHelper.h"
#if ANDROID
#include <android/log.h>
#else
#include "cocos/base/Log.h"
#endif
#include <pthread.h>
#include <cstring>
#include "base/UTF8.h"
#define CC_CACHE_CLASS_ID 0
#if ANDROID
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#else
#define LOGD(...) CC_LOG_DEBUG(__VA_ARGS__)
#define LOGE(...) CC_LOG_ERROR(__VA_ARGS__)
#endif
namespace {
pthread_key_t g_key; // NOLINT(readability-identifier-naming)
class JClassWrapper final {
public:
explicit JClassWrapper(jclass kls) {
if (kls) {
_globalKls = static_cast<jclass>(cc::JniHelper::getEnv()->NewGlobalRef(static_cast<jobject>(kls)));
}
}
~JClassWrapper() {
if (_globalKls) {
cc::JniHelper::getEnv()->DeleteGlobalRef(_globalKls);
}
_globalKls = nullptr;
}
jclass operator*() const {
return _globalKls;
}
private:
jclass _globalKls = {};
};
#if CC_CACHE_CLASS_ID
ccstd::unordered_map<const char *, JClassWrapper> _cachedJClasses;
#endif
}; // namespace
jclass _getClassID(const char *className) { // NOLINT
if (nullptr == className) {
return nullptr;
}
#if CC_CACHE_CLASS_ID
auto it = _cachedJClasses.find(className);
if (it != _cachedJClasses.end()) {
return *it->second;
}
#endif
JNIEnv *env = cc::JniHelper::getEnv();
jstring jstrClassName = env->NewStringUTF(className);
auto *klassObj = static_cast<jclass>(env->CallObjectMethod(cc::JniHelper::classloader,
cc::JniHelper::loadclassMethodMethodId,
jstrClassName));
if (nullptr == klassObj || env->ExceptionCheck()) {
LOGE("Classloader failed to find class of %s", className);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
env->ExceptionClear();
klassObj = nullptr;
}
ccDeleteLocalRef(env, jstrClassName);
// LOGE("1. delete 0x%p", jstrClassName);
#if CC_CACHE_CLASS_ID
if (klassObj) {
_cachedJClasses.emplace(className, klassObj);
}
#endif
return klassObj;
}
void cbDetachCurrentThread(void * /*a*/) {
cc::JniHelper::getJavaVM()->DetachCurrentThread();
}
namespace cc {
jmethodID JniHelper::loadclassMethodMethodId = nullptr;
jobject JniHelper::classloader = nullptr;
std::function<void()> JniHelper::classloaderCallback = nullptr;
jobject JniHelper::sContext = nullptr;
JavaVM *JniHelper::sJavaVM = nullptr;
JavaVM *JniHelper::getJavaVM() {
pthread_t thisthread = pthread_self();
LOGD("JniHelper::getJavaVM(), pthread_self() = %ld", thisthread);
return JniHelper::sJavaVM;
}
void JniHelper::init(JNIEnv *env, jobject context) {
env->GetJavaVM(&JniHelper::sJavaVM);
JniHelper::sContext = context;
pthread_key_create(&g_key, cbDetachCurrentThread);
auto ok = JniHelper::setClassLoaderFrom(context);
CC_ASSERT(ok);
}
void JniHelper::onDestroy() {
if (JniHelper::sJavaVM) {
if (JniHelper::sContext) {
cc::JniHelper::getEnv()->DeleteGlobalRef(JniHelper::sContext);
JniHelper::sContext = nullptr;
}
LOGD("JniHelper::onDestroy");
}
}
JNIEnv *JniHelper::cacheEnv() {
JavaVM *jvm = JniHelper::sJavaVM;
JNIEnv *env = nullptr;
// get jni environment
jint ret = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4);
switch (ret) {
case JNI_OK:
// Success!
pthread_setspecific(g_key, env);
return env;
case JNI_EDETACHED:
// Thread not attached
#if CC_PLATFORM == CC_PLATFORM_ANDROID
if (jvm->AttachCurrentThread(&env, nullptr) < 0) {
#else
if (jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr) < 0) {
#endif
LOGE("Failed to get the environment using AttachCurrentThread()");
return nullptr;
} else {
// Success : Attached and obtained JNIEnv!
pthread_setspecific(g_key, env);
return env;
}
case JNI_EVERSION:
// Cannot recover from this error
LOGE("JNI interface version 1.4 not supported");
default:
LOGE("Failed to get the environment using GetEnv()");
return nullptr;
}
}
JNIEnv *JniHelper::getEnv() {
auto *env = static_cast<JNIEnv *>(pthread_getspecific(g_key));
if (env == nullptr) {
env = JniHelper::cacheEnv();
}
return env;
}
jobject JniHelper::getContext() {
return sContext;
}
jobject JniHelper::getActivity() {
// TODO(cjh): In normal mode, sContext is Activity itself, but in surface-less mode, we need to
// returns nullptr.
return sContext;
}
#if CC_PLATFORM == CC_PLATFORM_OHOS
bool JniHelper::setClassLoaderFrom(jobject contextInstance) {
if (!JniHelper::classloader) {
JniMethodInfo getclassloaderMethod;
if (!JniHelper::getMethodInfoDefaultClassLoader(getclassloaderMethod,
"ohos/app/AbilityContext",
"getClassloader", // typo ?
"()Ljava/lang/ClassLoader;")) {
return false;
}
jobject klassLoader = cc::JniHelper::getEnv()->CallObjectMethod(contextInstance,
getclassloaderMethod.methodID);
if (nullptr == klassLoader) {
return false;
}
JniMethodInfo loadClass;
if (!JniHelper::getMethodInfoDefaultClassLoader(loadClass,
"java/lang/ClassLoader",
"loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;")) {
return false;
}
JniHelper::classloader = cc::JniHelper::getEnv()->NewGlobalRef(klassLoader);
JniHelper::loadclassMethodMethodId = loadClass.methodID;
}
JniHelper::sContext = cc::JniHelper::getEnv()->NewGlobalRef(contextInstance);
if (JniHelper::classloaderCallback != nullptr) {
JniHelper::classloaderCallback();
}
return true;
}
#elif CC_PLATFORM == CC_PLATFORM_ANDROID
bool JniHelper::setClassLoaderFrom(jobject contextInstance) {
if (!JniHelper::classloader) {
JniMethodInfo getClassloaderMethod;
if (!JniHelper::getMethodInfoDefaultClassLoader(getClassloaderMethod,
"android/content/Context",
"getClassLoader",
"()Ljava/lang/ClassLoader;")) {
return false;
}
jobject classLoader = cc::JniHelper::getEnv()->CallObjectMethod(contextInstance,
getClassloaderMethod.methodID);
if (nullptr == classLoader) {
return false;
}
JniMethodInfo loadClass;
if (!JniHelper::getMethodInfoDefaultClassLoader(loadClass,
"java/lang/ClassLoader",
"loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;")) {
return false;
}
JniHelper::classloader = cc::JniHelper::getEnv()->NewGlobalRef(classLoader);
JniHelper::loadclassMethodMethodId = loadClass.methodID;
}
JniHelper::sContext = cc::JniHelper::getEnv()->NewGlobalRef(contextInstance);
if (JniHelper::classloaderCallback != nullptr) {
JniHelper::classloaderCallback();
}
return true;
}
#endif
bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
const char *paramCode) {
if ((nullptr == className) ||
(nullptr == methodName) ||
(nullptr == paramCode)) {
return false;
}
JNIEnv *env = JniHelper::getEnv();
if (!env) {
LOGE("Failed to get JNIEnv");
return false;
}
jclass classID = _getClassID(className);
if (!classID) {
LOGE("Failed to find class %s", className);
env->ExceptionClear();
return false;
}
jmethodID methodID = env->GetStaticMethodID(classID, methodName, paramCode);
if (!methodID) {
LOGE("Failed to find static method id of %s", methodName);
env->ExceptionClear();
return false;
}
methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID;
return true;
}
//NOLINTNEXTLINE
bool JniHelper::getMethodInfoDefaultClassLoader(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
const char *paramCode) {
if ((nullptr == className) ||
(nullptr == methodName) ||
(nullptr == paramCode)) {
return false;
}
JNIEnv *env = JniHelper::getEnv();
if (!env) {
return false;
}
jclass classID = env->FindClass(className);
if (!classID) {
LOGE("Failed to find class %s", className);
env->ExceptionClear();
return false;
}
jmethodID methodID = env->GetMethodID(classID, methodName, paramCode);
if (!methodID) {
LOGE("Failed to find method id of %s", methodName);
env->ExceptionClear();
return false;
}
methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID;
return true;
}
bool JniHelper::getMethodInfo(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
const char *paramCode) {
if ((nullptr == className) ||
(nullptr == methodName) ||
(nullptr == paramCode)) {
return false;
}
JNIEnv *env = JniHelper::getEnv();
if (!env) {
return false;
}
jclass classID = _getClassID(className);
if (!classID) {
LOGE("Failed to find class %s", className);
env->ExceptionClear();
return false;
}
jmethodID methodID = env->GetMethodID(classID, methodName, paramCode);
if (!methodID) {
LOGE("Failed to find method id of %s", methodName);
env->ExceptionClear();
return false;
}
methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID;
return true;
}
ccstd::string JniHelper::jstring2string(jstring jstr) {
if (jstr == nullptr) {
return "";
}
JNIEnv *env = JniHelper::getEnv();
if (!env) {
return "";
}
ccstd::string strValue = cc::StringUtils::getStringUTFCharsJNI(env, jstr);
return strValue;
}
jstring JniHelper::convert(JniHelper::LocalRefMapType *localRefs, cc::JniMethodInfo *t, const char *x) {
jstring ret = nullptr;
if (x) {
ret = cc::StringUtils::newStringUTFJNI(t->env, x);
}
(*localRefs)[t->env].push_back(ret);
return ret;
}
jstring JniHelper::convert(JniHelper::LocalRefMapType *localRefs, cc::JniMethodInfo *t, const ccstd::string &x) {
return convert(localRefs, t, x.c_str());
}
jobject JniHelper::convert(JniHelper::LocalRefMapType *localRefs, cc::JniMethodInfo *t, const std::vector<std::string> &x) {
jclass stringClass = _getClassID("java/lang/String");
jobjectArray ret = t->env->NewObjectArray(x.size(), stringClass, nullptr);
for (auto i = 0; i < x.size(); i++) {
jstring jstr = cc::StringUtils::newStringUTFJNI(t->env, x[i]);
t->env->SetObjectArrayElement(ret, i, jstr);
t->env->DeleteLocalRef(jstr);
}
(*localRefs)[t->env].push_back(ret);
return ret;
}
void JniHelper::deleteLocalRefs(JNIEnv *env, JniHelper::LocalRefMapType *localRefs) {
if (!env) {
return;
}
for (const auto &ref : (*localRefs)[env]) {
ccDeleteLocalRef(env, ref);
// LOGE("2. delete 0x%p", ref);
}
(*localRefs)[env].clear();
}
void JniHelper::reportError(const ccstd::string &className, const ccstd::string &methodName, const ccstd::string &signature) {
LOGE("Failed to find static java method. Class name: %s, method name: %s, signature: %s ", className.c_str(), methodName.c_str(), signature.c_str());
}
} //namespace cc

View File

@@ -0,0 +1,556 @@
/****************************************************************************
Copyright (c) 2010-2012 cc-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <jni.h>
#include <functional>
#include "base/Log.h"
#include "base/Macros.h"
#include "base/std/container/string.h"
#include "base/std/container/unordered_map.h"
#include "base/std/container/vector.h"
#include "math/Vec3.h"
// The macro must be used this way to find the native method. The principle is not well understood.
#define JNI_METHOD2(CLASS2, FUNC2) Java_##CLASS2##_##FUNC2
#define JNI_METHOD1(CLASS1, FUNC1) JNI_METHOD2(CLASS1, FUNC1)
// ccDeleteLocalRef with classid produces warning??
#if 0
#define ccDeleteLocalRef(jenv, ref) \
do { \
jenv->DeleteLocalRef(ref); \
CC_LOG_DEBUG("deleteLocalRef file: %s, func: %s, line: %d", __FILE__, __FUNCTION__, __LINE__); \
} while (0)
#else
#define ccDeleteLocalRef(jenv, ref) jenv->DeleteLocalRef(ref); // NOLINT
#endif
#define CLEAR_EXCEPTON(env) \
do { \
if (env->ExceptionCheck()) { \
env->ExceptionDescribe(); \
env->ExceptionClear(); \
} \
} while (false)
struct android_app;
namespace cc {
using JniMethodInfo = struct JniMethodInfo_ { // NOLINT(readability-identifier-naming)
JNIEnv *env;
jclass classID;
jmethodID methodID;
};
class CC_DLL JniHelper {
public:
using LocalRefMapType = ccstd::unordered_map<JNIEnv *, ccstd::vector<jobject>>;
static JavaVM *getJavaVM();
static JNIEnv *getEnv();
static jobject getActivity();
static jobject getContext();
static void init(JNIEnv *env, jobject context);
static void onDestroy();
// NOLINTNEXTLINE
static bool getStaticMethodInfo(JniMethodInfo &methodInfo,
const char *className,
const char *methodName,
const char *paramCode);
// NOLINTNEXTLINE
static bool getMethodInfo(JniMethodInfo &methodInfo,
const char *className,
const char *methodName,
const char *paramCode);
static ccstd::string jstring2string(jstring str);
static jmethodID loadclassMethodMethodId;
static jobject classloader;
static std::function<void()> classloaderCallback;
template <typename... Ts>
static jobject newObject(const ccstd::string &className, Ts... xs) {
jobject ret = nullptr;
static const char *methodName = "<init>";
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")V";
if (cc::JniHelper::getMethodInfo(t, className.c_str(), methodName, signature.c_str())) {
LocalRefMapType localRefs;
ret = t.env->NewObject(t.classID, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static void callObjectVoidMethod(jobject object,
const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")V";
if (cc::JniHelper::getMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
t.env->CallVoidMethod(object, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
}
template <typename... Ts>
static float callObjectFloatMethod(jobject object,
const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
float ret = 0.0F;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")F";
if (cc::JniHelper::getMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
ret = t.env->CallFloatMethod(object, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static jlong callObjectLongMethod(jobject object,
const std::string &className,
const std::string &methodName,
Ts... xs) {
jlong ret = 0;
cc::JniMethodInfo t;
std::string signature = "(" + std::string(getJNISignature(xs...)) + ")J";
if (cc::JniHelper::getMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
ret = t.env->CallLongMethod(object, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static jbyteArray callObjectByteArrayMethod(jobject object,
const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
jbyteArray ret = nullptr;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")[B";
if (cc::JniHelper::getMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
ret = static_cast<jbyteArray>(t.env->CallObjectMethod(object, t.methodID, convert(&localRefs, &t, xs)...));
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static void callStaticVoidMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")V";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
t.env->CallStaticVoidMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
}
template <typename... Ts>
static bool callStaticBooleanMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
jboolean jret = JNI_FALSE;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")Z";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
jret = t.env->CallStaticBooleanMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return (jret == JNI_TRUE);
}
template <typename... Ts>
static int callStaticIntMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
jint ret = 0;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")I";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
ret = t.env->CallStaticIntMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static float callStaticFloatMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
jfloat ret = 0.0;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")F";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
ret = t.env->CallStaticFloatMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
CLEAR_EXCEPTON(t.env);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static float *callStaticFloatArrayMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
static float ret[32];
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")[F";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
auto *array = static_cast<jfloatArray>(t.env->CallStaticObjectMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...));
CLEAR_EXCEPTON(t.env);
jsize len = t.env->GetArrayLength(array);
if (len <= 32) {
jfloat *elems = t.env->GetFloatArrayElements(array, nullptr);
if (elems) {
memcpy(ret, elems, sizeof(float) * len);
t.env->ReleaseFloatArrayElements(array, elems, 0);
};
}
CLEAR_EXCEPTON(t.env);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
ccDeleteLocalRef(t.env, array);
deleteLocalRefs(t.env, &localRefs);
return &ret[0];
}
reportError(className, methodName, signature);
return nullptr;
}
template <typename... Ts>
static Vec3 callStaticVec3Method(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
Vec3 ret;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")[F";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
auto *array = static_cast<jfloatArray>(t.env->CallStaticObjectMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...));
CLEAR_EXCEPTON(t.env);
jsize len = t.env->GetArrayLength(array);
if (len == 3) {
jfloat *elems = t.env->GetFloatArrayElements(array, nullptr);
ret.x = elems[0];
ret.y = elems[1];
ret.z = elems[2];
t.env->ReleaseFloatArrayElements(array, elems, 0);
}
CLEAR_EXCEPTON(t.env);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
ccDeleteLocalRef(t.env, array);
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static double callStaticDoubleMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
jdouble ret = 0.0;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")D";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
ret = t.env->CallStaticDoubleMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...);
CLEAR_EXCEPTON(t.env);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
template <typename... Ts>
static ccstd::string callStaticStringMethod(const ccstd::string &className,
const ccstd::string &methodName,
Ts... xs) {
ccstd::string ret;
cc::JniMethodInfo t;
ccstd::string signature = "(" + ccstd::string(getJNISignature(xs...)) + ")Ljava/lang/String;";
if (cc::JniHelper::getStaticMethodInfo(t, className.c_str(), methodName.c_str(), signature.c_str())) {
LocalRefMapType localRefs;
auto *jret = static_cast<jstring>(t.env->CallStaticObjectMethod(t.classID, t.methodID, convert(&localRefs, &t, xs)...));
CLEAR_EXCEPTON(t.env);
ret = cc::JniHelper::jstring2string(jret);
ccDeleteLocalRef(t.env, jret);
#ifndef __OHOS__
ccDeleteLocalRef(t.env, t.classID);
#endif
deleteLocalRefs(t.env, &localRefs);
} else {
reportError(className, methodName, signature);
}
return ret;
}
static bool setClassLoaderFrom(jobject contextInstance);
private:
static jobject sContext;
static JavaVM *sJavaVM;
static JNIEnv *cacheEnv();
// NOLINTNEXTLINE
static bool getMethodInfoDefaultClassLoader(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
const char *paramCode);
static jstring convert(LocalRefMapType *localRefs, cc::JniMethodInfo *t, const char *x);
static jstring convert(LocalRefMapType *localRefs, cc::JniMethodInfo *t, const ccstd::string &x);
static jobject convert(LocalRefMapType *localRefs, cc::JniMethodInfo *t, const std::vector<std::string> &x);
template <typename T>
static T convert(LocalRefMapType * /*localRefs*/, cc::JniMethodInfo * /*t*/, T x) {
return x;
}
template <typename T>
static jobject convert(LocalRefMapType *localRefs, cc::JniMethodInfo *t, std::pair<T *, size_t> data) {
jobject ret = nullptr;
#define JNI_SET_TYPED_ARRAY(lowercase, camelCase) \
j##lowercase##Array array = t->env->New##camelCase##Array(data.second); \
t->env->Set##camelCase##ArrayRegion(array, 0, data.second, reinterpret_cast<const j##lowercase *>(data.first)); \
if (array) { \
(*localRefs)[t->env].push_back(array); \
} \
ret = static_cast<jobject>(array);
using U = typename std::remove_cv<typename std::remove_pointer<T>::type>::type;
if (sizeof(U) == 1) {
JNI_SET_TYPED_ARRAY(byte, Byte)
} else if (sizeof(U) == 4 && std::is_integral<U>::value) {
JNI_SET_TYPED_ARRAY(int, Int)
} else if (sizeof(U) == 8 && std::is_integral<U>::value) {
JNI_SET_TYPED_ARRAY(long, Long);
} else if (sizeof(U) == 4 && std::is_floating_point<U>::value) {
JNI_SET_TYPED_ARRAY(float, Float);
} else if (sizeof(U) == 8 && std::is_floating_point<U>::value) {
JNI_SET_TYPED_ARRAY(double, Double);
}
#undef JNI_SET_TYPED_ARRAY
return ret;
}
template <typename T, typename A>
static typename std::enable_if<std::is_arithmetic<T>::value, jobject>::type convert(LocalRefMapType *localRefs, cc::JniMethodInfo *t, const std::vector<T, A> &data) {
jobject ret = nullptr;
#define JNI_SET_TYPED_ARRAY(lowercase, camelCase) \
j##lowercase##Array array = t->env->New##camelCase##Array(data.size()); \
t->env->Set##camelCase##ArrayRegion(array, 0, data.size(), reinterpret_cast<const j##lowercase *>(data.data())); \
if (array) { \
(*localRefs)[t->env].push_back(array); \
} \
ret = static_cast<jobject>(array);
if (sizeof(T) == 1) {
JNI_SET_TYPED_ARRAY(byte, Byte)
} else if (sizeof(T) == 4 && std::is_integral<T>::value) {
JNI_SET_TYPED_ARRAY(int, Int)
} else if (sizeof(T) == 8 && std::is_integral<T>::value) {
JNI_SET_TYPED_ARRAY(long, Long);
} else if (sizeof(T) == 4 && std::is_floating_point<T>::value) {
JNI_SET_TYPED_ARRAY(float, Float);
} else if (sizeof(T) == 8 && std::is_floating_point<T>::value) {
JNI_SET_TYPED_ARRAY(double, Double);
}
#undef JNI_SET_TYPED_ARRAY
return ret;
}
static void deleteLocalRefs(JNIEnv *env, LocalRefMapType *localRefs);
static ccstd::string getJNISignature() {
return "";
}
static ccstd::string getJNISignature(bool /*unused*/) {
return "Z";
}
static ccstd::string getJNISignature(char /*unused*/) {
return "C";
}
static ccstd::string getJNISignature(unsigned char /*unused*/) {
return "B"; // same as jbyte
}
static ccstd::string getJNISignature(int16_t /*unused*/) {
return "S";
}
static ccstd::string getJNISignature(int32_t /*unused*/) {
return "I";
}
static ccstd::string getJNISignature(int64_t /*unused*/) {
return "J";
}
static ccstd::string getJNISignature(float /*unused*/) {
return "F";
}
static ccstd::string getJNISignature(double /*unused*/) {
return "D";
}
static ccstd::string getJNISignature(jbyteArray /*unused*/) {
return "[B";
}
static ccstd::string getJNISignature(jintArray /*unused*/) {
return "[I";
}
static ccstd::string getJNISignature(const char * /*unused*/) {
return "Ljava/lang/String;";
}
static ccstd::string getJNISignature(const ccstd::string & /*unused*/) {
return "Ljava/lang/String;";
}
template <typename T>
static ccstd::string getJNISignature(T x) {
// This template should never be instantiated
static_assert(sizeof(x) == 0, "Unsupported argument type");
return "";
}
template <typename T>
static std::string getJNISignature(std::pair<T *, size_t> /*x*/) {
typename std::remove_pointer<typename std::remove_cv<T>::type>::type m;
return std::string("[") + getJNISignature(m);
}
template <typename T, typename A>
static std::string getJNISignature(const std::vector<T, A> & /*x*/) {
T m;
return std::string("[") + getJNISignature(m);
}
template <typename T, typename... Ts>
static ccstd::string getJNISignature(T x, Ts... xs) {
return getJNISignature(x) + getJNISignature(xs...);
}
static void reportError(const ccstd::string &className, const ccstd::string &methodName, const ccstd::string &signature);
};
} // namespace cc

View File

@@ -0,0 +1,172 @@
/****************************************************************************
Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "JniImp.h"
#if CC_PLATFORM == CC_PLATFORM_ANDROID
#include <android/log.h>
#else
#include <hilog/log.h>
#endif
#include <jni.h>
#include "JniHelper.h"
#include "cocos/audio/include/AudioEngine.h"
#ifndef JCLS_HELPER
#define JCLS_HELPER "com/cocos/lib/CocosHelper"
#endif
#ifndef JCLS_SENSOR
#define JCLS_SENSOR "com/cocos/lib/CocosSensorHandler"
#endif
#ifndef COM_AUDIOFOCUS_CLASS_NAME
#define COM_AUDIOFOCUS_CLASS_NAME com_cocos_lib_CocosAudioFocusManager
#endif
#define JNI_AUDIO(FUNC) JNI_METHOD1(COM_AUDIOFOCUS_CLASS_NAME, FUNC)
/***********************************************************
* Functions invoke from cpp to Java.
***********************************************************/
namespace cc {
ccstd::string getObbFilePathJNI() {
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getObbFilePath");
}
int getObbAssetFileDescriptorJNI(const ccstd::string &path, int64_t *startOffset, int64_t *size) {
JniMethodInfo methodInfo;
int fd = 0;
if (JniHelper::getStaticMethodInfo(methodInfo, JCLS_HELPER, "getObbAssetFileDescriptor", "(Ljava/lang/String;)[J")) {
jstring stringArg = methodInfo.env->NewStringUTF(path.c_str());
auto *newArray = static_cast<jlongArray>(methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, stringArg));
jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);
if (3 == theArrayLen) {
jboolean copy = JNI_FALSE;
jlong *array = methodInfo.env->GetLongArrayElements(newArray, &copy);
fd = static_cast<int>(array[0]);
*startOffset = array[1];
*size = array[2];
methodInfo.env->ReleaseLongArrayElements(newArray, array, 0);
}
ccDeleteLocalRef(methodInfo.env, methodInfo.classID);
ccDeleteLocalRef(methodInfo.env, stringArg);
}
return fd;
}
ccstd::string getCurrentLanguageJNI() {
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getCurrentLanguage");
}
ccstd::string getCurrentLanguageCodeJNI() {
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getCurrentLanguageCode");
}
ccstd::string getSystemVersionJNI() {
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getSystemVersion");
}
bool openURLJNI(const ccstd::string &url) {
return JniHelper::callStaticBooleanMethod(JCLS_HELPER, "openURL", url);
}
void copyTextToClipboardJNI(const ccstd::string &text) {
JniHelper::callStaticVoidMethod(JCLS_HELPER, "copyTextToClipboard", text);
}
ccstd::string getDeviceModelJNI() {
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getDeviceModel");
}
int getDPIJNI() {
return JniHelper::callStaticIntMethod(JCLS_HELPER, "getDPI");
}
void setVibrateJNI(float duration) {
JniHelper::callStaticVoidMethod(JCLS_HELPER, "vibrate", duration);
}
void setKeepScreenOnJNI(bool isEnabled) {
return JniHelper::callStaticVoidMethod(JCLS_HELPER, "setKeepScreenOn", isEnabled);
}
void finishActivity() {
JniHelper::callStaticVoidMethod(JCLS_HELPER, "finishActivity");
}
int getNetworkTypeJNI() {
return JniHelper::callStaticIntMethod(JCLS_HELPER, "getNetworkType");
}
float *getSafeAreaEdgeJNI() {
return JniHelper::callStaticFloatArrayMethod(JCLS_HELPER, "getSafeArea");
}
int getDeviceRotationJNI() {
return JniHelper::callStaticIntMethod(JCLS_HELPER, "getDeviceRotation");
}
float getBatteryLevelJNI() {
return JniHelper::callStaticFloatMethod(JCLS_HELPER, "getBatteryLevel");
}
void flushTasksOnGameThreadJNI() {
JniHelper::callStaticVoidMethod(JCLS_HELPER,
"flushTasksOnGameThread");
}
void flushTasksOnGameThreadAtForegroundJNI() {
JniHelper::callStaticVoidMethod(JCLS_HELPER,
"flushTasksOnGameThreadAtForeground");
}
void setAccelerometerEnabledJNI(bool isEnabled) {
JniHelper::callStaticVoidMethod(JCLS_SENSOR, "setAccelerometerEnabled", isEnabled);
}
void setAccelerometerIntervalJNI(float interval) {
JniHelper::callStaticVoidMethod(JCLS_SENSOR, "setAccelerometerInterval", interval);
}
float *getDeviceMotionValueJNI() {
return JniHelper::callStaticFloatArrayMethod(JCLS_SENSOR, "getDeviceMotionValue");
}
bool getSupportHPE() {
return JniHelper::callStaticBooleanMethod(JCLS_HELPER, "supportHPE");
}
} // namespace cc
extern "C" {
JNIEXPORT void JNICALL JNI_AUDIO(nativeSetAudioVolumeFactor)(JNIEnv * /*env*/, jclass /* thiz*/, jfloat volumeFactor) {
#if CC_USE_AUDIO
cc::AudioEngine::setVolumeFactor(volumeFactor);
#endif
}
}

View File

@@ -0,0 +1,55 @@
/****************************************************************************
Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/std/container/string.h"
namespace cc {
ccstd::string getObbFilePathJNI();
int getObbAssetFileDescriptorJNI(const ccstd::string &path, int64_t *startOffset, int64_t *size);
ccstd::string getCurrentLanguageJNI();
ccstd::string getCurrentLanguageCodeJNI();
ccstd::string getSystemVersionJNI();
bool openURLJNI(const ccstd::string &url);
void copyTextToClipboardJNI(const ccstd::string &text);
ccstd::string getDeviceModelJNI();
int getDPIJNI();
void setVibrateJNI(float duration);
void setKeepScreenOnJNI(bool isEnabled);
int getNetworkTypeJNI();
float *getSafeAreaEdgeJNI();
int getDeviceRotationJNI();
float getBatteryLevelJNI();
void flushTasksOnGameThreadJNI();
void flushTasksOnGameThreadAtForegroundJNI();
void setAccelerometerEnabledJNI(bool isEnabled);
void setAccelerometerIntervalJNI(float interval);
float *getDeviceMotionValueJNI();
void finishActivity();
/**
* support for High Performance Emulator
*/
bool getSupportHPE();
} // namespace cc

View File

@@ -0,0 +1,298 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/jni/glue/JniNativeGlue.h"
#include <functional>
#include <future>
#include "application/ApplicationManager.h"
#include "engine/EngineEvents.h"
#include "platform/BasePlatform.h"
#include "platform/java/jni/JniImp.h"
#include "platform/java/jni/glue/MessagePipe.h"
#include "platform/java/jni/log.h"
#include "platform/java/modules/SystemWindow.h"
#include "platform/java/modules/SystemWindowManager.h"
namespace cc {
JniNativeGlue::~JniNativeGlue() = default;
JniNativeGlue* JniNativeGlue::getInstance() {
static JniNativeGlue jniNativeGlue;
return &jniNativeGlue;
}
void JniNativeGlue::start(int argc, const char** argv) {
_messagePipe = std::make_unique<MessagePipe>();
BasePlatform* platform = cc::BasePlatform::getPlatform();
if (platform->init()) {
LOGV("Platform initialization failed");
}
platform->run(argc, argv);
}
void JniNativeGlue::setWindowHandle(NativeWindowType* window) {
if (_pendingWindow) {
writeCommandSync(JniCommand::JNI_CMD_TERM_WINDOW);
}
_pendingWindow = window;
if (window) {
writeCommandSync(JniCommand::JNI_CMD_INIT_WINDOW);
}
}
void JniNativeGlue::setActivityGetter(std::function<NativeActivity(void)> getter) {
_activityGetter = std::move(getter);
}
void* JniNativeGlue::getActivity() {
return _activityGetter ? _activityGetter() : nullptr;
}
void JniNativeGlue::setEnvGetter(std::function<NativeEnv(void)> getter) {
_envGetter = std::move(getter);
}
void* JniNativeGlue::getEnv() {
return _envGetter ? _envGetter() : nullptr;
}
void JniNativeGlue::setResourceManager(ResourceManagerType* resourceManager) {
_resourceManager = resourceManager;
}
ResourceManagerType* JniNativeGlue::getResourceManager() {
return _resourceManager;
}
NativeWindowType* JniNativeGlue::getWindowHandle() {
return _window;
}
void JniNativeGlue::setSdkVersion(int sdkVersion) {
_sdkVersion = sdkVersion;
}
int JniNativeGlue::getSdkVersion() const {
return _sdkVersion;
}
void JniNativeGlue::setObbPath(const std::string& path) {
_obbPath = path;
}
std::string JniNativeGlue::getObbPath() const {
return _obbPath;
}
void JniNativeGlue::setRunning(bool isRunning) {
_threadPromise.set_value();
_running = isRunning;
}
void JniNativeGlue::waitRunning() {
_threadPromise.get_future().get();
}
bool JniNativeGlue::isRunning() const {
return _running;
}
void JniNativeGlue::flushTasksOnGameThread() const {
// Handle java events send by UI thread. Input events are handled here too.
flushTasksOnGameThreadJNI();
if (_animating) {
flushTasksOnGameThreadAtForegroundJNI();
}
}
void JniNativeGlue::writeCommandAsync(JniCommand cmd) {
CommandMsg msg{.cmd = cmd, .callback = nullptr};
_messagePipe->writeCommand(&msg, sizeof(msg));
}
void JniNativeGlue::writeCommandSync(JniCommand cmd) {
std::promise<void> fu;
CommandMsg msg{.cmd = cmd, .callback = [&fu]() {
fu.set_value();
}};
_messagePipe->writeCommand(&msg, sizeof(msg));
fu.get_future().get();
}
int JniNativeGlue::readCommand(CommandMsg* msg) {
return _messagePipe->readCommand(msg, sizeof(CommandMsg));
}
int JniNativeGlue::readCommandWithTimeout(CommandMsg* cmd, int delayMS) {
return _messagePipe->readCommandWithTimeout(cmd, sizeof(CommandMsg), delayMS);
}
bool JniNativeGlue::isPause() const {
if (!_animating) {
return true;
}
if (_appState == JniCommand::JNI_CMD_PAUSE) {
return true;
}
return false;
}
void JniNativeGlue::onPause() {
writeCommandAsync(JniCommand::JNI_CMD_PAUSE);
}
void JniNativeGlue::onResume() {
writeCommandAsync(JniCommand::JNI_CMD_RESUME);
}
void JniNativeGlue::onLowMemory() {
writeCommandAsync(JniCommand::JNI_CMD_LOW_MEMORY);
}
void JniNativeGlue::execCommand() {
static CommandMsg msg;
static bool runInLowRate{false};
runInLowRate = !_animating || JniCommand::JNI_CMD_PAUSE == _appState;
if (readCommandWithTimeout(&msg, runInLowRate ? 50 : 0) > 0) {
preExecCmd(msg.cmd);
engineHandleCmd(msg.cmd);
postExecCmd(msg.cmd);
if (msg.callback) {
msg.callback();
}
}
}
void JniNativeGlue::preExecCmd(JniCommand cmd) {
switch (cmd) {
case JniCommand::JNI_CMD_INIT_WINDOW: {
LOGV("JNI_CMD_INIT_WINDOW");
_animating = true;
_window = _pendingWindow;
} break;
case JniCommand::JNI_CMD_TERM_WINDOW:
LOGV("JNI_CMD_TERM_WINDOW");
_animating = false;
break;
case JniCommand::JNI_CMD_RESUME:
LOGV("JNI_CMD_RESUME");
_appState = cmd;
break;
case JniCommand::JNI_CMD_PAUSE:
LOGV("JNI_CMD_PAUSE");
_appState = cmd;
break;
default:
break;
}
}
void JniNativeGlue::engineHandleCmd(JniCommand cmd) {
static bool isWindowInitialized = false;
// Handle CMD here if needed.
switch (cmd) {
case JniCommand::JNI_CMD_INIT_WINDOW: {
if (isWindowInitialized) {
return;
}
isWindowInitialized = true;
// cc::CustomEvent event;
// event.name = EVENT_RECREATE_WINDOW;
// event.args->ptrVal = reinterpret_cast<void*>(getWindowHandle());
ISystemWindowInfo info;
info.width = getWidth();
info.height = getHeight();
info.externalHandle = getWindowHandle();
BasePlatform* platform = cc::BasePlatform::getPlatform();
auto* windowMgr = platform->getInterface<SystemWindowManager>();
CC_ASSERT(windowMgr != nullptr);
windowMgr->createWindow(info);
events::WindowRecreated::broadcast(ISystemWindow::mainWindowId);
} break;
case JniCommand::JNI_CMD_TERM_WINDOW: {
events::WindowDestroy::broadcast(ISystemWindow::mainWindowId);
} break;
case JniCommand::JNI_CMD_RESUME: {
events::WindowChanged::broadcast(WindowEvent::Type::SHOW);
} break;
case JniCommand::JNI_CMD_PAUSE: {
events::WindowChanged::broadcast(WindowEvent::Type::HIDDEN);
} break;
case JniCommand::JNI_CMD_DESTROY: {
LOGV("APP_CMD_DESTROY");
events::WindowChanged::broadcast(WindowEvent::Type::CLOSE);
setRunning(false);
} break;
case JniCommand::JNI_CMD_LOW_MEMORY: {
events::LowMemory::broadcast();
break;
}
default:
break;
}
}
void JniNativeGlue::postExecCmd(JniCommand cmd) {
switch (cmd) {
case JniCommand::JNI_CMD_TERM_WINDOW: {
#if CC_PLATFORM == CC_PLATFORM_ANDROID
if (_window) {
ANativeWindow_release(_window);
}
#endif
_window = nullptr;
} break;
default:
break;
}
}
int32_t JniNativeGlue::getWidth() const {
int32_t width = 0;
if (_window) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
width = ANativeWindow_getWidth(_window);
#elif (CC_PLATFORM == CC_PLATFORM_OHOS)
width = NativeLayerHandle(_window, NativeLayerOps::GET_WIDTH);
#endif
}
return width;
}
int32_t JniNativeGlue::getHeight() const {
int32_t height = 0;
if (_window) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
height = ANativeWindow_getHeight(_window);
#elif (CC_PLATFORM == CC_PLATFORM_OHOS)
height = NativeLayerHandle(_window, NativeLayerOps::GET_HEIGHT);
#endif
}
return height;
}
} // namespace cc

View File

@@ -0,0 +1,142 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <functional>
#include <future>
#include <memory>
#include "base/Macros.h"
#include "platform/java/jni/glue/MessagePipe.h"
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
#include <android/asset_manager.h>
#include <android/native_window.h>
using ResourceManagerType = AAssetManager;
using NativeWindowType = ANativeWindow;
#elif (CC_PLATFORM == CC_PLATFORM_OHOS)
#include <native_layer.h>
#include <rawfile/resource_manager.h>
using ResourceManagerType = ResourceManager;
using NativeWindowType = NativeLayer;
#endif
using NativeActivity = void*; //jobject
using NativeEnv = void*; //jnienv
namespace cc {
class IEventDispatch;
class TouchEvent;
class CC_DLL JniNativeGlue {
public:
enum class JniCommand {
JNI_CMD_TERM_WINDOW = 0,
JNI_CMD_INIT_WINDOW,
JNI_CMD_RESUME,
JNI_CMD_PAUSE,
JNI_CMD_DESTROY,
JNI_CMD_LOW_MEMORY,
JNI_CMD_UNKNOW,
};
virtual ~JniNativeGlue();
static JniNativeGlue* getInstance();
virtual void start(int argc, const char** argv);
void setWindowHandle(NativeWindowType* window);
NativeWindowType* getWindowHandle();
void setActivityGetter(std::function<NativeActivity(void)>);
void* getActivity();
void setEnvGetter(std::function<NativeEnv(void)>);
void* getEnv();
void setResourceManager(ResourceManagerType* resourceManager);
ResourceManagerType* getResourceManager();
void setSdkVersion(int sdkVersion);
int getSdkVersion() const;
void setObbPath(const std::string& path);
std::string getObbPath() const;
bool isRunning() const;
void setRunning(bool isRunning);
void waitRunning();
void flushTasksOnGameThread() const;
struct CommandMsg {
JniCommand cmd;
std::function<void()> callback;
};
void writeCommandAsync(JniCommand cmd);
void writeCommandSync(JniCommand cmd);
int readCommand(CommandMsg* msg);
int readCommandWithTimeout(CommandMsg* cmd, int delayMS);
void onPause();
void onResume();
void onLowMemory();
bool isPause() const;
void execCommand();
int32_t getWidth() const;
int32_t getHeight() const;
bool isAnimating() const { return _animating; }
private:
void preExecCmd(JniCommand cmd);
void engineHandleCmd(JniCommand cmd);
void postExecCmd(JniCommand cmd);
bool _running{false};
int _sdkVersion{0};
bool _animating{false};
std::promise<void> _threadPromise;
std::string _obbPath;
ResourceManagerType* _resourceManager{nullptr};
NativeWindowType* _window{nullptr};
NativeWindowType* _pendingWindow{nullptr};
JniCommand _appState{JniCommand::JNI_CMD_UNKNOW};
IEventDispatch* _eventDispatcher{nullptr};
std::unique_ptr<MessagePipe> _messagePipe{nullptr};
std::function<NativeEnv(void)> _envGetter;
std::function<NativeActivity(void)> _activityGetter;
};
} // namespace cc
#define JNI_NATIVE_GLUE() cc::JniNativeGlue::getInstance()

View File

@@ -0,0 +1,89 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/jni/glue/MessagePipe.h"
#include <fcntl.h>
#include <unistd.h>
#include "platform/java/jni/log.h"
//#include <android/log.h>
//#include "platform/android/jni/JniCocosActivity.h"
namespace cc {
MessagePipe::MessagePipe() {
int messagePipe[2] = {0};
if (pipe(messagePipe)) {
LOGV("Can not create pipe: %s", strerror(errno));
}
_pipeRead = messagePipe[0];
_pipeWrite = messagePipe[1];
if (fcntl(_pipeRead, F_SETFL, O_NONBLOCK) < 0) {
LOGV("Can not make pipe read to non blocking mode.");
}
}
MessagePipe::~MessagePipe() {
close(_pipeRead);
close(_pipeWrite);
}
void MessagePipe::writeCommand(int8_t cmd) const {
write(_pipeWrite, &cmd, sizeof(cmd));
}
int MessagePipe::readCommand(int8_t &cmd) const {
return read(_pipeRead, &cmd, sizeof(cmd));
}
int MessagePipe::readCommandWithTimeout(void *msg, int32_t size, int delayMS) {
if (delayMS > 0) {
static fd_set fdSet;
static timeval timeout;
timeout = {delayMS / 1000, (delayMS % 1000) * 1000};
FD_ZERO(&fdSet);
FD_SET(_pipeRead, &fdSet);
auto ret = select(_pipeRead + 1, &fdSet, nullptr, nullptr, &timeout);
if (ret < 0) {
LOGV("failed to run select(..): %s\n", strerror(errno));
return ret;
}
if (ret == 0) {
return 0;
}
}
return readCommand(msg, size);
}
void MessagePipe::writeCommand(void *msg, int32_t size) const {
write(_pipeWrite, msg, size);
}
int MessagePipe::readCommand(void *msg, int32_t size) const {
return read(_pipeRead, msg, size);
}
} // namespace cc

View File

@@ -0,0 +1,48 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <iostream>
#include "base/Macros.h"
namespace cc {
class CC_DLL MessagePipe {
public:
MessagePipe();
~MessagePipe();
void writeCommand(int8_t cmd) const;
int readCommand(int8_t &cmd) const;
void writeCommand(void *msg, int32_t size) const;
int readCommand(void *msg, int32_t size) const;
int readCommandWithTimeout(void *msg, int32_t size, int delayMS);
private:
int _pipeRead = 0;
int _pipeWrite = 0;
};
} // namespace cc

View File

@@ -0,0 +1,37 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#define JNI_IMP_LOG_TAG "JniImp"
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
#include <android/log.h>
#define LOGV(...) __android_log_print(ANDROID_LOG_INFO, "CocosActivity JNI", __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, JNI_IMP_LOG_TAG, __VA_ARGS__)
#elif (CC_PLATFORM == CC_PLATFORM_OHOS)
#include <hilog/log.h>
#define LOGV(...) HILOG_INFO(LOG_APP, __VA_ARGS__)
#define LOGD(...)
#endif

View File

@@ -0,0 +1,60 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/Accelerometer.h"
#include "platform/java/jni/JniImp.h"
namespace cc {
void Accelerometer::setAccelerometerEnabled(bool isEnabled) {
setAccelerometerEnabledJNI(isEnabled);
}
void Accelerometer::setAccelerometerInterval(float interval) {
setAccelerometerIntervalJNI(interval);
}
const Accelerometer::MotionValue &Accelerometer::getDeviceMotionValue() {
static MotionValue motionValue;
float *v = getDeviceMotionValueJNI();
if (v) {
motionValue.accelerationIncludingGravityX = v[0];
motionValue.accelerationIncludingGravityY = v[1];
motionValue.accelerationIncludingGravityZ = v[2];
motionValue.accelerationX = v[3];
motionValue.accelerationY = v[4];
motionValue.accelerationZ = v[5];
motionValue.rotationRateAlpha = v[6];
motionValue.rotationRateBeta = v[7];
motionValue.rotationRateGamma = v[8];
} else {
memset(&motionValue, 0, sizeof(motionValue));
}
return motionValue;
}
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/IAccelerometer.h"
namespace cc {
class Accelerometer : public IAccelerometer {
public:
/**
* To enable or disable accelerometer.
*/
void setAccelerometerEnabled(bool isEnabled) override;
/**
* Sets the interval of accelerometer.
*/
void setAccelerometerInterval(float interval) override;
/**
* Gets the motion value of current device.
*/
const MotionValue &getDeviceMotionValue() override;
};
} // namespace cc

View File

@@ -0,0 +1,34 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/Battery.h"
#include "platform/java/jni/JniImp.h"
namespace cc {
float Battery::getBatteryLevel() const {
return getBatteryLevelJNI();
}
} // namespace cc

View File

@@ -0,0 +1,36 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/IBattery.h"
namespace cc {
class Battery : public IBattery {
public:
float getBatteryLevel() const override;
};
} // namespace cc

View File

@@ -0,0 +1,343 @@
/****************************************************************************
Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/CanvasRenderingContext2DDelegate.h"
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
#include <android/bitmap.h>
#else
#include <multimedia/image/image_pixel_map.h>
#endif
namespace {
} // namespace
#define CLAMP(V, HI) std::min((V), (HI))
namespace cc {
CanvasRenderingContext2DDelegate::CanvasRenderingContext2DDelegate() {
jobject obj = JniHelper::newObject(JCLS_CANVASIMPL);
_obj = JniHelper::getEnv()->NewGlobalRef(obj);
ccDeleteLocalRef(JniHelper::getEnv(), obj);
}
CanvasRenderingContext2DDelegate::~CanvasRenderingContext2DDelegate() {
JniHelper::getEnv()->DeleteGlobalRef(_obj);
}
void CanvasRenderingContext2DDelegate::recreateBuffer(float w, float h) {
_bufferWidth = w;
_bufferHeight = h;
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "recreateBuffer", w, h);
}
void CanvasRenderingContext2DDelegate::beginPath() {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "beginPath");
}
void CanvasRenderingContext2DDelegate::closePath() {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "closePath");
}
void CanvasRenderingContext2DDelegate::moveTo(float x, float y) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "moveTo", x, y);
}
void CanvasRenderingContext2DDelegate::lineTo(float x, float y) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "lineTo", x, y);
}
void CanvasRenderingContext2DDelegate::stroke() {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "stroke");
}
void CanvasRenderingContext2DDelegate::fill() {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "fill");
}
void CanvasRenderingContext2DDelegate::rect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "rect", x, y, w, h);
}
void CanvasRenderingContext2DDelegate::saveContext() {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "saveContext");
}
void CanvasRenderingContext2DDelegate::restoreContext() {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "restoreContext");
}
void CanvasRenderingContext2DDelegate::clearRect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
if (x >= _bufferWidth || y >= _bufferHeight) {
return;
}
if (x + w > _bufferWidth) {
w = _bufferWidth - x;
}
if (y + h > _bufferHeight) {
h = _bufferHeight - y;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "clearRect", x, y, w, h);
}
void CanvasRenderingContext2DDelegate::fillRect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
if (x >= _bufferWidth || y >= _bufferHeight) {
return;
}
if (x + w > _bufferWidth) {
w = _bufferWidth - x;
}
if (y + h > _bufferHeight) {
h = _bufferHeight - y;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "fillRect", x, y, w, h);
}
void CanvasRenderingContext2DDelegate::fillText(const ccstd::string &text, float x, float y, float maxWidth) {
if (text.empty() || _bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "fillText", text, x, y, maxWidth);
}
void CanvasRenderingContext2DDelegate::strokeText(const ccstd::string &text, float x, float y, float maxWidth) {
if (text.empty() || _bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "strokeText", text, x, y, maxWidth);
}
CanvasRenderingContext2DDelegate::Size CanvasRenderingContext2DDelegate::measureText(const ccstd::string &text) {
if (text.empty()) {
return ccstd::array<float, 2>{0.0F, 0.0F};
}
float measureText1 = JniHelper::callObjectFloatMethod(_obj, JCLS_CANVASIMPL, "measureText", text);
Size size{measureText1, 0.0F};
return size;
}
void CanvasRenderingContext2DDelegate::updateFont(const ccstd::string &fontName, float fontSize, bool bold, bool italic, bool oblique, bool smallCaps) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "updateFont", fontName, fontSize, bold, italic, oblique, smallCaps);
}
void CanvasRenderingContext2DDelegate::setLineCap(const ccstd::string &lineCap) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setLineCap", lineCap);
}
void CanvasRenderingContext2DDelegate::setLineJoin(const ccstd::string &lineJoin) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setLineJoin", lineJoin);
}
void CanvasRenderingContext2DDelegate::setTextAlign(TextAlign align) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setTextAlign", static_cast<int>(align));
}
void CanvasRenderingContext2DDelegate::setTextBaseline(TextBaseline baseline) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setTextBaseline", static_cast<int>(baseline));
}
void CanvasRenderingContext2DDelegate::setFillStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setFillStyle",
static_cast<jint>(r),
static_cast<jint>(g),
static_cast<jint>(b),
static_cast<jint>(a));
}
void CanvasRenderingContext2DDelegate::setStrokeStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setStrokeStyle",
static_cast<jint>(r),
static_cast<jint>(g),
static_cast<jint>(b),
static_cast<jint>(a));
}
void CanvasRenderingContext2DDelegate::setLineWidth(float lineWidth) {
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setLineWidth", lineWidth);
}
const cc::Data &CanvasRenderingContext2DDelegate::getDataRef() const {
return _data;
}
void CanvasRenderingContext2DDelegate::fillImageData(const Data &imageData, float imageWidth, float imageHeight, float offsetX, float offsetY) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
auto *arr = JniHelper::getEnv()->NewIntArray(imageData.getSize() / 4);
JniHelper::getEnv()->SetIntArrayRegion(arr, 0, imageData.getSize() / 4,
reinterpret_cast<const jint *>(imageData.getBytes()));
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "_fillImageData", arr, imageWidth,
imageHeight, offsetX, offsetY);
ccDeleteLocalRef(JniHelper::getEnv(), arr);
}
void CanvasRenderingContext2DDelegate::updateData() {
jobject bmpObj = nullptr;
JniMethodInfo methodInfo;
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
if (JniHelper::getMethodInfo(methodInfo, JCLS_CANVASIMPL, "getBitmap", "()Landroid/graphics/Bitmap;")) {
bmpObj = methodInfo.env->CallObjectMethod(_obj, methodInfo.methodID);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
#else
if (JniHelper::getMethodInfo(methodInfo, JCLS_CANVASIMPL, "getBitmap", "()Lohos/media/image/PixelMap;")) {
bmpObj = methodInfo.env->CallObjectMethod(_obj, methodInfo.methodID);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
#endif
JNIEnv *env = JniHelper::getEnv();
do {
if (nullptr == bmpObj) {
break;
}
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
AndroidBitmapInfo bmpInfo;
if (AndroidBitmap_getInfo(env, bmpObj, &bmpInfo) != ANDROID_BITMAP_RESULT_SUCCESS) {
CC_LOG_ERROR("AndroidBitmap_getInfo() failed ! error");
break;
}
if (bmpInfo.width < 1 || bmpInfo.height < 1) {
break;
}
void *pixelData;
if (AndroidBitmap_lockPixels(env, bmpObj, &pixelData) != ANDROID_BITMAP_RESULT_SUCCESS) {
CC_LOG_ERROR("AndroidBitmap_lockPixels() failed ! error");
break;
}
uint32_t size = bmpInfo.stride * bmpInfo.height;
#else
OhosPixelMapInfo bmpInfo;
void *pixelData = nullptr;
if (GetImageInfo(env, bmpObj, bmpInfo) ==
OHOS_IMAGE_RESULT_SUCCESS &&
bmpInfo.width > 0 &&
bmpInfo.height > 0 &&
bmpInfo.pixelFormat == OHOS_PIXEL_MAP_FORMAT_RGBA_8888) {
if (AccessPixels(env, bmpObj, &pixelData) != OHOS_IMAGE_RESULT_SUCCESS) {
CC_LOG_ERROR("AccessPixels() failed ! error");
break;
}
} else {
break;
}
uint32_t size = bmpInfo.rowSize * bmpInfo.height;
#endif
auto *bmpData = static_cast<jbyte *>(malloc(size));
memcpy(bmpData, pixelData, size);
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
unMultiplyAlpha(reinterpret_cast<unsigned char *>(bmpData), size);
#endif
_data.fastSet(reinterpret_cast<unsigned char *>(bmpData), size);
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
AndroidBitmap_unlockPixels(env, bmpObj);
#else
UnAccessPixels(env, bmpObj);
#endif
} while (false);
if (bmpObj) {
env->DeleteLocalRef(bmpObj);
}
}
void CanvasRenderingContext2DDelegate::unMultiplyAlpha(unsigned char *ptr, uint32_t size) { // NOLINT(readability-convert-member-functions-to-static)
// Android source data is not premultiplied alpha when API >= 19
// please refer CanvasRenderingContext2DImpl::recreateBuffer(float w, float h)
// in CanvasRenderingContext2DImpl.java
// if (getAndroidSDKInt() >= 19)
// return;
float alpha;
for (int i = 0; i < size; i += 4) {
alpha = static_cast<float>(ptr[i + 3]);
if (alpha > 0) {
ptr[i] = CLAMP((int)((float)ptr[i] / alpha * 255), 255);
ptr[i + 1] = CLAMP((int)((float)ptr[i + 1] / alpha * 255), 255);
ptr[i + 2] = CLAMP((int)((float)ptr[i + 2] / alpha * 255), 255);
}
}
}
void CanvasRenderingContext2DDelegate::setShadowBlur(float blur) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setShadowBlur", blur);
#else
CC_LOG_WARNING("shadowBlur not implemented");
#endif
}
void CanvasRenderingContext2DDelegate::setShadowColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setShadowColor",
static_cast<jint>(r),
static_cast<jint>(g),
static_cast<jint>(b),
static_cast<jint>(a));
#else
CC_LOG_WARNING("shadowColor not implemented");
#endif
}
void CanvasRenderingContext2DDelegate::setShadowOffsetX(float offsetX) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setShadowOffsetX", offsetX);
#else
CC_LOG_WARNING("shadowOffsetX not implemented");
#endif
}
void CanvasRenderingContext2DDelegate::setShadowOffsetY(float offsetY) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
JniHelper::callObjectVoidMethod(_obj, JCLS_CANVASIMPL, "setShadowOffsetY", offsetY);
#else
CC_LOG_WARNING("shadowOffsetY not implemented");
#endif
}
} // namespace cc

View File

@@ -0,0 +1,101 @@
/****************************************************************************
Copyright (c) 2018-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/canvas/ICanvasRenderingContext2D.h"
#include "base/csscolorparser.h"
#include "bindings/jswrapper/config.h"
#include "math/Math.h"
#include "cocos/bindings/jswrapper/SeApi.h"
#include "platform/java/jni/JniHelper.h"
#include "platform/java/jni/JniImp.h"
#if __OHOS__
#include <hilog/log.h>
#endif
#include <regex>
#ifndef JCLS_CANVASIMPL
#define JCLS_CANVASIMPL "com/cocos/lib/CanvasRenderingContext2DImpl"
#endif
#include "base/std/container/array.h"
namespace cc {
class CanvasRenderingContext2DDelegate : public ICanvasRenderingContext2D::Delegate {
public:
using Size = ccstd::array<float, 2>;
using TextAlign = ICanvasRenderingContext2D::TextAlign;
using TextBaseline = ICanvasRenderingContext2D::TextBaseline;
CanvasRenderingContext2DDelegate();
~CanvasRenderingContext2DDelegate() override;
void recreateBuffer(float w, float h) override;
void beginPath() override;
void closePath() override;
void moveTo(float x, float y) override;
void lineTo(float x, float y) override;
void stroke() override;
void saveContext() override;
void restoreContext() override;
void clearRect(float /*x*/, float /*y*/, float w, float h) override;
void fill() override;
void setLineCap(const ccstd::string &lineCap) override;
void setLineJoin(const ccstd::string &lineJoin) override;
void rect(float x, float y, float w, float h) override;
void fillRect(float x, float y, float w, float h) override;
void fillText(const ccstd::string &text, float x, float y, float /*maxWidth*/) override;
void strokeText(const ccstd::string &text, float /*x*/, float /*y*/, float /*maxWidth*/) override;
Size measureText(const ccstd::string &text) override;
void updateFont(const ccstd::string &fontName, float fontSize, bool bold, bool italic, bool oblique, bool smallCaps) override;
void setTextAlign(TextAlign align) override;
void setTextBaseline(TextBaseline baseline) override;
void setFillStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override;
void setStrokeStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override;
void setLineWidth(float lineWidth) override;
const cc::Data &getDataRef() const override;
void fillImageData(const Data &imageData, float imageWidth, float imageHeight, float offsetX, float offsetY) override;
void updateData() override;
void setShadowBlur(float blur) override;
void setShadowColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override;
void setShadowOffsetX(float offsetX) override;
void setShadowOffsetY(float offsetY) override;
private:
void unMultiplyAlpha(unsigned char *ptr, uint32_t size);
public:
private:
jobject _obj = nullptr;
Data _data;
float _bufferWidth = 0.0F;
float _bufferHeight = 0.0F;
};
} // namespace cc

View File

@@ -0,0 +1,103 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/CommonScreen.h"
#include "cocos/bindings/jswrapper/SeApi.h"
#include "platform/java/jni/JniImp.h"
namespace {
// constant from Android API:
// reference: https://developer.android.com/reference/android/view/Surface#ROTATION_0
enum Rotation {
ROTATION_0 = 0,
ROTATION_90,
ROTATION_180,
ROTATION_270
};
} // namespace
namespace cc {
// int Screen::getDPI() {
// static int dpi = -1;
// if (dpi == -1) {
// AConfiguration *config = AConfiguration_new();
// //AConfiguration_fromAssetManager(config, cocosApp.assetManager);
// int32_t density = AConfiguration_getDensity(config);
// AConfiguration_delete(config);
// const int stdDpi = 160;
// dpi = density * stdDpi;
// }
// return dpi;
// }
float CommonScreen::getDevicePixelRatio() const {
return 1;
}
void CommonScreen::setKeepScreenOn(bool keepScreenOn) {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "setKeepScreenOn", value);
// ANativeActivity_setWindowFlags(JniHelper::getAndroidApp()->activity, AWINDOW_FLAG_KEEP_SCREEN_ON, 0);
//CC_UNUSED_PARAM(keepScreenOn);
return setKeepScreenOnJNI(keepScreenOn);
}
IScreen::Orientation CommonScreen::getDeviceOrientation() const {
int rotation = getDeviceRotationJNI();
switch (rotation) {
case ROTATION_0:
return Orientation::PORTRAIT;
case ROTATION_90:
return Orientation::LANDSCAPE_RIGHT;
case ROTATION_180:
return Orientation::PORTRAIT_UPSIDE_DOWN;
case ROTATION_270:
return Orientation::LANDSCAPE_LEFT;
default:
break;
}
return Orientation::PORTRAIT;
}
Vec4 CommonScreen::getSafeAreaEdge() const {
float *data = getSafeAreaEdgeJNI();
return cc::Vec4(data[0], data[1], data[2], data[3]);
}
bool CommonScreen::isDisplayStats() { //NOLINT
se::AutoHandleScope hs;
se::Value ret;
char commandBuf[100] = "cc.debug.isDisplayStats();";
se::ScriptEngine::getInstance()->evalString(commandBuf, 100, &ret);
return ret.toBoolean();
}
void CommonScreen::setDisplayStats(bool isShow) { //NOLINT
se::AutoHandleScope hs;
char commandBuf[100] = {0};
sprintf(commandBuf, "cc.debug.setDisplayStats(%s);", isShow ? "true" : "false");
se::ScriptEngine::getInstance()->evalString(commandBuf);
}
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/IScreen.h"
namespace cc {
class CommonScreen : public IScreen {
public:
float getDevicePixelRatio() const override;
void setKeepScreenOn(bool keepScreenOn) override;
Orientation getDeviceOrientation() const override;
Vec4 getSafeAreaEdge() const override;
/**
@brief Get current display stats.
@return bool, is displaying stats or not.
*/
bool isDisplayStats() override;
/**
@brief set display stats information.
*/
void setDisplayStats(bool isShow) override;
};
} // namespace cc

View File

@@ -0,0 +1,102 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/CommonSystem.h"
#include "platform/java/jni/JniHelper.h"
#include "platform/java/jni/JniImp.h"
namespace cc {
CommonSystem::CommonSystem() = default;
CommonSystem::~CommonSystem() = default;
ccstd::string CommonSystem::getDeviceModel() const {
return getDeviceModelJNI();
}
CommonSystem::LanguageType CommonSystem::getCurrentLanguage() const {
ccstd::string languageName = getCurrentLanguageJNI();
const char *pLanguageName = languageName.c_str();
LanguageType ret = LanguageType::ENGLISH;
if (0 == strcmp("zh", pLanguageName)) {
ret = LanguageType::CHINESE;
} else if (0 == strcmp("en", pLanguageName)) {
ret = LanguageType::ENGLISH;
} else if (0 == strcmp("fr", pLanguageName)) {
ret = LanguageType::FRENCH;
} else if (0 == strcmp("it", pLanguageName)) {
ret = LanguageType::ITALIAN;
} else if (0 == strcmp("de", pLanguageName)) {
ret = LanguageType::GERMAN;
} else if (0 == strcmp("es", pLanguageName)) {
ret = LanguageType::SPANISH;
} else if (0 == strcmp("ru", pLanguageName)) {
ret = LanguageType::RUSSIAN;
} else if (0 == strcmp("nl", pLanguageName)) {
ret = LanguageType::DUTCH;
} else if (0 == strcmp("ko", pLanguageName)) {
ret = LanguageType::KOREAN;
} else if (0 == strcmp("ja", pLanguageName)) {
ret = LanguageType::JAPANESE;
} else if (0 == strcmp("hu", pLanguageName)) {
ret = LanguageType::HUNGARIAN;
} else if (0 == strcmp("pt", pLanguageName)) {
ret = LanguageType::PORTUGUESE;
} else if (0 == strcmp("ar", pLanguageName)) {
ret = LanguageType::ARABIC;
} else if (0 == strcmp("nb", pLanguageName)) {
ret = LanguageType::NORWEGIAN;
} else if (0 == strcmp("pl", pLanguageName)) {
ret = LanguageType::POLISH;
} else if (0 == strcmp("tr", pLanguageName)) {
ret = LanguageType::TURKISH;
} else if (0 == strcmp("uk", pLanguageName)) {
ret = LanguageType::UKRAINIAN;
} else if (0 == strcmp("ro", pLanguageName)) {
ret = LanguageType::ROMANIAN;
} else if (0 == strcmp("bg", pLanguageName)) {
ret = LanguageType::BULGARIAN;
} else if (0 == strcmp("hi", pLanguageName)) {
ret = LanguageType::HINDI;
}
return ret;
}
ccstd::string CommonSystem::getCurrentLanguageCode() const {
return getCurrentLanguageCodeJNI();
}
ccstd::string CommonSystem::getSystemVersion() const {
return getSystemVersionJNI();
}
bool CommonSystem::openURL(const ccstd::string &url) {
return openURLJNI(url);
}
void CommonSystem::copyTextToClipboard(const ccstd::string &text) {
copyTextToClipboardJNI(text);
}
} // namespace cc

View File

@@ -0,0 +1,64 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/ISystem.h"
namespace cc {
class CommonSystem : public ISystem {
public:
CommonSystem();
~CommonSystem() override;
/**
@brief Get target device model.
*/
ccstd::string getDeviceModel() const override;
/**
@brief Get current language config.
@return Current language config.
*/
LanguageType getCurrentLanguage() const override;
/**
@brief Get current language iso 639-1 code.
@return Current language iso 639-1 code.
*/
ccstd::string getCurrentLanguageCode() const override;
/**
@brief Get system version.
@return system version.
*/
ccstd::string getSystemVersion() const override;
/**
@brief Open url in default browser.
@param String with url to open.
@return True if the resource located by the URL was successfully opened; otherwise false.
*/
bool openURL(const ccstd::string& url) override;
void copyTextToClipboard(const std::string& text) override;
};
} // namespace cc

View File

@@ -0,0 +1,34 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/Network.h"
#include "platform/java/jni/JniImp.h"
namespace cc {
INetwork::NetworkType Network::getNetworkType() const {
return static_cast<INetwork::NetworkType>(getNetworkTypeJNI());
}
} // namespace cc

View File

@@ -0,0 +1,36 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/INetwork.h"
namespace cc {
class Network : public INetwork {
public:
NetworkType getNetworkType() const override;
};
} // namespace cc

View File

@@ -0,0 +1,126 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/SystemWindow.h"
#include <fcntl.h>
#include <jni.h>
#include <unistd.h>
#include <functional>
#include <thread>
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
#include <android/native_window.h>
#endif
#include "BasePlatform.h"
#include "base/Log.h"
#include "base/Macros.h"
#include "platform/java/jni/JniHelper.h"
#include "platform/java/jni/JniImp.h"
#include "platform/java/jni/glue/JniNativeGlue.h"
namespace {
#ifndef JCLS_COCOSACTIVITY
#define JCLS_COCOSACTIVITY "com/cocos/lib/CocosActivity"
#endif
} // namespace
namespace cc {
SystemWindow::SystemWindow(uint32_t windowId, void *externalHandle)
: _windowHandle(externalHandle), _windowId(windowId) {
}
void SystemWindow::setCursorEnabled(bool value) {
}
void SystemWindow::setWindowHandle(void *handle) {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
//The getWindowHandle interface may have been called earlier, causing _handleMutex to be occupied all the time.
bool lockSuccess = _handleMutex.try_lock();
bool needNotify = _windowHandle == nullptr;
_windowHandle = handle;
if (needNotify) {
_windowHandlePromise.set_value();
}
if (lockSuccess) {
_handleMutex.unlock();
}
#else
_windowHandle = handle;
#endif
}
uintptr_t SystemWindow::getWindowHandle() const {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
std::lock_guard lock(const_cast<std::mutex &>(_handleMutex));
if (!_windowHandle) {
auto &future = const_cast<std::promise<void> &>(_windowHandlePromise);
future.get_future().get();
}
CC_ASSERT(_windowHandle);
return reinterpret_cast<uintptr_t>(_windowHandle);
#else
return reinterpret_cast<uintptr_t>(
JNI_NATIVE_GLUE()->getWindowHandle());
#endif
}
SystemWindow::Size SystemWindow::getViewSize() const {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
CC_ASSERT(_windowHandle);
auto *nativeWindow = static_cast<ANativeWindow *>(_windowHandle);
return Size{static_cast<float>(ANativeWindow_getWidth(nativeWindow)),
static_cast<float>(ANativeWindow_getHeight(nativeWindow))};
#else
return Size{static_cast<float>(JNI_NATIVE_GLUE()->getWidth()),
static_cast<float>(JNI_NATIVE_GLUE()->getHeight())};
#endif
}
void SystemWindow::closeWindow() {
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
finishActivity();
#else
events::Close::broadcast();
exit(0); //TODO(cc): better exit for ohos
#endif
}
bool SystemWindow::createWindow(const char *title, int x, int y, int w, int h, int flags) {
CC_UNUSED_PARAM(title);
CC_UNUSED_PARAM(flags);
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
cc::JniHelper::callObjectVoidMethod(cc::JniHelper::getActivity(), JCLS_COCOSACTIVITY, "createSurface", x, y, w, h, static_cast<jint>(_windowId));
#endif
return true;
}
bool SystemWindow::createWindow(const char *title, int w, int h, int flags) {
CC_UNUSED_PARAM(title);
CC_UNUSED_PARAM(flags);
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
cc::JniHelper::callObjectVoidMethod(cc::JniHelper::getActivity(), JCLS_COCOSACTIVITY, "createSurface", 0, 0, w, h, static_cast<jint>(_windowId));
#endif
return true;
}
} // namespace cc

View File

@@ -0,0 +1,61 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <future>
#include <iostream>
#include "platform/interfaces/modules/ISystemWindow.h"
namespace cc {
class SystemWindow : public ISystemWindow {
public:
SystemWindow(uint32_t windowId, void *externalHandle);
bool createWindow(const char *title, int x, int y, int w, int h, int flags) override;
bool createWindow(const char *title, int w, int h, int flags) override;
/**
@brief enable/disable(lock) the cursor, default is enabled
*/
void setCursorEnabled(bool value) override;
void setWindowHandle(void *handle);
uintptr_t getWindowHandle() const override;
uint32_t getWindowId() const override { return _windowId; }
Size getViewSize() const override;
void closeWindow() override;
private:
std::mutex _handleMutex;
std::promise<void> _windowHandlePromise;
uint32_t _windowId{0};
void *_windowHandle{nullptr};
};
} // namespace cc

View File

@@ -0,0 +1,85 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "SystemWindowManager.h"
#include "BasePlatform.h"
#include "platform/java/modules/SystemWindow.h"
namespace cc {
int SystemWindowManager::init() {
return 0;
}
void SystemWindowManager::processEvent() {
}
ISystemWindow *SystemWindowManager::createWindow(const ISystemWindowInfo &info) {
if (!isExternalHandleExist(info.externalHandle)) {
ISystemWindow *window = BasePlatform::getPlatform()->createNativeWindow(_nextWindowId, info.externalHandle);
if (window) {
if (!info.externalHandle) {
window->createWindow(info.title.c_str(), info.x, info.y, info.width, info.height, info.flags);
}
_windows[_nextWindowId] = std::shared_ptr<ISystemWindow>(window);
_nextWindowId++;
}
return window;
}
return getWindowFromANativeWindow(static_cast<ANativeWindow *>(info.externalHandle));
}
ISystemWindow *SystemWindowManager::getWindow(uint32_t windowId) const {
if (windowId == 0) {
return nullptr;
}
auto iter = _windows.find(windowId);
if (iter != _windows.end()) {
return iter->second.get();
}
return nullptr;
}
ISystemWindow *SystemWindowManager::getWindowFromANativeWindow(ANativeWindow *window) const {
if (!window) {
return nullptr;
}
for (const auto &pair : _windows) {
ISystemWindow *sysWindow = pair.second.get();
auto *nativeWindow = reinterpret_cast<ANativeWindow *>(sysWindow->getWindowHandle());
if (nativeWindow == window) {
return sysWindow;
}
}
return nullptr;
}
bool SystemWindowManager::isExternalHandleExist(void *externalHandle) const {
return std::any_of(_windows.begin(), _windows.end(), [externalHandle](const auto &pair) {
auto *handle = reinterpret_cast<void *>(pair.second->getWindowHandle());
return handle == externalHandle;
});
}
} // namespace cc

View File

@@ -0,0 +1,52 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/std/container/unordered_map.h"
#include "platform/interfaces/modules/ISystemWindowManager.h"
struct ANativeWindow;
namespace cc {
class ISystemWindow;
class SystemWindowManager : public ISystemWindowManager {
public:
SystemWindowManager() = default;
int init() override;
void processEvent() override;
ISystemWindow *createWindow(const ISystemWindowInfo &info) override;
ISystemWindow *getWindow(uint32_t windowId) const override;
const SystemWindowMap &getWindows() const override { return _windows; }
ISystemWindow *getWindowFromANativeWindow(ANativeWindow *window) const;
bool isExternalHandleExist(void *handle) const;
private:
uint32_t _nextWindowId{1}; // start from 1, 0 means an invalid ID
SystemWindowMap _windows;
};
} // namespace cc

View File

@@ -0,0 +1,34 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/java/modules/Vibrator.h"
#include "platform/java/jni/JniImp.h"
namespace cc {
void Vibrator::vibrate(float duration) {
setVibrateJNI(duration);
}
} // namespace cc

View File

@@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/interfaces/modules/IVibrator.h"
namespace cc {
class Vibrator : public IVibrator {
public:
/**
* Vibrate for the specified amount of time.
* If vibrate is not supported, then invoking this method has no effect.
* Some platforms limit to a maximum duration of 5 seconds.
* Duration is ignored on iOS due to API limitations.
* @param duration The duration in seconds.
*/
void vibrate(float duration) override;
};
} // namespace cc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/Ptr.h"
#include "base/ThreadPool.h"
#include "platform/interfaces/modules/IXRInterface.h"
#if CC_USE_XR_REMOTE_PREVIEW
#include "xr/XRRemotePreviewManager.h"
#endif
namespace se {
class Object;
}
namespace cc {
class XRInterface : public IXRInterface {
public:
xr::XRVendor getVendor() override;
xr::XRConfigValue getXRConfig(xr::XRConfigKey key) override;
void setXRConfig(xr::XRConfigKey key, xr::XRConfigValue value) override;
uint32_t getRuntimeVersion() override;
void initialize(void *javaVM, void *activity) override;
// render thread lifecycle
void onRenderPause() override;
void onRenderResume() override;
void onRenderDestroy() override;
// render thread lifecycle
// gfx
void preGFXDeviceInitialize(gfx::API gfxApi) override;
void postGFXDeviceInitialize(gfx::API gfxApi) override;
const xr::XRSwapchain &doGFXDeviceAcquire(gfx::API gfxApi) override;
bool isGFXDeviceNeedsPresent(gfx::API gfxApi) override;
void postGFXDevicePresent(gfx::API gfxApi) override;
void createXRSwapchains() override;
const std::vector<cc::xr::XRSwapchain> &getXRSwapchains() override;
gfx::Format getXRSwapchainFormat() override;
void updateXRSwapchainTypedID(uint32_t typedID) override;
// gfx
// vulkan
#ifdef CC_USE_VULKAN
uint32_t getXRVkApiVersion(uint32_t engineVkApiVersion) override;
void initializeVulkanData(const PFN_vkGetInstanceProcAddr &addr) override;
VkInstance createXRVulkanInstance(const VkInstanceCreateInfo &instInfo) override;
VkDevice createXRVulkanDevice(const VkDeviceCreateInfo *deviceInfo) override;
VkPhysicalDevice getXRVulkanGraphicsDevice() override;
void getXRSwapchainVkImages(std::vector<VkImage> &vkImages, uint32_t eye) override;
#endif
// vulkan
// gles
#ifdef CC_USE_GLES3
void initializeGLESData(xr::PFNGLES3WLOADPROC gles3wLoadFuncProc, gfx::GLES3GPUContext *gpuContext) override;
void attachGLESFramebufferTexture2D() override;
EGLSurfaceType acquireEGLSurfaceType(uint32_t typedID) override;
#endif
// gles
// stereo render loop
bool platformLoopStart() override;
bool beginRenderFrame() override;
bool isRenderAllowable() override;
bool beginRenderEyeFrame(uint32_t eye) override;
bool endRenderEyeFrame(uint32_t eye) override;
bool endRenderFrame() override;
bool platformLoopEnd() override;
// stereo render loop
ccstd::vector<float> getHMDViewPosition(uint32_t eye, int trackingType) override;
ccstd::vector<float> getXRViewProjectionData(uint32_t eye, float near, float far) override;
ccstd::vector<float> getXREyeFov(uint32_t eye) override;
// renderwindow
xr::XREye getXREyeByRenderWindow(void *window) override;
void bindXREyeWithRenderWindow(void *window, xr::XREye eye) override;
void handleAppCommand(int appCmd) override;
void adaptOrthographicMatrix(cc::scene::Camera *camera, const ccstd::array<float, 4> &preTransform, Mat4 &proj, Mat4 &view) override;
private:
void loadImageTrackingData(const std::string &imageInfo);
void asyncLoadAssetsImage(const std::string &imagePath);
void dispatchGamepadEventInternal(const xr::XRControllerEvent &xrControllerEvent);
void dispatchHandleEventInternal(const xr::XRControllerEvent &xrControllerEvent);
void dispatchHMDEventInternal(const xr::XRControllerEvent &xrControllerEvent);
ControllerEvent _controllerEvent;
se::Object *_jsPoseEventArray{nullptr};
#if CC_USE_VULKAN
PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr{nullptr};
VkPhysicalDevice _vkPhysicalDevice{nullptr};
VkInstance _vkInstance{nullptr};
VkDevice _vkDevice{nullptr};
#endif
#if CC_USE_GLES3
xr::PFNGLES3WLOADPROC _gles3wLoadFuncProc{nullptr};
gfx::GLES3GPUContext *_gles3GPUContext{nullptr};
#endif
xr::XRSwapchain _acquireSwapchain;
std::vector<cc::xr::XRSwapchain> _xrSwapchains;
bool _renderPaused{false};
bool _renderResumed{false};
bool _isXrEntryInstanceValid{false};
std::unordered_map<void *, xr::XREye> _xrWindowMap;
std::unordered_map<uint32_t, EGLSurfaceType> _eglSurfaceTypeMap;
bool _committedFrame{false};
#if CC_USE_XR_REMOTE_PREVIEW
cc::IntrusivePtr<XRRemotePreviewManager> _xrRemotePreviewManager{nullptr};
#endif
LegacyThreadPool *_gThreadPool{nullptr};
bool _isFlipPixelY{false};
bool _isEnabledEyeRenderJsCallback{false};
};
} // namespace cc