This source file includes following definitions.
- Run
- Start
- Quit
- ScheduleWork
- ScheduleDelayedWork
- RegisterJni
#include "content/public/test/nested_message_pump_android.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/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "jni/NestedSystemMessageHandler_jni.h"
namespace {
base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >
g_message_handler_obj = LAZY_INSTANCE_INITIALIZER;
}
namespace content {
struct NestedMessagePumpAndroid::RunState {
RunState(base::MessagePump::Delegate* delegate, int run_depth)
: delegate(delegate),
run_depth(run_depth),
should_quit(false),
waitable_event(false, false) {
}
base::MessagePump::Delegate* delegate;
int run_depth;
bool should_quit;
base::WaitableEvent waitable_event;
base::TimeTicks delayed_work_time;
};
NestedMessagePumpAndroid::NestedMessagePumpAndroid()
: state_(NULL) {
}
NestedMessagePumpAndroid::~NestedMessagePumpAndroid() {
}
void NestedMessagePumpAndroid::Run(Delegate* delegate) {
RunState state(delegate, state_ ? state_->run_depth + 1 : 1);
RunState* previous_state = state_;
state_ = &state;
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
base::TimeDelta max_delay = base::TimeDelta::FromMilliseconds(100);
for (;;) {
if (state_->should_quit)
break;
bool did_work = state_->delegate->DoWork();
if (state_->should_quit)
break;
did_work |= state_->delegate->DoDelayedWork(&state_->delayed_work_time);
if (state_->should_quit)
break;
if (did_work) {
continue;
}
did_work = state_->delegate->DoIdleWork();
if (state_->should_quit)
break;
if (did_work)
continue;
bool ret = Java_NestedSystemMessageHandler_runNestedLoopTillIdle(env,
g_message_handler_obj.Get().obj());
CHECK(ret) << "Error running java message loop, tests will likely fail.";
base::ThreadRestrictions::ScopedAllowWait allow_wait;
if (state_->delayed_work_time.is_null()) {
state_->waitable_event.TimedWait(max_delay);
} else {
base::TimeDelta delay =
state_->delayed_work_time - base::TimeTicks::Now();
if (delay > max_delay)
delay = max_delay;
if (delay > base::TimeDelta()) {
state_->waitable_event.TimedWait(delay);
} else {
state_->delayed_work_time = base::TimeTicks();
}
}
}
state_ = previous_state;
}
void NestedMessagePumpAndroid::Start(
base::MessagePump::Delegate* delegate) {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
g_message_handler_obj.Get().Reset(
Java_NestedSystemMessageHandler_create(env));
base::MessagePumpForUI::Start(delegate);
}
void NestedMessagePumpAndroid::Quit() {
if (state_) {
state_->should_quit = true;
state_->waitable_event.Signal();
return;
}
base::MessagePumpForUI::Quit();
}
void NestedMessagePumpAndroid::ScheduleWork() {
if (state_) {
state_->waitable_event.Signal();
return;
}
base::MessagePumpForUI::ScheduleWork();
}
void NestedMessagePumpAndroid::ScheduleDelayedWork(
const base::TimeTicks& delayed_work_time) {
if (state_) {
state_->delayed_work_time = delayed_work_time;
return;
}
base::MessagePumpForUI::ScheduleDelayedWork(delayed_work_time);
}
bool NestedMessagePumpAndroid::RegisterJni(JNIEnv* env) {
return RegisterNativesImpl(env);
}
}