Browse Source

fixed keyboard hide freeze on Android

Conflicts:
	gameplay/src/PlatformAndroid.cpp
Andrew Karpushin 10 years ago
parent
commit
65bfaf0a46
1 changed files with 49 additions and 0 deletions
  1. 49 0
      gameplay/src/PlatformAndroid.cpp

+ 49 - 0
gameplay/src/PlatformAndroid.cpp

@@ -44,6 +44,7 @@ static int __orientationAngle = 90;
 static bool __multiSampling = false;
 static bool __multiTouch = false;
 static int __primaryTouchId = -1;
+static bool __keyboardIsVisible = false;
 
 // OpenGL VAO functions.
 static const char* __glExtensions;
@@ -430,6 +431,8 @@ static void displayKeyboard(android_app* state, bool show)
     
     // Finished with the JVM.
     jvm->DetachCurrentThread(); 
+
+    __keyboardIsVisible = show;
 }
 
 // Gets the Keyboard::Key enumeration constant that corresponds to the given Android key code.
@@ -757,6 +760,18 @@ static float clampFuzz(float value, float fuzz)
 // Process the next input event.
 static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
 {
+    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY
+        && AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN
+        && AKeyEvent_getKeyCode(event) == AKEYCODE_BACK
+        && __keyboardIsVisible
+        )
+    {
+        Game::getInstance()->displayKeyboard(false);
+        return 1;
+    }
+
+	Game::getInstance()->handlePlatformEvent(event);
+
     int32_t deviceId = AInputEvent_getDeviceId(event);
     int32_t source = AInputEvent_getSource(event);
 
@@ -1241,6 +1256,37 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
     }
 }
 
+// Patch andoid_native_app_glue.c process_input function since it freezes app when user tries to hide keyboard
+// See: http://stackoverflow.com/questions/15913080/crash-when-closing-soft-keyboard-while-using-native-activity
+#include <android/log.h>
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
+#define LOGV(...)  ((void)0)
+static void process_input( struct android_app* app, struct android_poll_source* source)
+{
+    AInputEvent* event = NULL;
+    if (AInputQueue_getEvent(app->inputQueue, &event) >= 0)
+    {
+        int type = AInputEvent_getType(event);
+        LOGV("New input event: type=%d\n", AInputEvent_getType(event));
+
+        bool skip_predispatch
+            =  AInputEvent_getType(event)  == AINPUT_EVENT_TYPE_KEY
+            && AKeyEvent_getKeyCode(event) == AKEYCODE_BACK;
+
+        // skip predispatch (all it does is send to the IME)
+        if (!skip_predispatch && AInputQueue_preDispatchEvent(app->inputQueue, event))
+            return;
+
+        int32_t handled = 0;
+        if (app->onInputEvent != NULL)
+            handled = app->onInputEvent(app, event);
+        AInputQueue_finishEvent(app->inputQueue, event, handled);
+    } else {
+        LOGE("Failure reading next input event: %s\n", strerror(errno));
+    }
+}
+
+
 Platform::Platform(Game* game)
     : _game(game)
 {
@@ -1312,6 +1358,9 @@ int Platform::enterMessagePump()
     __state->onAppCmd = engine_handle_cmd;
     __state->onInputEvent = engine_handle_input;
     
+    // Apply patch to native process_input function
+    __state->inputPollSource.process = process_input;
+
     // Prepare to monitor accelerometer.
     __sensorManager = ASensorManager_getInstance();
     __accelerometerSensor = ASensorManager_getDefaultSensor(__sensorManager, ASENSOR_TYPE_ACCELEROMETER);