484 lines
15 KiB
C++
484 lines
15 KiB
C++
/****************************************************************************
|
|
Copyright (c) 2018 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 engine source code (the "Software"), a limited,
|
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
|
not use Cocos Creator software for developing other software or tools that's
|
|
used for developing games. You are not granted to publish, distribute,
|
|
sublicense, and/or sell copies of Cocos Creator.
|
|
|
|
The software or tools in this License Agreement are licensed, not sold.
|
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
|
|
|
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"
|
|
#include <unordered_map>
|
|
#include <android/log.h>
|
|
#include <android/asset_manager_jni.h>
|
|
#include <jni.h>
|
|
#include <mutex>
|
|
#include <scripting/js-bindings/manual/jsb_global.h>
|
|
#include "JniHelper.h"
|
|
#include "platform/CCApplication.h"
|
|
#include "scripting/js-bindings/jswrapper/SeApi.h"
|
|
#include "scripting/js-bindings/event/EventDispatcher.h"
|
|
#include "platform/android/CCFileUtils-android.h"
|
|
#include "base/CCScheduler.h"
|
|
#include "base/CCAutoreleasePool.h"
|
|
#include "base/CCGLUtils.h"
|
|
|
|
#define JNI_IMP_LOG_TAG "JniImp"
|
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, JNI_IMP_LOG_TAG, __VA_ARGS__)
|
|
|
|
#ifndef ORG_RENDER_CLASS_NAME
|
|
#define ORG_RENDER_CLASS_NAME org_cocos2dx_lib_Cocos2dxRenderer
|
|
#endif
|
|
#define JNI_RENDER(FUNC) JNI_METHOD1(ORG_RENDER_CLASS_NAME, FUNC)
|
|
|
|
#ifndef ORG_JS_HELPER_CLASS_NAME
|
|
#define ORG_JS_HELPER_CLASS_NAME org_cocos2dx_lib_CocosJSHelper
|
|
#endif
|
|
#define JNI_JS_HELPER(FUNC) JNI_METHOD1(ORG_JS_HELPER_CLASS_NAME, FUNC)
|
|
|
|
#ifndef ORG_ACTIVITY_CLASS_NAME
|
|
#define ORG_ACTIVITY_CLASS_NAME org_cocos2dx_lib_Cocos2dxActivity
|
|
#endif
|
|
#define JNI_ACTIVITY(FUNC) JNI_METHOD1(ORG_ACTIVITY_CLASS_NAME, FUNC)
|
|
|
|
#ifndef ORG_ACCELEROMETER_CLASS_NAME
|
|
#define ORG_ACCELEROMETER_CLASS_NAME org_cocos2dx_lib_Cocos2dxAccelerometer
|
|
#endif
|
|
#define JNI_ACCELEROMETER(FUNC) JNI_METHOD1(ORG_ACCELEROMETER_CLASS_NAME, FUNC)
|
|
|
|
#ifndef ORG_HELPER_CLASS_NAME
|
|
#define ORG_HELPER_CLASS_NAME org_cocos2dx_lib_Cocos2dxHelper
|
|
#endif
|
|
#define JNI_HELPER(FUNC) JNI_METHOD1(ORG_HELPER_CLASS_NAME, FUNC)
|
|
|
|
#ifndef ORG_AUDIOFOCUS_CLASS_NAME
|
|
#define ORG_AUDIOFOCUS_CLASS_NAME org_cocos2dx_lib_Cocos2dxAudioFocusManager
|
|
#endif
|
|
#define JNI_AUDIO(FUNC) JNI_METHOD1(ORG_AUDIOFOCUS_CLASS_NAME, FUNC)
|
|
|
|
#ifndef JCLS_HELPER
|
|
#define JCLS_HELPER "org/cocos2dx/lib/Cocos2dxHelper"
|
|
#endif
|
|
|
|
#ifndef JCLS_RENDERER
|
|
#define JCLS_RENDERER "org/cocos2dx/lib/Cocos2dxRenderer"
|
|
#endif
|
|
|
|
#ifndef JCSDK
|
|
#define JCSDK "com.jc.jcfw.JcSDK"
|
|
#endif
|
|
|
|
#define KEYCODE_BACK 0x04
|
|
#define KEYCODE_MENU 0x52
|
|
#define KEYCODE_DPAD_UP 0x13
|
|
#define KEYCODE_DPAD_DOWN 0x14
|
|
#define KEYCODE_DPAD_LEFT 0x15
|
|
#define KEYCODE_DPAD_RIGHT 0x16
|
|
#define KEYCODE_ENTER 0x42
|
|
#define KEYCODE_DPAD_CENTER 0x17
|
|
|
|
using namespace cocos2d;
|
|
|
|
extern uint32_t __jsbInvocationCount;
|
|
|
|
namespace
|
|
{
|
|
auto _isOpenDebugView = false;
|
|
auto _isGLOptModeEnabled = true;
|
|
std::string g_apkPath;
|
|
EditTextCallback s_editTextCallback = nullptr;
|
|
void *s_ctx = nullptr;
|
|
int g_deviceSampleRate = 44100;
|
|
int g_deviceAudioBufferSizeInFrames = 192;
|
|
int g_width = 0;
|
|
int g_height = 0;
|
|
bool g_isStarted = false;
|
|
bool g_isGameFinished = false;
|
|
int g_SDKInt = 0;
|
|
|
|
cocos2d::Application *g_app = nullptr;
|
|
|
|
bool setCanvasCallback(se::Object *global)
|
|
{
|
|
se::AutoHandleScope scope;
|
|
se::ScriptEngine *se = se::ScriptEngine::getInstance();
|
|
char commandBuf[200] = {0};
|
|
uint8_t devicePixelRatio = Application::getInstance()->getDevicePixelRatio();
|
|
sprintf(commandBuf, "window.innerWidth = %d; window.innerHeight = %d;",
|
|
g_width / devicePixelRatio,
|
|
g_height / devicePixelRatio);
|
|
se->evalString(commandBuf);
|
|
glViewport(0, 0, g_width / devicePixelRatio, g_height / devicePixelRatio);
|
|
glDepthMask(GL_TRUE);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void cocos_jni_env_init(JNIEnv *env);
|
|
|
|
Application *cocos_android_app_init(int width, int height);
|
|
|
|
extern "C"
|
|
{
|
|
void getSDKInt(JNIEnv *env)
|
|
{
|
|
if (env && g_SDKInt == 0)
|
|
{
|
|
// VERSION is a nested class within android.os.Build (hence "$" rather than "/")
|
|
jclass versionClass = env->FindClass("android/os/Build$VERSION");
|
|
if (NULL == versionClass)
|
|
return;
|
|
|
|
jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I");
|
|
if (NULL == sdkIntFieldID)
|
|
return;
|
|
|
|
g_SDKInt = env->GetStaticIntField(versionClass, sdkIntFieldID);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
|
{
|
|
JniHelper::setJavaVM(vm);
|
|
cocos_jni_env_init(JniHelper::getEnv());
|
|
getSDKInt(JniHelper::getEnv());
|
|
|
|
return JNI_VERSION_1_4;
|
|
}
|
|
|
|
|
|
/***********************************************************
|
|
* Cocos2dxHelper native functions implementation.
|
|
***********************************************************/
|
|
|
|
JNIEXPORT void JNICALL JNI_HELPER(nativeSetApkPath)(JNIEnv *env, jclass thiz, jstring apkPath)
|
|
{
|
|
g_apkPath = JniHelper::jstring2string(apkPath);
|
|
LOGD("nativeSetApkPath: %s", g_apkPath.c_str());
|
|
}
|
|
|
|
JNIEXPORT void JNICALL JNI_HELPER(nativeSetContext)(JNIEnv *env, jclass thiz, jobject context, jobject assetManager)
|
|
{
|
|
JniHelper::setClassLoaderFrom(context);
|
|
FileUtilsAndroid::setassetmanager(AAssetManager_fromJava(env, assetManager));
|
|
}
|
|
|
|
JNIEXPORT void JNICALL JNI_HELPER(nativeSetAudioDeviceInfo)(JNIEnv *env, jclass thiz, jboolean isSupportLowLatency, jint deviceSampleRate, jint deviceAudioBufferSizeInFrames)
|
|
{
|
|
g_deviceSampleRate = deviceSampleRate;
|
|
g_deviceAudioBufferSizeInFrames = deviceAudioBufferSizeInFrames;
|
|
LOGD("nativeSetAudioDeviceInfo: sampleRate: %d, bufferSizeInFrames: %d", g_deviceSampleRate, g_deviceAudioBufferSizeInFrames);
|
|
}
|
|
|
|
/***********************************************************
|
|
* Cocos2dxAudioFocusManager native functions implementation.
|
|
***********************************************************/
|
|
|
|
JNIEXPORT void JNICALL JNI_AUDIO(nativeOnAudioFocusChange)(JNIEnv *env, jclass thiz, jint focusChange)
|
|
{
|
|
// cocos_audioengine_focus_change(focusChange);
|
|
}
|
|
|
|
/***********************************************************
|
|
* CocosJSHelper native functions implementation.
|
|
***********************************************************/
|
|
JNIEXPORT void JNICALL JNI_JS_HELPER(nativeJSInit)(JNIEnv *env, jclass clazz, jstring resource_path)
|
|
{
|
|
g_app = cocos_android_app_init(1, 1);
|
|
se::ScriptEngine *se = se::ScriptEngine::getInstance();
|
|
// se->addRegisterCallback(setCanvasCallback);
|
|
|
|
EventDispatcher::init();
|
|
|
|
g_app->start();
|
|
}
|
|
JNIEXPORT void JNICALL JNI_JS_HELPER(initNativeWallet)(JNIEnv *env, jclass clazz, jstring resource_path)
|
|
{
|
|
se::Value rval;
|
|
se::ScriptEngine *se = se::ScriptEngine::getInstance();
|
|
se::AutoHandleScope hs;
|
|
std::string coder = "jc.wallet.currentAccount().address";
|
|
se::ScriptEngine::getInstance()->evalString(coder.c_str(), coder.size(), &rval);
|
|
}
|
|
} // end of extern "C"
|
|
|
|
void restartJSVM()
|
|
{
|
|
g_isStarted = false;
|
|
}
|
|
|
|
/***********************************************************
|
|
* Functions invoke from cpp to Java.
|
|
***********************************************************/
|
|
|
|
std::string getApkPathJNI()
|
|
{
|
|
return g_apkPath;
|
|
}
|
|
|
|
std::string getPackageNameJNI()
|
|
{
|
|
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getPackageName");
|
|
}
|
|
|
|
int getObbAssetFileDescriptorJNI(const std::string &path, long *startOffset, long *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());
|
|
jlongArray newArray = (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, ©);
|
|
fd = static_cast<int>(array[0]);
|
|
*startOffset = array[1];
|
|
*size = array[2];
|
|
methodInfo.env->ReleaseLongArrayElements(newArray, array, 0);
|
|
}
|
|
|
|
methodInfo.env->DeleteLocalRef(methodInfo.classID);
|
|
methodInfo.env->DeleteLocalRef(stringArg);
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
|
|
int getDeviceSampleRateJNI()
|
|
{
|
|
return g_deviceSampleRate;
|
|
}
|
|
|
|
int getDeviceAudioBufferSizeInFramesJNI()
|
|
{
|
|
return g_deviceAudioBufferSizeInFrames;
|
|
}
|
|
|
|
void convertEncodingJNI(const std::string &src, int byteSize, const std::string &fromCharset, std::string &dst, const std::string &newCharset)
|
|
{
|
|
JniMethodInfo methodInfo;
|
|
|
|
if (JniHelper::getStaticMethodInfo(methodInfo, JCLS_HELPER, "conversionEncoding", "([BLjava/lang/String;Ljava/lang/String;)[B"))
|
|
{
|
|
jbyteArray strArray = methodInfo.env->NewByteArray(byteSize);
|
|
methodInfo.env->SetByteArrayRegion(strArray, 0, byteSize, reinterpret_cast<const jbyte *>(src.c_str()));
|
|
|
|
jstring stringArg1 = methodInfo.env->NewStringUTF(fromCharset.c_str());
|
|
jstring stringArg2 = methodInfo.env->NewStringUTF(newCharset.c_str());
|
|
|
|
jbyteArray newArray = (jbyteArray)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, strArray, stringArg1, stringArg2);
|
|
jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);
|
|
methodInfo.env->GetByteArrayRegion(newArray, 0, theArrayLen, (jbyte *)dst.c_str());
|
|
|
|
methodInfo.env->DeleteLocalRef(strArray);
|
|
methodInfo.env->DeleteLocalRef(stringArg1);
|
|
methodInfo.env->DeleteLocalRef(stringArg2);
|
|
methodInfo.env->DeleteLocalRef(newArray);
|
|
methodInfo.env->DeleteLocalRef(methodInfo.classID);
|
|
}
|
|
}
|
|
|
|
std::string getCurrentLanguageJNI()
|
|
{
|
|
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getCurrentLanguage");
|
|
}
|
|
|
|
std::string getCurrentLanguageCodeJNI()
|
|
{
|
|
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getCurrentLanguageCode");
|
|
}
|
|
|
|
std::string getSystemVersionJNI()
|
|
{
|
|
return JniHelper::callStaticStringMethod(JCLS_HELPER, "getSystemVersion");
|
|
}
|
|
|
|
bool openURLJNI(const std::string &url)
|
|
{
|
|
return JniHelper::callStaticBooleanMethod(JCLS_HELPER, "openURL", url);
|
|
}
|
|
|
|
void copyTextToClipboardJNI(const std::string &text)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCLS_HELPER, "copyTextToClipboard", text);
|
|
}
|
|
|
|
void showQRCodeJNI(const std::string &funid, const std::string &content)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "showQRCode", funid, content);
|
|
}
|
|
|
|
void showWebPageJNI(const std::string &funid, const std::string &content)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "showWebPage", funid, content);
|
|
}
|
|
|
|
void scanQRCodeJNI(const std::string &funid, const std::string &title)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "scanQRCode", funid, title);
|
|
}
|
|
|
|
void signWithGoogleJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithGoogle", funid);
|
|
}
|
|
void signWithAppleJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithApple", funid);
|
|
}
|
|
void signWithTiktokJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithTiktok", funid);
|
|
}
|
|
|
|
void signOutGoogleJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signOutGoogle", funid);
|
|
}
|
|
|
|
void signWithFacebookJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithFacebook", funid);
|
|
}
|
|
|
|
void signWithTwitterJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithTwitter", funid);
|
|
}
|
|
|
|
void signWithEmailJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithEmail", funid);
|
|
}
|
|
|
|
void signWithDiscordJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "signWithDiscord", funid);
|
|
}
|
|
|
|
void callJcVoidMethodJNI(const std::string &funid, const std::string &method_name)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, method_name, funid);
|
|
}
|
|
|
|
void toWalletJNI(const std::string &url)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "toWallet", url);
|
|
}
|
|
|
|
void beginBuyJNI(const std::string &funid, const std::string &productid, const std::string &orderid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "buyProduct", funid, productid, orderid);
|
|
}
|
|
void passStorageStateJNI(const std::string &funid, const std::string &account)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "passStorageState", funid, account);
|
|
}
|
|
void storagePassJNI(const std::string &funid, const std::string &account, std::string &password)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "storagePass", funid, account, password);
|
|
}
|
|
void storageGameDataJNI(const std::string &content) {
|
|
JniHelper::callStaticVoidMethod(JCSDK, "storageGameData", content);
|
|
}
|
|
|
|
void onProxyCBJNI(const std::string &funid, const std::string &data) {
|
|
JniHelper::callStaticVoidMethod(JCSDK, "onProxyCB", funid, data);
|
|
}
|
|
|
|
void authGetStoragePassJNI(const std::string &funid, const std::string &account)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "authGetStoragePass", funid, account);
|
|
}
|
|
void getClientIdJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "getClientId", funid);
|
|
}
|
|
void queryProductsJNI(const std::string &funid, const std::string &content)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "queryProducts", funid, content);
|
|
}
|
|
|
|
void queryPurchaseJNI(const std::string &funid)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCSDK, "queryPurchase", funid);
|
|
}
|
|
|
|
void setPreferredFramesPerSecondJNI(int fps)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCLS_RENDERER, "setPreferredFramesPerSecond", fps);
|
|
}
|
|
|
|
void setGameInfoDebugViewTextJNI(int index, const std::string &text)
|
|
{
|
|
if (!_isOpenDebugView)
|
|
return;
|
|
JniHelper::callStaticVoidMethod(JCLS_HELPER, "setGameInfoDebugViewText", index, text);
|
|
}
|
|
|
|
void setJSBInvocationCountJNI(int count)
|
|
{
|
|
if (!_isOpenDebugView)
|
|
return;
|
|
JniHelper::callStaticVoidMethod(JCLS_HELPER, "setJSBInvocationCount", count);
|
|
}
|
|
|
|
void openDebugViewJNI()
|
|
{
|
|
if (!_isOpenDebugView)
|
|
{
|
|
LOGD("openDebugViewJNI ...");
|
|
_isOpenDebugView = true;
|
|
JniHelper::callStaticVoidMethod(JCLS_HELPER, "openDebugView");
|
|
if (!_isGLOptModeEnabled)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCLS_HELPER, "disableBatchGLCommandsToNative");
|
|
}
|
|
}
|
|
}
|
|
|
|
void disableBatchGLCommandsToNativeJNI()
|
|
{
|
|
_isGLOptModeEnabled = false;
|
|
if (_isOpenDebugView)
|
|
{
|
|
JniHelper::callStaticVoidMethod(JCLS_HELPER, "disableBatchGLCommandsToNative");
|
|
}
|
|
}
|
|
|
|
void exitApplication()
|
|
{
|
|
g_isGameFinished = true;
|
|
}
|
|
|
|
bool getApplicationExited()
|
|
{
|
|
return g_isGameFinished;
|
|
}
|
|
|
|
int getAndroidSDKInt()
|
|
{
|
|
return g_SDKInt;
|
|
}
|