| 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 7189dc2f3d2d92d84d5c37c793f914f8ea9c7ada..bedb205e075e98e0669648606552551dff54f139 100644
|
| --- a/base/message_loop/message_pump_android.cc
|
| +++ b/base/message_loop/message_pump_android.cc
|
| @@ -6,10 +6,12 @@
|
|
|
| #include <jni.h>
|
|
|
| +#include "base/android/java_message_handler_factory.h"
|
| #include "base/android/jni_android.h"
|
| #include "base/android/scoped_java_ref.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| +#include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "base/time/time.h"
|
| #include "jni/SystemMessageHandler_jni.h"
|
| @@ -25,10 +27,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
|
| @@ -36,6 +42,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
|
| @@ -61,6 +72,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
|
| @@ -82,13 +98,16 @@ static void DoRunLoopOnce(JNIEnv* env,
|
| return;
|
|
|
| delegate->DoIdleWork();
|
| + // Note that we do not check whether we should abort here since we are
|
| + // returning to the JVM anyway. If, in the future, we add any more code after
|
| + // the call to DoIdleWork() here, we should add an abort-check and return
|
| + // immediately if the check passes.
|
| }
|
|
|
| namespace base {
|
|
|
| MessagePumpForUI::MessagePumpForUI()
|
| - : run_loop_(NULL) {
|
| -}
|
| + : run_loop_(nullptr), should_abort_(false) {}
|
|
|
| MessagePumpForUI::~MessagePumpForUI() {
|
| }
|
| @@ -98,7 +117,7 @@ void MessagePumpForUI::Run(Delegate* delegate) {
|
| " test_stub_android.h";
|
| }
|
|
|
| -void MessagePumpForUI::Start(Delegate* delegate) {
|
| +JNIEnv* MessagePumpForUI::StartInternal() {
|
| run_loop_ = new RunLoop();
|
| // Since the RunLoop was just created above, BeforeRun should be guaranteed to
|
| // return true (it only returns false if the RunLoop has been Quit already).
|
| @@ -109,10 +128,23 @@ void MessagePumpForUI::Start(Delegate* delegate) {
|
|
|
| JNIEnv* env = base::android::AttachCurrentThread();
|
| DCHECK(env);
|
| + return env;
|
| +}
|
| +
|
| +void MessagePumpForUI::Start(Delegate* delegate) {
|
| + JNIEnv* env = StartInternal();
|
| + system_message_handler_obj_.Reset(Java_SystemMessageHandler_create(
|
| + env, reinterpret_cast<intptr_t>(delegate),
|
| + reinterpret_cast<intptr_t>(this)));
|
| +}
|
|
|
| +void MessagePumpForUI::StartForUnitTest(
|
| + Delegate* delegate,
|
| + base::android::JavaMessageHandlerFactory* factory,
|
| + WaitableEvent* test_done_event) {
|
| + JNIEnv* env = StartInternal();
|
| system_message_handler_obj_.Reset(
|
| - Java_SystemMessageHandler_create(
|
| - env, reinterpret_cast<intptr_t>(delegate)));
|
| + factory->CreateMessageHandler(env, delegate, this, test_done_event));
|
| }
|
|
|
| void MessagePumpForUI::Quit() {
|
|
|