Chromium Code Reviews| 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..38791fc0c775cb6fab7c02b68c15fc023989756d 100644 |
| --- a/base/message_loop/message_pump_android.cc |
| +++ b/base/message_loop/message_pump_android.cc |
| @@ -24,10 +24,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 +39,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 +69,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 |
| @@ -81,13 +95,26 @@ 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. |
| +} |
| + |
| +// This should only be called during tests |
| +static void NotifyTestDone(JNIEnv* env, |
| + const JavaParamRef<jclass>& jcaller, |
| + jlong native_message_pump) { |
| + base::MessagePumpForUI* pump = |
| + reinterpret_cast<base::MessagePumpForUI*>(native_message_pump); |
| + DCHECK(pump); |
| + pump->NotifyTestDone(); |
| } |
| namespace base { |
| MessagePumpForUI::MessagePumpForUI() |
| - : run_loop_(NULL) { |
| -} |
| + : run_loop_(nullptr), should_abort_(false) {} |
| MessagePumpForUI::~MessagePumpForUI() { |
| } |
| @@ -109,9 +136,15 @@ 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::StartForTesting(Delegate* delegate, |
| + WaitableEvent* test_event) { |
| + test_event_ = test_event; |
| + Start(delegate); |
|
nyquist
2016/08/15 19:06:14
Could this instantiate a subclass of SystemMessage
gsennton
2016/08/16 15:27:36
Done.
|
| } |
| void MessagePumpForUI::Quit() { |
| @@ -156,6 +189,11 @@ void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { |
| delayed_work_time.ToInternalValue(), millis); |
| } |
| +void MessagePumpForUI::NotifyTestDone() { |
| + DCHECK(test_event_); |
| + test_event_->Signal(); |
| +} |
| + |
| // static |
| bool MessagePumpForUI::RegisterBindings(JNIEnv* env) { |
| return RegisterNativesImpl(env); |