GoogleGit

blob: 95be3f27b625a381a3a7818a0bdbadf3af4ac998 [file] [log] [blame]
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "NativeActivity"
  17. #include <utils/Log.h>
  18. #include <poll.h>
  19. #include <dlfcn.h>
  20. #include <fcntl.h>
  21. #include <android_runtime/android_app_NativeActivity.h>
  22. #include <android_runtime/android_util_AssetManager.h>
  23. #include <android_runtime/android_view_Surface.h>
  24. #include <android_runtime/AndroidRuntime.h>
  25. #include <input/InputTransport.h>
  26. #include <gui/Surface.h>
  27. #include <system/window.h>
  28. #include <utils/Looper.h>
  29. #include "JNIHelp.h"
  30. #include "android_os_MessageQueue.h"
  31. #include "android_view_InputChannel.h"
  32. #include "android_view_KeyEvent.h"
  33. #include "nativebridge/native_bridge.h"
  34. #include "core_jni_helpers.h"
  35. #define LOG_TRACE(...)
  36. //#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  37. namespace android
  38. {
  39. static const bool kLogTrace = false;
  40. static struct {
  41. jmethodID finish;
  42. jmethodID setWindowFlags;
  43. jmethodID setWindowFormat;
  44. jmethodID showIme;
  45. jmethodID hideIme;
  46. } gNativeActivityClassInfo;
  47. // ------------------------------------------------------------------------
  48. struct ActivityWork {
  49. int32_t cmd;
  50. int32_t arg1;
  51. int32_t arg2;
  52. };
  53. enum {
  54. CMD_FINISH = 1,
  55. CMD_SET_WINDOW_FORMAT,
  56. CMD_SET_WINDOW_FLAGS,
  57. CMD_SHOW_SOFT_INPUT,
  58. CMD_HIDE_SOFT_INPUT,
  59. };
  60. static void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
  61. ActivityWork work;
  62. work.cmd = cmd;
  63. work.arg1 = arg1;
  64. work.arg2 = arg2;
  65. if (kLogTrace) {
  66. ALOGD("write_work: cmd=%d", cmd);
  67. }
  68. restart:
  69. int res = write(fd, &work, sizeof(work));
  70. if (res < 0 && errno == EINTR) {
  71. goto restart;
  72. }
  73. if (res == sizeof(work)) return;
  74. if (res < 0) ALOGW("Failed writing to work fd: %s", strerror(errno));
  75. else ALOGW("Truncated writing to work fd: %d", res);
  76. }
  77. static bool read_work(int fd, ActivityWork* outWork) {
  78. int res = read(fd, outWork, sizeof(ActivityWork));
  79. // no need to worry about EINTR, poll loop will just come back again.
  80. if (res == sizeof(ActivityWork)) return true;
  81. if (res < 0) ALOGW("Failed reading work fd: %s", strerror(errno));
  82. else ALOGW("Truncated reading work fd: %d", res);
  83. return false;
  84. }
  85. /*
  86. * Native state for interacting with the NativeActivity class.
  87. */
  88. struct NativeCode : public ANativeActivity {
  89. NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
  90. memset((ANativeActivity*)this, 0, sizeof(ANativeActivity));
  91. memset(&callbacks, 0, sizeof(callbacks));
  92. dlhandle = _dlhandle;
  93. createActivityFunc = _createFunc;
  94. nativeWindow = NULL;
  95. mainWorkRead = mainWorkWrite = -1;
  96. }
  97. ~NativeCode() {
  98. if (callbacks.onDestroy != NULL) {
  99. callbacks.onDestroy(this);
  100. }
  101. if (env != NULL && clazz != NULL) {
  102. env->DeleteGlobalRef(clazz);
  103. }
  104. if (messageQueue != NULL && mainWorkRead >= 0) {
  105. messageQueue->getLooper()->removeFd(mainWorkRead);
  106. }
  107. setSurface(NULL);
  108. if (mainWorkRead >= 0) close(mainWorkRead);
  109. if (mainWorkWrite >= 0) close(mainWorkWrite);
  110. if (dlhandle != NULL) {
  111. // for now don't unload... we probably should clean this
  112. // up and only keep one open dlhandle per proc, since there
  113. // is really no benefit to unloading the code.
  114. //dlclose(dlhandle);
  115. }
  116. }
  117. void setSurface(jobject _surface) {
  118. if (_surface != NULL) {
  119. nativeWindow = android_view_Surface_getNativeWindow(env, _surface);
  120. } else {
  121. nativeWindow = NULL;
  122. }
  123. }
  124. ANativeActivityCallbacks callbacks;
  125. void* dlhandle;
  126. ANativeActivity_createFunc* createActivityFunc;
  127. String8 internalDataPathObj;
  128. String8 externalDataPathObj;
  129. String8 obbPathObj;
  130. sp<ANativeWindow> nativeWindow;
  131. int32_t lastWindowWidth;
  132. int32_t lastWindowHeight;
  133. // These are used to wake up the main thread to process work.
  134. int mainWorkRead;
  135. int mainWorkWrite;
  136. sp<MessageQueue> messageQueue;
  137. };
  138. void android_NativeActivity_finish(ANativeActivity* activity) {
  139. NativeCode* code = static_cast<NativeCode*>(activity);
  140. write_work(code->mainWorkWrite, CMD_FINISH, 0);
  141. }
  142. void android_NativeActivity_setWindowFormat(
  143. ANativeActivity* activity, int32_t format) {
  144. NativeCode* code = static_cast<NativeCode*>(activity);
  145. write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
  146. }
  147. void android_NativeActivity_setWindowFlags(
  148. ANativeActivity* activity, int32_t values, int32_t mask) {
  149. NativeCode* code = static_cast<NativeCode*>(activity);
  150. write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
  151. }
  152. void android_NativeActivity_showSoftInput(
  153. ANativeActivity* activity, int32_t flags) {
  154. NativeCode* code = static_cast<NativeCode*>(activity);
  155. write_work(code->mainWorkWrite, CMD_SHOW_SOFT_INPUT, flags);
  156. }
  157. void android_NativeActivity_hideSoftInput(
  158. ANativeActivity* activity, int32_t flags) {
  159. NativeCode* code = static_cast<NativeCode*>(activity);
  160. write_work(code->mainWorkWrite, CMD_HIDE_SOFT_INPUT, flags);
  161. }
  162. // ------------------------------------------------------------------------
  163. /*
  164. * Callback for handling native events on the application's main thread.
  165. */
  166. static int mainWorkCallback(int fd, int events, void* data) {
  167. NativeCode* code = (NativeCode*)data;
  168. if ((events & POLLIN) == 0) {
  169. return 1;
  170. }
  171. ActivityWork work;
  172. if (!read_work(code->mainWorkRead, &work)) {
  173. return 1;
  174. }
  175. if (kLogTrace) {
  176. ALOGD("mainWorkCallback: cmd=%d", work.cmd);
  177. }
  178. switch (work.cmd) {
  179. case CMD_FINISH: {
  180. code->env->CallVoidMethod(code->clazz, gNativeActivityClassInfo.finish);
  181. code->messageQueue->raiseAndClearException(code->env, "finish");
  182. } break;
  183. case CMD_SET_WINDOW_FORMAT: {
  184. code->env->CallVoidMethod(code->clazz,
  185. gNativeActivityClassInfo.setWindowFormat, work.arg1);
  186. code->messageQueue->raiseAndClearException(code->env, "setWindowFormat");
  187. } break;
  188. case CMD_SET_WINDOW_FLAGS: {
  189. code->env->CallVoidMethod(code->clazz,
  190. gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
  191. code->messageQueue->raiseAndClearException(code->env, "setWindowFlags");
  192. } break;
  193. case CMD_SHOW_SOFT_INPUT: {
  194. code->env->CallVoidMethod(code->clazz,
  195. gNativeActivityClassInfo.showIme, work.arg1);
  196. code->messageQueue->raiseAndClearException(code->env, "showIme");
  197. } break;
  198. case CMD_HIDE_SOFT_INPUT: {
  199. code->env->CallVoidMethod(code->clazz,
  200. gNativeActivityClassInfo.hideIme, work.arg1);
  201. code->messageQueue->raiseAndClearException(code->env, "hideIme");
  202. } break;
  203. default:
  204. ALOGW("Unknown work command: %d", work.cmd);
  205. break;
  206. }
  207. return 1;
  208. }
  209. // ------------------------------------------------------------------------
  210. static jlong
  211. loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
  212. jobject messageQueue, jstring internalDataDir, jstring obbDir,
  213. jstring externalDataDir, jint sdkVersion,
  214. jobject jAssetMgr, jbyteArray savedState)
  215. {
  216. if (kLogTrace) {
  217. ALOGD("loadNativeCode_native");
  218. }
  219. const char* pathStr = env->GetStringUTFChars(path, NULL);
  220. NativeCode* code = NULL;
  221. bool needNativeBridge = false;
  222. void* handle = dlopen(pathStr, RTLD_LAZY);
  223. if (handle == NULL) {
  224. if (NativeBridgeIsSupported(pathStr)) {
  225. handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY);
  226. needNativeBridge = true;
  227. }
  228. }
  229. env->ReleaseStringUTFChars(path, pathStr);
  230. if (handle != NULL) {
  231. void* funcPtr = NULL;
  232. const char* funcStr = env->GetStringUTFChars(funcName, NULL);
  233. if (needNativeBridge) {
  234. funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0);
  235. } else {
  236. funcPtr = dlsym(handle, funcStr);
  237. }
  238. code = new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr);
  239. env->ReleaseStringUTFChars(funcName, funcStr);
  240. if (code->createActivityFunc == NULL) {
  241. ALOGW("ANativeActivity_onCreate not found");
  242. delete code;
  243. return 0;
  244. }
  245. code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
  246. if (code->messageQueue == NULL) {
  247. ALOGW("Unable to retrieve native MessageQueue");
  248. delete code;
  249. return 0;
  250. }
  251. int msgpipe[2];
  252. if (pipe(msgpipe)) {
  253. ALOGW("could not create pipe: %s", strerror(errno));
  254. delete code;
  255. return 0;
  256. }
  257. code->mainWorkRead = msgpipe[0];
  258. code->mainWorkWrite = msgpipe[1];
  259. int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
  260. SLOGW_IF(result != 0, "Could not make main work read pipe "
  261. "non-blocking: %s", strerror(errno));
  262. result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
  263. SLOGW_IF(result != 0, "Could not make main work write pipe "
  264. "non-blocking: %s", strerror(errno));
  265. code->messageQueue->getLooper()->addFd(
  266. code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
  267. code->ANativeActivity::callbacks = &code->callbacks;
  268. if (env->GetJavaVM(&code->vm) < 0) {
  269. ALOGW("NativeActivity GetJavaVM failed");
  270. delete code;
  271. return 0;
  272. }
  273. code->env = env;
  274. code->clazz = env->NewGlobalRef(clazz);
  275. const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
  276. code->internalDataPathObj = dirStr;
  277. code->internalDataPath = code->internalDataPathObj.string();
  278. env->ReleaseStringUTFChars(internalDataDir, dirStr);
  279. if (externalDataDir != NULL) {
  280. dirStr = env->GetStringUTFChars(externalDataDir, NULL);
  281. code->externalDataPathObj = dirStr;
  282. env->ReleaseStringUTFChars(externalDataDir, dirStr);
  283. }
  284. code->externalDataPath = code->externalDataPathObj.string();
  285. code->sdkVersion = sdkVersion;
  286. code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
  287. if (obbDir != NULL) {
  288. dirStr = env->GetStringUTFChars(obbDir, NULL);
  289. code->obbPathObj = dirStr;
  290. env->ReleaseStringUTFChars(obbDir, dirStr);
  291. }
  292. code->obbPath = code->obbPathObj.string();
  293. jbyte* rawSavedState = NULL;
  294. jsize rawSavedSize = 0;
  295. if (savedState != NULL) {
  296. rawSavedState = env->GetByteArrayElements(savedState, NULL);
  297. rawSavedSize = env->GetArrayLength(savedState);
  298. }
  299. code->createActivityFunc(code, rawSavedState, rawSavedSize);
  300. if (rawSavedState != NULL) {
  301. env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
  302. }
  303. }
  304. return (jlong)code;
  305. }
  306. static void
  307. unloadNativeCode_native(JNIEnv* env, jobject clazz, jlong handle)
  308. {
  309. if (kLogTrace) {
  310. ALOGD("unloadNativeCode_native");
  311. }
  312. if (handle != 0) {
  313. NativeCode* code = (NativeCode*)handle;
  314. delete code;
  315. }
  316. }
  317. static void
  318. onStart_native(JNIEnv* env, jobject clazz, jlong handle)
  319. {
  320. if (kLogTrace) {
  321. ALOGD("onStart_native");
  322. }
  323. if (handle != 0) {
  324. NativeCode* code = (NativeCode*)handle;
  325. if (code->callbacks.onStart != NULL) {
  326. code->callbacks.onStart(code);
  327. }
  328. }
  329. }
  330. static void
  331. onResume_native(JNIEnv* env, jobject clazz, jlong handle)
  332. {
  333. if (kLogTrace) {
  334. ALOGD("onResume_native");
  335. }
  336. if (handle != 0) {
  337. NativeCode* code = (NativeCode*)handle;
  338. if (code->callbacks.onResume != NULL) {
  339. code->callbacks.onResume(code);
  340. }
  341. }
  342. }
  343. static jbyteArray
  344. onSaveInstanceState_native(JNIEnv* env, jobject clazz, jlong handle)
  345. {
  346. if (kLogTrace) {
  347. ALOGD("onSaveInstanceState_native");
  348. }
  349. jbyteArray array = NULL;
  350. if (handle != 0) {
  351. NativeCode* code = (NativeCode*)handle;
  352. if (code->callbacks.onSaveInstanceState != NULL) {
  353. size_t len = 0;
  354. jbyte* state = (jbyte*)code->callbacks.onSaveInstanceState(code, &len);
  355. if (len > 0) {
  356. array = env->NewByteArray(len);
  357. if (array != NULL) {
  358. env->SetByteArrayRegion(array, 0, len, state);
  359. }
  360. }
  361. if (state != NULL) {
  362. free(state);
  363. }
  364. }
  365. }
  366. return array;
  367. }
  368. static void
  369. onPause_native(JNIEnv* env, jobject clazz, jlong handle)
  370. {
  371. if (kLogTrace) {
  372. ALOGD("onPause_native");
  373. }
  374. if (handle != 0) {
  375. NativeCode* code = (NativeCode*)handle;
  376. if (code->callbacks.onPause != NULL) {
  377. code->callbacks.onPause(code);
  378. }
  379. }
  380. }
  381. static void
  382. onStop_native(JNIEnv* env, jobject clazz, jlong handle)
  383. {
  384. if (kLogTrace) {
  385. ALOGD("onStop_native");
  386. }
  387. if (handle != 0) {
  388. NativeCode* code = (NativeCode*)handle;
  389. if (code->callbacks.onStop != NULL) {
  390. code->callbacks.onStop(code);
  391. }
  392. }
  393. }
  394. static void
  395. onConfigurationChanged_native(JNIEnv* env, jobject clazz, jlong handle)
  396. {
  397. if (kLogTrace) {
  398. ALOGD("onConfigurationChanged_native");
  399. }
  400. if (handle != 0) {
  401. NativeCode* code = (NativeCode*)handle;
  402. if (code->callbacks.onConfigurationChanged != NULL) {
  403. code->callbacks.onConfigurationChanged(code);
  404. }
  405. }
  406. }
  407. static void
  408. onLowMemory_native(JNIEnv* env, jobject clazz, jlong handle)
  409. {
  410. if (kLogTrace) {
  411. ALOGD("onLowMemory_native");
  412. }
  413. if (handle != 0) {
  414. NativeCode* code = (NativeCode*)handle;
  415. if (code->callbacks.onLowMemory != NULL) {
  416. code->callbacks.onLowMemory(code);
  417. }
  418. }
  419. }
  420. static void
  421. onWindowFocusChanged_native(JNIEnv* env, jobject clazz, jlong handle, jboolean focused)
  422. {
  423. if (kLogTrace) {
  424. ALOGD("onWindowFocusChanged_native");
  425. }
  426. if (handle != 0) {
  427. NativeCode* code = (NativeCode*)handle;
  428. if (code->callbacks.onWindowFocusChanged != NULL) {
  429. code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
  430. }
  431. }
  432. }
  433. static void
  434. onSurfaceCreated_native(JNIEnv* env, jobject clazz, jlong handle, jobject surface)
  435. {
  436. if (kLogTrace) {
  437. ALOGD("onSurfaceCreated_native");
  438. }
  439. if (handle != 0) {
  440. NativeCode* code = (NativeCode*)handle;
  441. code->setSurface(surface);
  442. if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
  443. code->callbacks.onNativeWindowCreated(code,
  444. code->nativeWindow.get());
  445. }
  446. }
  447. }
  448. static int32_t getWindowProp(ANativeWindow* window, int what) {
  449. int value;
  450. int res = window->query(window, what, &value);
  451. return res < 0 ? res : value;
  452. }
  453. static void
  454. onSurfaceChanged_native(JNIEnv* env, jobject clazz, jlong handle, jobject surface,
  455. jint format, jint width, jint height)
  456. {
  457. if (kLogTrace) {
  458. ALOGD("onSurfaceChanged_native");
  459. }
  460. if (handle != 0) {
  461. NativeCode* code = (NativeCode*)handle;
  462. sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
  463. code->setSurface(surface);
  464. if (oldNativeWindow != code->nativeWindow) {
  465. if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
  466. code->callbacks.onNativeWindowDestroyed(code,
  467. oldNativeWindow.get());
  468. }
  469. if (code->nativeWindow != NULL) {
  470. if (code->callbacks.onNativeWindowCreated != NULL) {
  471. code->callbacks.onNativeWindowCreated(code,
  472. code->nativeWindow.get());
  473. }
  474. code->lastWindowWidth = getWindowProp(code->nativeWindow.get(),
  475. NATIVE_WINDOW_WIDTH);
  476. code->lastWindowHeight = getWindowProp(code->nativeWindow.get(),
  477. NATIVE_WINDOW_HEIGHT);
  478. }
  479. } else {
  480. // Maybe it resized?
  481. int32_t newWidth = getWindowProp(code->nativeWindow.get(),
  482. NATIVE_WINDOW_WIDTH);
  483. int32_t newHeight = getWindowProp(code->nativeWindow.get(),
  484. NATIVE_WINDOW_HEIGHT);
  485. if (newWidth != code->lastWindowWidth
  486. || newHeight != code->lastWindowHeight) {
  487. if (code->callbacks.onNativeWindowResized != NULL) {
  488. code->callbacks.onNativeWindowResized(code,
  489. code->nativeWindow.get());
  490. }
  491. }
  492. }
  493. }
  494. }
  495. static void
  496. onSurfaceRedrawNeeded_native(JNIEnv* env, jobject clazz, jlong handle)
  497. {
  498. if (kLogTrace) {
  499. ALOGD("onSurfaceRedrawNeeded_native");
  500. }
  501. if (handle != 0) {
  502. NativeCode* code = (NativeCode*)handle;
  503. if (code->nativeWindow != NULL && code->callbacks.onNativeWindowRedrawNeeded != NULL) {
  504. code->callbacks.onNativeWindowRedrawNeeded(code, code->nativeWindow.get());
  505. }
  506. }
  507. }
  508. static void
  509. onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jlong handle, jobject surface)
  510. {
  511. if (kLogTrace) {
  512. ALOGD("onSurfaceDestroyed_native");
  513. }
  514. if (handle != 0) {
  515. NativeCode* code = (NativeCode*)handle;
  516. if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
  517. code->callbacks.onNativeWindowDestroyed(code,
  518. code->nativeWindow.get());
  519. }
  520. code->setSurface(NULL);
  521. }
  522. }
  523. static void
  524. onInputQueueCreated_native(JNIEnv* env, jobject clazz, jlong handle, jlong queuePtr)
  525. {
  526. if (kLogTrace) {
  527. ALOGD("onInputChannelCreated_native");
  528. }
  529. if (handle != 0) {
  530. NativeCode* code = (NativeCode*)handle;
  531. if (code->callbacks.onInputQueueCreated != NULL) {
  532. AInputQueue* queue = reinterpret_cast<AInputQueue*>(queuePtr);
  533. code->callbacks.onInputQueueCreated(code, queue);
  534. }
  535. }
  536. }
  537. static void
  538. onInputQueueDestroyed_native(JNIEnv* env, jobject clazz, jlong handle, jlong queuePtr)
  539. {
  540. if (kLogTrace) {
  541. ALOGD("onInputChannelDestroyed_native");
  542. }
  543. if (handle != 0) {
  544. NativeCode* code = (NativeCode*)handle;
  545. if (code->callbacks.onInputQueueDestroyed != NULL) {
  546. AInputQueue* queue = reinterpret_cast<AInputQueue*>(queuePtr);
  547. code->callbacks.onInputQueueDestroyed(code, queue);
  548. }
  549. }
  550. }
  551. static void
  552. onContentRectChanged_native(JNIEnv* env, jobject clazz, jlong handle,
  553. jint x, jint y, jint w, jint h)
  554. {
  555. if (kLogTrace) {
  556. ALOGD("onContentRectChanged_native");
  557. }
  558. if (handle != 0) {
  559. NativeCode* code = (NativeCode*)handle;
  560. if (code->callbacks.onContentRectChanged != NULL) {
  561. ARect rect;
  562. rect.left = x;
  563. rect.top = y;
  564. rect.right = x+w;
  565. rect.bottom = y+h;
  566. code->callbacks.onContentRectChanged(code, &rect);
  567. }
  568. }
  569. }
  570. static const JNINativeMethod g_methods[] = {
  571. { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)J",
  572. (void*)loadNativeCode_native },
  573. { "unloadNativeCode", "(J)V", (void*)unloadNativeCode_native },
  574. { "onStartNative", "(J)V", (void*)onStart_native },
  575. { "onResumeNative", "(J)V", (void*)onResume_native },
  576. { "onSaveInstanceStateNative", "(J)[B", (void*)onSaveInstanceState_native },
  577. { "onPauseNative", "(J)V", (void*)onPause_native },
  578. { "onStopNative", "(J)V", (void*)onStop_native },
  579. { "onConfigurationChangedNative", "(J)V", (void*)onConfigurationChanged_native },
  580. { "onLowMemoryNative", "(J)V", (void*)onLowMemory_native },
  581. { "onWindowFocusChangedNative", "(JZ)V", (void*)onWindowFocusChanged_native },
  582. { "onSurfaceCreatedNative", "(JLandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
  583. { "onSurfaceChangedNative", "(JLandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
  584. { "onSurfaceRedrawNeededNative", "(JLandroid/view/Surface;)V", (void*)onSurfaceRedrawNeeded_native },
  585. { "onSurfaceDestroyedNative", "(J)V", (void*)onSurfaceDestroyed_native },
  586. { "onInputQueueCreatedNative", "(JJ)V",
  587. (void*)onInputQueueCreated_native },
  588. { "onInputQueueDestroyedNative", "(JJ)V",
  589. (void*)onInputQueueDestroyed_native },
  590. { "onContentRectChangedNative", "(JIIII)V", (void*)onContentRectChanged_native },
  591. };
  592. static const char* const kNativeActivityPathName = "android/app/NativeActivity";
  593. int register_android_app_NativeActivity(JNIEnv* env)
  594. {
  595. //ALOGD("register_android_app_NativeActivity");
  596. jclass clazz = FindClassOrDie(env, kNativeActivityPathName);
  597. gNativeActivityClassInfo.finish = GetMethodIDOrDie(env, clazz, "finish", "()V");
  598. gNativeActivityClassInfo.setWindowFlags = GetMethodIDOrDie(env, clazz, "setWindowFlags",
  599. "(II)V");
  600. gNativeActivityClassInfo.setWindowFormat = GetMethodIDOrDie(env, clazz, "setWindowFormat",
  601. "(I)V");
  602. gNativeActivityClassInfo.showIme = GetMethodIDOrDie(env, clazz, "showIme", "(I)V");
  603. gNativeActivityClassInfo.hideIme = GetMethodIDOrDie(env, clazz, "hideIme", "(I)V");
  604. return RegisterMethodsOrDie(env, kNativeActivityPathName, g_methods, NELEM(g_methods));
  605. }
  606. } // namespace android