Index: base/message_loop/message_pump_android.cc |
diff --git a/base/message_loop/message_pump_android.cc b/base/message_loop/message_pump_android.cc |
index a0eee12c85c3034e9b42ec82d259e96619b06759..cbc4413faaa742181096927f5dcc767ad2d9504d 100644 |
--- a/base/message_loop/message_pump_android.cc |
+++ b/base/message_loop/message_pump_android.cc |
@@ -14,6 +14,7 @@ |
#include "base/time/time.h" |
#include "jni/SystemMessageHandler_jni.h" |
+using base::android::HasException; |
using base::android::ScopedJavaLocalRef; |
// ---------------------------------------------------------------------------- |
@@ -24,10 +25,14 @@ using base::android::ScopedJavaLocalRef; |
static void DoRunLoopOnce(JNIEnv* env, |
const JavaParamRef<jobject>& obj, |
jlong native_delegate, |
+ jlong native_message_pump, |
jlong delayed_scheduled_time_ticks) { |
base::MessagePump::Delegate* delegate = |
reinterpret_cast<base::MessagePump::Delegate*>(native_delegate); |
DCHECK(delegate); |
+ base::MessagePumpForUI* pump = |
+ reinterpret_cast<base::MessagePumpForUI*>(native_message_pump); |
+ DCHECK(pump); |
// This is based on MessagePumpForUI::DoRunLoop() from desktop. |
// Note however that our system queue is handled in the java side. |
// In desktop we inspect and process a single system message and then |
@@ -35,6 +40,11 @@ static void DoRunLoopOnce(JNIEnv* env, |
// On Android, the java message queue may contain messages for other handlers |
// that will be processed before calling here again. |
bool did_work = delegate->DoWork(); |
+ if (pump->ShouldAbort()) { |
+ // There is a pending JNI exception, return to Java so that the exception is |
+ // thrown correctly |
+ return; |
+ } |
// In the java side, |SystemMessageHandler| keeps a single "delayed" message. |
// It's an expensive operation to |removeMessage| there, so this is optimized |
@@ -60,6 +70,11 @@ static void DoRunLoopOnce(JNIEnv* env, |
// avoid comparisons with TimeDelta / Now() (expensive). |
base::TimeTicks next_delayed_work_time; |
did_work |= delegate->DoDelayedWork(&next_delayed_work_time); |
+ if (pump->ShouldAbort()) { |
+ // There is a pending JNI exception, return to Java so that the exception is |
+ // thrown correctly |
+ return; |
+ } |
if (!next_delayed_work_time.is_null()) { |
// Schedule a new message if there's nothing already scheduled or there's a |
@@ -85,9 +100,7 @@ static void DoRunLoopOnce(JNIEnv* env, |
namespace base { |
-MessagePumpForUI::MessagePumpForUI() |
- : run_loop_(NULL) { |
-} |
+MessagePumpForUI::MessagePumpForUI() : run_loop_(NULL), should_abort_(false) {} |
danakj
2016/07/20 21:37:08
nit: nullptr while you're here?
gsennton
2016/07/26 14:42:39
Done.
|
MessagePumpForUI::~MessagePumpForUI() { |
} |
@@ -109,9 +122,9 @@ void MessagePumpForUI::Start(Delegate* delegate) { |
JNIEnv* env = base::android::AttachCurrentThread(); |
DCHECK(env); |
- system_message_handler_obj_.Reset( |
- Java_SystemMessageHandler_create( |
- env, reinterpret_cast<intptr_t>(delegate))); |
+ system_message_handler_obj_.Reset(Java_SystemMessageHandler_create( |
+ env, reinterpret_cast<intptr_t>(delegate), |
+ reinterpret_cast<intptr_t>(this))); |
} |
void MessagePumpForUI::Quit() { |
@@ -119,6 +132,7 @@ void MessagePumpForUI::Quit() { |
JNIEnv* env = base::android::AttachCurrentThread(); |
DCHECK(env); |
+ // We can't call back into java if there is a pending jni exception |
danakj
2016/07/20 21:37:09
I'm not sure what this comment means to explain, c
Torne
2016/07/21 13:38:25
We need to avoid calling any Java functions (like
gsennton
2016/07/26 14:42:39
Removed this comment since it doesn't really make
|
Java_SystemMessageHandler_removeAllPendingMessages(env, |
system_message_handler_obj_.obj()); |
system_message_handler_obj_.Reset(); |