summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorpeter@chromium.org <peter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-14 22:17:00 +0000
committerpeter@chromium.org <peter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-14 22:17:00 +0000
commit449019cafa2e658d0765038a4d5d4e06d781e0ad (patch)
tree223be7ba714ff05e64b924f8f88963e34e6164de /base
parentd0c978ce5327d7f6c6bfac5ea64cf3210769db51 (diff)
downloadchromium_src-449019cafa2e658d0765038a4d5d4e06d781e0ad.zip
chromium_src-449019cafa2e658d0765038a4d5d4e06d781e0ad.tar.gz
chromium_src-449019cafa2e658d0765038a4d5d4e06d781e0ad.tar.bz2
Build Android's MessagePumpForUI by upstreaming SystemMessageHandler
BUG= TEST=The "DumpRenderTree" target on the FYI bot should link. Review URL: http://codereview.chromium.org/9706022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126769 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/android/java/org/chromium/base/SystemMessageHandler.java93
-rw-r--r--base/base.gyp2
-rw-r--r--base/base.gypi3
-rw-r--r--base/message_pump_android.cc51
-rw-r--r--base/test/test_stub_android.cc24
5 files changed, 114 insertions, 59 deletions
diff --git a/base/android/java/org/chromium/base/SystemMessageHandler.java b/base/android/java/org/chromium/base/SystemMessageHandler.java
new file mode 100644
index 0000000..f7bb19f
--- /dev/null
+++ b/base/android/java/org/chromium/base/SystemMessageHandler.java
@@ -0,0 +1,93 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base;
+
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+class SystemMessageHandler extends Handler {
+
+ private static final int TIMER_MESSAGE = 1;
+ private static final int DELAYED_TIMER_MESSAGE = 2;
+
+ // Native class pointer set by the constructor of the SharedClient native class.
+ private int mMessagePumpDelegateNative = 0;
+
+ // Used to ensure we have at most one TIMER_MESSAGE pending at once.
+ private AtomicBoolean mTimerFired = new AtomicBoolean(true);
+
+ // Used to insert TIMER_MESSAGE on the front of the system message queue during startup only.
+ // This is a wee hack, to give a priority boost to native tasks during startup as they tend to
+ // be on the critical path. (After startup, handling the UI with minimum latency is more
+ // important).
+ private boolean mStartupComplete = false;
+ private final long mStartupCompleteTime = System.currentTimeMillis() + 2000;
+ private final boolean startupComplete() {
+ if (!mStartupComplete && System.currentTimeMillis() > mStartupCompleteTime) {
+ mStartupComplete = true;
+ }
+ return mStartupComplete;
+ }
+
+ private SystemMessageHandler(int messagePumpDelegateNative) {
+ mMessagePumpDelegateNative = messagePumpDelegateNative;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == TIMER_MESSAGE) {
+ mTimerFired.set(true);
+ }
+ while (nativeDoRunLoopOnce(mMessagePumpDelegateNative)) {
+ if (startupComplete()) {
+ setTimer();
+ break;
+ }
+ }
+ }
+
+ @CalledByNative
+ private void setTimer() {
+ if (!mTimerFired.getAndSet(false)) {
+ // mTimerFired was already false.
+ return;
+ }
+ if (startupComplete()) {
+ sendEmptyMessage(TIMER_MESSAGE);
+ } else {
+ sendMessageAtFrontOfQueue(obtainMessage(TIMER_MESSAGE));
+ }
+ }
+
+ // If millis <=0, it'll send a TIMER_MESSAGE instead of
+ // a DELAYED_TIMER_MESSAGE.
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private void setDelayedTimer(long millis) {
+ if (millis <= 0) {
+ setTimer();
+ } else {
+ removeMessages(DELAYED_TIMER_MESSAGE);
+ sendEmptyMessageDelayed(DELAYED_TIMER_MESSAGE, millis);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private void removeTimer() {
+ removeMessages(TIMER_MESSAGE);
+ removeMessages(DELAYED_TIMER_MESSAGE);
+ }
+
+ @CalledByNative
+ private static SystemMessageHandler create(int messagePumpDelegateNative) {
+ return new SystemMessageHandler(messagePumpDelegateNative);
+ }
+
+ private native boolean nativeDoRunLoopOnce(int messagePumpDelegateNative);
+}
diff --git a/base/base.gyp b/base/base.gyp
index e3ccc34..e7d8624 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -123,9 +123,11 @@
'inputs': [
'android/jni_generator/jni_generator.py',
'android/java/org/chromium/base/PathUtils.java',
+ 'android/java/org/chromium/base/SystemMessageHandler.java',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/base/jni/path_utils_jni.h',
+ '<(SHARED_INTERMEDIATE_DIR)/base/jni/system_message_handler_jni.h',
],
'action': [
'python',
diff --git a/base/base.gypi b/base/base.gypi
index 399b9e8..c4df5b7 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -484,9 +484,6 @@
['include', '^sys_info_linux\\.cc$'],
['include', '^sys_string_conversions_posix\\.cc$'],
['include', '^worker_pool_linux\\.cc$'],
- # TODO(michaelbai): The below files are excluded because of the
- # missing JNI, add them back when JNI is ready.
- ['exclude', '^message_pump_android\\.cc$'],
],
}],
[ 'OS != "mac"', {
diff --git a/base/message_pump_android.cc b/base/message_pump_android.cc
index 7136eff..2daf98d 100644
--- a/base/message_pump_android.cc
+++ b/base/message_pump_android.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,16 +7,17 @@
#include <jni.h>
#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "jni/system_message_handler_jni.h"
-using base::android::ScopedJavaReference;
+using base::android::ScopedJavaLocalRef;
namespace {
-const char* kClassPathName = "com/android/chromeview/base/SystemMessageHandler";
-
-jobject g_system_message_handler_obj = NULL;
+base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >
+ g_system_message_handler_obj = LAZY_INSTANCE_INITIALIZER;
} // namespace
@@ -53,7 +54,6 @@ static jboolean DoRunLoopOnce(JNIEnv* env, jobject obj, jint native_delegate) {
jlong millis =
(delayed_work_time - base::TimeTicks::Now()).InMillisecondsRoundedUp();
Java_SystemMessageHandler_setDelayedTimer(env, obj, millis);
- base::android::CheckException(env);
}
return more_work_is_plausible;
}
@@ -75,34 +75,23 @@ void MessagePumpForUI::Run(Delegate* delegate) {
void MessagePumpForUI::Start(Delegate* delegate) {
state_ = new MessageLoop::AutoRunState(MessageLoop::current());
- DCHECK(!g_system_message_handler_obj);
+ DCHECK(g_system_message_handler_obj.Get().is_null());
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
- jclass clazz = env->FindClass(kClassPathName);
- DCHECK(clazz);
-
- jmethodID constructor = base::android::GetMethodID(env, clazz, "<init>",
- "(I)V");
- ScopedJavaReference<jobject> client(env, env->NewObject(clazz, constructor,
- delegate));
- DCHECK(client.obj());
-
- g_system_message_handler_obj = env->NewGlobalRef(client.obj());
-
- base::android::CheckException(env);
+ g_system_message_handler_obj.Get().Reset(
+ Java_SystemMessageHandler_create(env, reinterpret_cast<jint>(delegate)));
}
void MessagePumpForUI::Quit() {
- if (g_system_message_handler_obj) {
+ if (!g_system_message_handler_obj.Get().is_null()) {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
- Java_SystemMessageHandler_removeTimer(env, g_system_message_handler_obj);
- env->DeleteGlobalRef(g_system_message_handler_obj);
- base::android::CheckException(env);
- g_system_message_handler_obj = NULL;
+ Java_SystemMessageHandler_removeTimer(env,
+ g_system_message_handler_obj.Get().obj());
+ g_system_message_handler_obj.Get().Reset();
}
if (state_) {
@@ -112,19 +101,18 @@ void MessagePumpForUI::Quit() {
}
void MessagePumpForUI::ScheduleWork() {
- if (!g_system_message_handler_obj)
+ if (g_system_message_handler_obj.Get().is_null())
return;
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
- Java_SystemMessageHandler_setTimer(env, g_system_message_handler_obj);
- base::android::CheckException(env);
-
+ Java_SystemMessageHandler_setTimer(env,
+ g_system_message_handler_obj.Get().obj());
}
void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
- if (!g_system_message_handler_obj)
+ if (g_system_message_handler_obj.Get().is_null())
return;
JNIEnv* env = base::android::AttachCurrentThread();
@@ -134,9 +122,8 @@ void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
(delayed_work_time - base::TimeTicks::Now()).InMillisecondsRoundedUp();
// Note that we're truncating to milliseconds as required by the java side,
// even though delayed_work_time is microseconds resolution.
- Java_SystemMessageHandler_setDelayedTimer(env, g_system_message_handler_obj,
- millis);
- base::android::CheckException(env);
+ Java_SystemMessageHandler_setDelayedTimer(env,
+ g_system_message_handler_obj.Get().obj(), millis);
}
// Register native methods
diff --git a/base/test/test_stub_android.cc b/base/test/test_stub_android.cc
index c806e22..be45e42 100644
--- a/base/test/test_stub_android.cc
+++ b/base/test/test_stub_android.cc
@@ -178,27 +178,3 @@ void InitAndroidTestStub() {
MessageLoop::InitMessagePumpForUIFactory(&CreateMessagePumpForUIStub);
}
-
-namespace base {
-
-// TODO(michaelbai): The below MessagePumpForUI were added because we excluded
-// message_pump_android.{h|cc} which require JNI to compile. Remove them when
-// those 2 files added.
-MessagePumpForUI::MessagePumpForUI()
- : state_(NULL) {
-}
-
-MessagePumpForUI::~MessagePumpForUI() {}
-
-void MessagePumpForUI::Run(Delegate* delegate) {}
-
-void MessagePumpForUI::Start(Delegate* delegate) {}
-
-void MessagePumpForUI::Quit() {}
-
-void MessagePumpForUI::ScheduleWork() {}
-
-void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
-}
-
-} // namespace base