JniImp.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /****************************************************************************
  2. Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
  3. http://www.cocos.com
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated engine source code (the "Software"), a limited,
  6. worldwide, royalty-free, non-assignable, revocable and non-exclusive license
  7. to use Cocos Creator solely to develop games on your target platforms. You shall
  8. not use Cocos Creator software for developing other software or tools that's
  9. used for developing games. You are not granted to publish, distribute,
  10. sublicense, and/or sell copies of Cocos Creator.
  11. The software or tools in this License Agreement are licensed, not sold.
  12. Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. ****************************************************************************/
  21. #include "JniImp.h"
  22. #include <unordered_map>
  23. #include <android/log.h>
  24. #include <android/asset_manager_jni.h>
  25. #include <jni.h>
  26. #include <mutex>
  27. #include "JniHelper.h"
  28. #include "platform/CCApplication.h"
  29. #include "scripting/js-bindings/jswrapper/SeApi.h"
  30. #include "scripting/js-bindings/event/EventDispatcher.h"
  31. #include "platform/android/CCFileUtils-android.h"
  32. #include "base/CCScheduler.h"
  33. #include "base/CCAutoreleasePool.h"
  34. #include "base/CCGLUtils.h"
  35. #define JNI_IMP_LOG_TAG "JniImp"
  36. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,JNI_IMP_LOG_TAG,__VA_ARGS__)
  37. #ifndef ORG_RENDER_CLASS_NAME
  38. #define ORG_RENDER_CLASS_NAME org_cocos2dx_lib_Cocos2dxRenderer
  39. #endif
  40. #define JNI_RENDER(FUNC) JNI_METHOD1(ORG_RENDER_CLASS_NAME,FUNC)
  41. #ifndef ORG_ACTIVITY_CLASS_NAME
  42. #define ORG_ACTIVITY_CLASS_NAME org_cocos2dx_lib_Cocos2dxActivity
  43. #endif
  44. #define JNI_ACTIVITY(FUNC) JNI_METHOD1(ORG_ACTIVITY_CLASS_NAME,FUNC)
  45. #ifndef ORG_ACCELEROMETER_CLASS_NAME
  46. #define ORG_ACCELEROMETER_CLASS_NAME org_cocos2dx_lib_Cocos2dxAccelerometer
  47. #endif
  48. #define JNI_ACCELEROMETER(FUNC) JNI_METHOD1(ORG_ACCELEROMETER_CLASS_NAME,FUNC)
  49. #ifndef ORG_HELPER_CLASS_NAME
  50. #define ORG_HELPER_CLASS_NAME org_cocos2dx_lib_Cocos2dxHelper
  51. #endif
  52. #define JNI_HELPER(FUNC) JNI_METHOD1(ORG_HELPER_CLASS_NAME,FUNC)
  53. #ifndef ORG_AUDIOFOCUS_CLASS_NAME
  54. #define ORG_AUDIOFOCUS_CLASS_NAME org_cocos2dx_lib_Cocos2dxAudioFocusManager
  55. #endif
  56. #define JNI_AUDIO(FUNC) JNI_METHOD1(ORG_AUDIOFOCUS_CLASS_NAME,FUNC)
  57. #ifndef JCLS_HELPER
  58. #define JCLS_HELPER "org/cocos2dx/lib/Cocos2dxHelper"
  59. #endif
  60. #ifndef JCLS_RENDERER
  61. #define JCLS_RENDERER "org/cocos2dx/lib/Cocos2dxRenderer"
  62. #endif
  63. #define KEYCODE_BACK 0x04
  64. #define KEYCODE_MENU 0x52
  65. #define KEYCODE_DPAD_UP 0x13
  66. #define KEYCODE_DPAD_DOWN 0x14
  67. #define KEYCODE_DPAD_LEFT 0x15
  68. #define KEYCODE_DPAD_RIGHT 0x16
  69. #define KEYCODE_ENTER 0x42
  70. #define KEYCODE_DPAD_CENTER 0x17
  71. using namespace cocos2d;
  72. extern uint32_t __jsbInvocationCount;
  73. namespace
  74. {
  75. bool __isOpenDebugView = false;
  76. bool __isGLOptModeEnabled = true;
  77. std::string g_apkPath;
  78. EditTextCallback s_editTextCallback = nullptr;
  79. void* s_ctx = nullptr;
  80. int g_deviceSampleRate = 44100;
  81. int g_deviceAudioBufferSizeInFrames = 192;
  82. int g_width = 0;
  83. int g_height = 0;
  84. bool g_isStarted = false;
  85. bool g_isGameFinished = false;
  86. int g_SDKInt = 0;
  87. cocos2d::Application* g_app = nullptr;
  88. bool setCanvasCallback(se::Object* global)
  89. {
  90. se::AutoHandleScope scope;
  91. se::ScriptEngine* se = se::ScriptEngine::getInstance();
  92. char commandBuf[200] = {0};
  93. uint8_t devicePixelRatio = Application::getInstance()->getDevicePixelRatio();
  94. sprintf(commandBuf, "window.innerWidth = %d; window.innerHeight = %d;",
  95. g_width / devicePixelRatio,
  96. g_height / devicePixelRatio);
  97. se->evalString(commandBuf);
  98. glViewport(0, 0, g_width / devicePixelRatio, g_height / devicePixelRatio);
  99. glDepthMask(GL_TRUE);
  100. return true;
  101. }
  102. }
  103. void cocos_jni_env_init (JNIEnv* env);
  104. Application* cocos_android_app_init(JNIEnv* env, int width, int height);
  105. extern "C"
  106. {
  107. void getSDKInt(JNIEnv* env)
  108. {
  109. if (env && g_SDKInt == 0)
  110. {
  111. // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
  112. jclass versionClass = env->FindClass("android/os/Build$VERSION");
  113. if (NULL == versionClass)
  114. return;
  115. jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I");
  116. if (NULL == sdkIntFieldID)
  117. return;
  118. g_SDKInt = env->GetStaticIntField(versionClass, sdkIntFieldID);
  119. }
  120. }
  121. JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
  122. {
  123. JniHelper::setJavaVM(vm);
  124. cocos_jni_env_init(JniHelper::getEnv());
  125. getSDKInt(JniHelper::getEnv());
  126. return JNI_VERSION_1_4;
  127. }
  128. /*****************************************************
  129. * Cocos2dxActivity native functions implementation.
  130. *****************************************************/
  131. JNIEXPORT jintArray JNICALL JNI_ACTIVITY(getGLContextAttrs)(JNIEnv* env, jobject thiz)
  132. {
  133. //REFINE
  134. int tmp[7] = {8, 8, 8,
  135. 8, 0, 0, 0};
  136. jintArray glContextAttrsJava = env->NewIntArray(7);
  137. env->SetIntArrayRegion(glContextAttrsJava, 0, 7, tmp);
  138. return glContextAttrsJava;
  139. }
  140. /*****************************************************
  141. * Cocos2dxRenderer native functions implementation.
  142. *****************************************************/
  143. JNIEXPORT void JNICALL JNI_RENDER(nativeInit)(JNIEnv* env, jobject thiz, jint w, jint h, jstring jDefaultResourcePath)
  144. {
  145. g_width = w;
  146. g_height = h;
  147. g_app = cocos_android_app_init(env, w, h);
  148. g_isGameFinished = false;
  149. ccInvalidateStateCache();
  150. std::string defaultResourcePath = JniHelper::jstring2string(jDefaultResourcePath);
  151. LOGD("nativeInit: %d, %d, %s", w, h, defaultResourcePath.c_str());
  152. if (!defaultResourcePath.empty())
  153. FileUtils::getInstance()->setDefaultResourceRootPath(defaultResourcePath);
  154. se::ScriptEngine* se = se::ScriptEngine::getInstance();
  155. se->addRegisterCallback(setCanvasCallback);
  156. EventDispatcher::init();
  157. g_app->start();
  158. g_isStarted = true;
  159. }
  160. JNIEXPORT void JNICALL JNI_RENDER(nativeRender)(JNIEnv* env)
  161. {
  162. if (g_isGameFinished)
  163. {
  164. // with Application destructor called, native resource will be released
  165. delete g_app;
  166. g_app = nullptr;
  167. JniHelper::callStaticVoidMethod(JCLS_HELPER, "endApplication");
  168. return;
  169. }
  170. if (!g_isStarted)
  171. {
  172. auto scheduler = Application::getInstance()->getScheduler();
  173. scheduler->removeAllFunctionsToBePerformedInCocosThread();
  174. scheduler->unscheduleAll();
  175. se::ScriptEngine::getInstance()->cleanup();
  176. cocos2d::PoolManager::getInstance()->getCurrentPool()->clear();
  177. //REFINE: Wait HttpClient, WebSocket, Audio thread to exit
  178. ccInvalidateStateCache();
  179. se::ScriptEngine* se = se::ScriptEngine::getInstance();
  180. se->addRegisterCallback(setCanvasCallback);
  181. EventDispatcher::init();
  182. if(!g_app->applicationDidFinishLaunching())
  183. {
  184. g_isGameFinished = true;
  185. return;
  186. }
  187. g_isStarted = true;
  188. }
  189. static std::chrono::steady_clock::time_point prevTime;
  190. static std::chrono::steady_clock::time_point now;
  191. static float dt = 0.f;
  192. static float dtSum = 0.f;
  193. static uint32_t jsbInvocationTotalCount = 0;
  194. static uint32_t jsbInvocationTotalFrames = 0;
  195. bool downsampleEnabled = g_app->isDownsampleEnabled();
  196. if (downsampleEnabled)
  197. g_app->getRenderTexture()->prepare();
  198. g_app->getScheduler()->update(dt);
  199. EventDispatcher::dispatchTickEvent(dt);
  200. if (downsampleEnabled)
  201. g_app->getRenderTexture()->draw();
  202. PoolManager::getInstance()->getCurrentPool()->clear();
  203. now = std::chrono::steady_clock::now();
  204. dt = std::chrono::duration_cast<std::chrono::microseconds>(now - prevTime).count() / 1000000.f;
  205. prevTime = std::chrono::steady_clock::now();
  206. if (__isOpenDebugView)
  207. {
  208. dtSum += dt;
  209. ++jsbInvocationTotalFrames;
  210. jsbInvocationTotalCount += __jsbInvocationCount;
  211. if (dtSum > 1.0f)
  212. {
  213. dtSum = 0.0f;
  214. setJSBInvocationCountJNI(jsbInvocationTotalCount / jsbInvocationTotalFrames);
  215. jsbInvocationTotalCount = 0;
  216. jsbInvocationTotalFrames = 0;
  217. }
  218. }
  219. __jsbInvocationCount = 0;
  220. }
  221. JNIEXPORT void JNICALL JNI_RENDER(nativeOnPause)()
  222. {
  223. if (g_isGameFinished) {
  224. return;
  225. }
  226. if (g_app)
  227. g_app->onPause();
  228. }
  229. JNIEXPORT void JNICALL JNI_RENDER(nativeOnResume)()
  230. {
  231. if (g_isGameFinished) {
  232. return;
  233. }
  234. if (g_app)
  235. g_app->onResume();
  236. }
  237. JNIEXPORT void JNICALL JNI_RENDER(nativeInsertText)(JNIEnv* env, jobject thiz, jstring text)
  238. {
  239. //REFINE
  240. }
  241. JNIEXPORT void JNICALL JNI_RENDER(nativeDeleteBackward)(JNIEnv* env, jobject thiz)
  242. {
  243. //REFINE
  244. }
  245. JNIEXPORT jstring JNICALL JNI_RENDER(nativeGetContentText)()
  246. {
  247. //REFINE
  248. }
  249. JNIEXPORT void JNICALL JNI_RENDER(nativeOnSurfaceChanged)(JNIEnv* env, jobject thiz, jint w, jint h)
  250. {
  251. //REFINE
  252. }
  253. /***********************************************************
  254. * Cocos2dxAccelerometer native functions implementation.
  255. ***********************************************************/
  256. JNIEXPORT void JNICALL JNI_ACCELEROMETER(onSensorChanged)(JNIEnv* env, jobject thiz, jfloat x, jfloat y, jfloat z, jlong timeStamp)
  257. {
  258. //REFINE
  259. }
  260. /***********************************************************
  261. * Touches native functions implementation.
  262. ***********************************************************/
  263. static void dispatchTouchEventWithOnePoint(JNIEnv* env, cocos2d::TouchEvent::Type type, jint id, jfloat x, jfloat y)
  264. {
  265. if (g_isGameFinished) {
  266. return;
  267. }
  268. cocos2d::TouchEvent touchEvent;
  269. touchEvent.type = type;
  270. uint8_t devicePixelRatio = Application::getInstance()->getDevicePixelRatio();
  271. cocos2d::TouchInfo touchInfo;
  272. touchInfo.index = id;
  273. touchInfo.x = x / devicePixelRatio;
  274. touchInfo.y = y / devicePixelRatio;
  275. touchEvent.touches.push_back(touchInfo);
  276. cocos2d::EventDispatcher::dispatchTouchEvent(touchEvent);
  277. }
  278. static void dispatchTouchEventWithPoints(JNIEnv* env, cocos2d::TouchEvent::Type type, jintArray ids, jfloatArray xs, jfloatArray ys)
  279. {
  280. if (g_isGameFinished) {
  281. return;
  282. }
  283. cocos2d::TouchEvent touchEvent;
  284. touchEvent.type = type;
  285. int size = env->GetArrayLength(ids);
  286. jint id[size];
  287. jfloat x[size];
  288. jfloat y[size];
  289. env->GetIntArrayRegion(ids, 0, size, id);
  290. env->GetFloatArrayRegion(xs, 0, size, x);
  291. env->GetFloatArrayRegion(ys, 0, size, y);
  292. uint8_t devicePixelRatio = Application::getInstance()->getDevicePixelRatio();
  293. for(int i = 0; i < size; i++)
  294. {
  295. cocos2d::TouchInfo touchInfo;
  296. touchInfo.index = id[i];
  297. touchInfo.x = x[i] / devicePixelRatio;
  298. touchInfo.y = y[i] / devicePixelRatio;
  299. touchEvent.touches.push_back(touchInfo);
  300. }
  301. cocos2d::EventDispatcher::dispatchTouchEvent(touchEvent);
  302. }
  303. JNIEXPORT void JNICALL JNI_RENDER(nativeTouchesBegin)(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y)
  304. {
  305. if (g_isGameFinished) {
  306. return;
  307. }
  308. dispatchTouchEventWithOnePoint(env, cocos2d::TouchEvent::Type::BEGAN, id, x, y);
  309. }
  310. JNIEXPORT void JNICALL JNI_RENDER(nativeTouchesEnd)(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y)
  311. {
  312. if (g_isGameFinished) {
  313. return;
  314. }
  315. dispatchTouchEventWithOnePoint(env, cocos2d::TouchEvent::Type::ENDED, id, x, y);
  316. }
  317. JNIEXPORT void JNICALL JNI_RENDER(nativeTouchesMove)(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys)
  318. {
  319. if (g_isGameFinished) {
  320. return;
  321. }
  322. dispatchTouchEventWithPoints(env, cocos2d::TouchEvent::Type::MOVED, ids, xs, ys);
  323. }
  324. JNIEXPORT void JNICALL JNI_RENDER(nativeTouchesCancel)(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys)
  325. {
  326. if (g_isGameFinished) {
  327. return;
  328. }
  329. dispatchTouchEventWithPoints(env, cocos2d::TouchEvent::Type::CANCELLED, ids, xs, ys);
  330. }
  331. JNIEXPORT jboolean JNICALL JNI_RENDER(nativeKeyEvent)(JNIEnv * env, jobject thiz, jint keyCode, jboolean isPressed)
  332. {
  333. if (g_isGameFinished) {
  334. return JNI_TRUE;
  335. }
  336. int keyInWeb = -1;
  337. // key values in web, refer to http://docs.cocos.com/creator/api/en/enums/KEY.html
  338. switch(keyCode)
  339. {
  340. case KEYCODE_BACK:
  341. keyInWeb = 6;
  342. break;
  343. case KEYCODE_ENTER:
  344. keyInWeb = 13;
  345. break;
  346. case KEYCODE_MENU:
  347. keyInWeb = 18;
  348. break;
  349. case KEYCODE_DPAD_UP:
  350. keyInWeb = 1003;
  351. break;
  352. case KEYCODE_DPAD_DOWN:
  353. keyInWeb = 1004;
  354. break;
  355. case KEYCODE_DPAD_LEFT:
  356. keyInWeb = 1000;
  357. break;
  358. case KEYCODE_DPAD_RIGHT:
  359. keyInWeb = 1001;
  360. break;
  361. case KEYCODE_DPAD_CENTER:
  362. keyInWeb = 1005;
  363. break;
  364. default:
  365. keyInWeb = 0; // If the key can't be identified, this value is 0
  366. }
  367. KeyboardEvent event;
  368. event.key = keyInWeb;
  369. event.action = isPressed ? KeyboardEvent::Action::PRESS : KeyboardEvent::Action::RELEASE;
  370. EventDispatcher::dispatchKeyboardEvent(event);
  371. return JNI_TRUE;
  372. }
  373. /***********************************************************
  374. * Cocos2dxHelper native functions implementation.
  375. ***********************************************************/
  376. JNIEXPORT void JNICALL JNI_HELPER(nativeSetApkPath)(JNIEnv* env, jobject thiz, jstring apkPath)
  377. {
  378. g_apkPath = JniHelper::jstring2string(apkPath);
  379. }
  380. JNIEXPORT void JNICALL JNI_HELPER(nativeSetContext)(JNIEnv* env, jobject thiz, jobject context, jobject assetManager)
  381. {
  382. JniHelper::setClassLoaderFrom(context);
  383. FileUtilsAndroid::setassetmanager(AAssetManager_fromJava(env, assetManager));
  384. }
  385. JNIEXPORT void JNICALL JNI_HELPER(nativeSetAudioDeviceInfo)(JNIEnv* env, jobject thiz, jboolean isSupportLowLatency, jint deviceSampleRate, jint deviceAudioBufferSizeInFrames)
  386. {
  387. g_deviceSampleRate = deviceSampleRate;
  388. g_deviceAudioBufferSizeInFrames = deviceAudioBufferSizeInFrames;
  389. LOGD("nativeSetAudioDeviceInfo: sampleRate: %d, bufferSizeInFrames: %d", g_deviceSampleRate, g_deviceAudioBufferSizeInFrames);
  390. }
  391. JNIEXPORT void JNICALL JNI_HELPER(nativeSetEditTextDialogResult)(JNIEnv* env, jobject obj, jbyteArray text)
  392. {
  393. jsize size = env->GetArrayLength(text);
  394. if (size > 0)
  395. {
  396. jbyte * data = (jbyte*)env->GetByteArrayElements(text, 0);
  397. char* buffer = (char*)malloc(size+1);
  398. if (buffer != nullptr)
  399. {
  400. memcpy(buffer, data, size);
  401. buffer[size] = '\0';
  402. // pass data to edittext's delegate
  403. if (s_editTextCallback)
  404. s_editTextCallback(buffer, s_ctx);
  405. free(buffer);
  406. }
  407. env->ReleaseByteArrayElements(text, data, 0);
  408. }
  409. else
  410. {
  411. if (s_editTextCallback)
  412. s_editTextCallback("", s_ctx);
  413. }
  414. }
  415. /***********************************************************
  416. * Cocos2dxAudioFocusManager native functions implementation.
  417. ***********************************************************/
  418. JNIEXPORT void JNICALL JNI_AUDIO(nativeOnAudioFocusChange)(JNIEnv* env, jobject thiz, jint focusChange)
  419. {
  420. // cocos_audioengine_focus_change(focusChange);
  421. }
  422. } // end of extern "C"
  423. void restartJSVM()
  424. {
  425. g_isStarted = false;
  426. }
  427. /***********************************************************
  428. * Functions invoke from cpp to Java.
  429. ***********************************************************/
  430. std::string getApkPathJNI()
  431. {
  432. return g_apkPath;
  433. }
  434. std::string getPackageNameJNI()
  435. {
  436. return JniHelper::callStaticStringMethod(JCLS_HELPER, "getPackageName");
  437. }
  438. int getObbAssetFileDescriptorJNI(const std::string& path, long* startOffset, long* size)
  439. {
  440. JniMethodInfo methodInfo;
  441. int fd = 0;
  442. if (JniHelper::getStaticMethodInfo(methodInfo, JCLS_HELPER, "getObbAssetFileDescriptor", "(Ljava/lang/String;)[J"))
  443. {
  444. jstring stringArg = methodInfo.env->NewStringUTF(path.c_str());
  445. jlongArray newArray = (jlongArray)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, stringArg);
  446. jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);
  447. if (3 == theArrayLen)
  448. {
  449. jboolean copy = JNI_FALSE;
  450. jlong *array = methodInfo.env->GetLongArrayElements(newArray, &copy);
  451. fd = static_cast<int>(array[0]);
  452. *startOffset = array[1];
  453. *size = array[2];
  454. methodInfo.env->ReleaseLongArrayElements(newArray, array, 0);
  455. }
  456. methodInfo.env->DeleteLocalRef(methodInfo.classID);
  457. methodInfo.env->DeleteLocalRef(stringArg);
  458. }
  459. return fd;
  460. }
  461. int getDeviceSampleRateJNI()
  462. {
  463. return g_deviceSampleRate;
  464. }
  465. int getDeviceAudioBufferSizeInFramesJNI()
  466. {
  467. return g_deviceAudioBufferSizeInFrames;
  468. }
  469. void convertEncodingJNI(const std::string& src, int byteSize, const std::string& fromCharset, std::string& dst, const std::string& newCharset)
  470. {
  471. JniMethodInfo methodInfo;
  472. if (JniHelper::getStaticMethodInfo(methodInfo, JCLS_HELPER, "conversionEncoding", "([BLjava/lang/String;Ljava/lang/String;)[B"))
  473. {
  474. jbyteArray strArray = methodInfo.env->NewByteArray(byteSize);
  475. methodInfo.env->SetByteArrayRegion(strArray, 0, byteSize, reinterpret_cast<const jbyte*>(src.c_str()));
  476. jstring stringArg1 = methodInfo.env->NewStringUTF(fromCharset.c_str());
  477. jstring stringArg2 = methodInfo.env->NewStringUTF(newCharset.c_str());
  478. jbyteArray newArray = (jbyteArray)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, strArray, stringArg1, stringArg2);
  479. jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);
  480. methodInfo.env->GetByteArrayRegion(newArray, 0, theArrayLen, (jbyte*)dst.c_str());
  481. methodInfo.env->DeleteLocalRef(strArray);
  482. methodInfo.env->DeleteLocalRef(stringArg1);
  483. methodInfo.env->DeleteLocalRef(stringArg2);
  484. methodInfo.env->DeleteLocalRef(newArray);
  485. methodInfo.env->DeleteLocalRef(methodInfo.classID);
  486. }
  487. }
  488. std::string getCurrentLanguageJNI()
  489. {
  490. return JniHelper::callStaticStringMethod(JCLS_HELPER, "getCurrentLanguage");
  491. }
  492. std::string getCurrentLanguageCodeJNI()
  493. {
  494. return JniHelper::callStaticStringMethod(JCLS_HELPER, "getCurrentLanguageCode");
  495. }
  496. std::string getSystemVersionJNI()
  497. {
  498. return JniHelper::callStaticStringMethod(JCLS_HELPER, "getSystemVersion");
  499. }
  500. bool openURLJNI(const std::string& url)
  501. {
  502. return JniHelper::callStaticBooleanMethod(JCLS_HELPER, "openURL", url);
  503. }
  504. void copyTextToClipboardJNI(const std::string& text)
  505. {
  506. JniHelper::callStaticVoidMethod(JCLS_HELPER, "copyTextToClipboard", text);
  507. }
  508. void setPreferredFramesPerSecondJNI(int fps)
  509. {
  510. JniHelper::callStaticVoidMethod(JCLS_RENDERER, "setPreferredFramesPerSecond", fps);
  511. }
  512. void setGameInfoDebugViewTextJNI(int index, const std::string& text)
  513. {
  514. if (!__isOpenDebugView)
  515. return;
  516. JniHelper::callStaticVoidMethod(JCLS_HELPER, "setGameInfoDebugViewText", index, text);
  517. }
  518. void setJSBInvocationCountJNI(int count)
  519. {
  520. if (!__isOpenDebugView)
  521. return;
  522. JniHelper::callStaticVoidMethod(JCLS_HELPER, "setJSBInvocationCount", count);
  523. }
  524. void openDebugViewJNI()
  525. {
  526. if (!__isOpenDebugView)
  527. {
  528. LOGD("openDebugViewJNI ...");
  529. __isOpenDebugView = true;
  530. JniHelper::callStaticVoidMethod(JCLS_HELPER, "openDebugView");
  531. if (!__isGLOptModeEnabled)
  532. {
  533. JniHelper::callStaticVoidMethod(JCLS_HELPER, "disableBatchGLCommandsToNative");
  534. }
  535. }
  536. }
  537. void disableBatchGLCommandsToNativeJNI()
  538. {
  539. __isGLOptModeEnabled = false;
  540. if (__isOpenDebugView)
  541. {
  542. JniHelper::callStaticVoidMethod(JCLS_HELPER, "disableBatchGLCommandsToNative");
  543. }
  544. }
  545. void exitApplication()
  546. {
  547. g_isGameFinished = true;
  548. }
  549. bool getApplicationExited()
  550. {
  551. return g_isGameFinished;
  552. }
  553. int getAndroidSDKInt()
  554. {
  555. return g_SDKInt;
  556. }