Encode method and error message inside LevelDB::Status message
[chromium-blink-merge.git] / base / message_pump_android.cc
blobf02da67ef7184ef470868cb3f11407bd3547ebbc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/message_pump_android.h"
7 #include <jni.h>
9 #include "base/android/jni_android.h"
10 #include "base/android/scoped_java_ref.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/run_loop.h"
14 #include "base/time.h"
15 #include "jni/SystemMessageHandler_jni.h"
17 using base::android::ScopedJavaLocalRef;
19 namespace {
21 base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >
22 g_system_message_handler_obj = LAZY_INSTANCE_INITIALIZER;
24 } // namespace
26 // ----------------------------------------------------------------------------
27 // Native JNI methods called by Java.
28 // ----------------------------------------------------------------------------
29 // This method can not move to anonymous namespace as it has been declared as
30 // 'static' in system_message_handler_jni.h.
31 static jboolean DoRunLoopOnce(JNIEnv* env, jobject obj, jint native_delegate) {
32 base::MessagePump::Delegate* delegate =
33 reinterpret_cast<base::MessagePump::Delegate*>(native_delegate);
34 DCHECK(delegate);
35 // This is based on MessagePumpForUI::DoRunLoop() from desktop.
36 // Note however that our system queue is handled in the java side.
37 // In desktop we inspect and process a single system message and then
38 // we call DoWork() / DoDelayedWork().
39 // On Android, the java message queue may contain messages for other handlers
40 // that will be processed before calling here again.
41 bool more_work_is_plausible = delegate->DoWork();
43 // This is the time when we need to do delayed work.
44 base::TimeTicks delayed_work_time;
45 more_work_is_plausible |= delegate->DoDelayedWork(&delayed_work_time);
47 // This is a major difference between android and other platforms: since we
48 // can't inspect it and process just one single message, instead we'll yeld
49 // the callstack, and post a message to call us back soon.
50 if (more_work_is_plausible)
51 return true;
53 more_work_is_plausible = delegate->DoIdleWork();
54 if (!more_work_is_plausible && !delayed_work_time.is_null()) {
55 // We only set the timer here as returning true would post a message.
56 jlong millis =
57 (delayed_work_time - base::TimeTicks::Now()).InMillisecondsRoundedUp();
58 Java_SystemMessageHandler_setDelayedTimer(env, obj, millis);
60 return more_work_is_plausible;
63 namespace base {
65 MessagePumpForUI::MessagePumpForUI()
66 : run_loop_(NULL) {
69 MessagePumpForUI::~MessagePumpForUI() {
72 void MessagePumpForUI::Run(Delegate* delegate) {
73 NOTREACHED() << "UnitTests should rely on MessagePumpForUIStub in"
74 " test_stub_android.h";
77 void MessagePumpForUI::Start(Delegate* delegate) {
78 run_loop_ = new base::RunLoop();
79 // Since the RunLoop was just created above, BeforeRun should be guaranteed to
80 // return true (it only returns false if the RunLoop has been Quit already).
81 if (!run_loop_->BeforeRun())
82 NOTREACHED();
84 DCHECK(g_system_message_handler_obj.Get().is_null());
86 JNIEnv* env = base::android::AttachCurrentThread();
87 DCHECK(env);
89 g_system_message_handler_obj.Get().Reset(
90 Java_SystemMessageHandler_create(env, reinterpret_cast<jint>(delegate)));
93 void MessagePumpForUI::Quit() {
94 if (!g_system_message_handler_obj.Get().is_null()) {
95 JNIEnv* env = base::android::AttachCurrentThread();
96 DCHECK(env);
98 Java_SystemMessageHandler_removeTimer(env,
99 g_system_message_handler_obj.Get().obj());
100 g_system_message_handler_obj.Get().Reset();
103 if (run_loop_) {
104 run_loop_->AfterRun();
105 delete run_loop_;
106 run_loop_ = NULL;
110 void MessagePumpForUI::ScheduleWork() {
111 DCHECK(!g_system_message_handler_obj.Get().is_null());
113 JNIEnv* env = base::android::AttachCurrentThread();
114 DCHECK(env);
116 Java_SystemMessageHandler_setTimer(env,
117 g_system_message_handler_obj.Get().obj());
120 void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
121 DCHECK(!g_system_message_handler_obj.Get().is_null());
123 JNIEnv* env = base::android::AttachCurrentThread();
124 DCHECK(env);
126 jlong millis =
127 (delayed_work_time - base::TimeTicks::Now()).InMillisecondsRoundedUp();
128 // Note that we're truncating to milliseconds as required by the java side,
129 // even though delayed_work_time is microseconds resolution.
130 Java_SystemMessageHandler_setDelayedTimer(env,
131 g_system_message_handler_obj.Get().obj(), millis);
134 // static
135 bool MessagePumpForUI::RegisterBindings(JNIEnv* env) {
136 return RegisterNativesImpl(env);
139 } // namespace base