diff options
author | peter@chromium.org <peter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 22:17:00 +0000 |
---|---|---|
committer | peter@chromium.org <peter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-14 22:17:00 +0000 |
commit | 449019cafa2e658d0765038a4d5d4e06d781e0ad (patch) | |
tree | 223be7ba714ff05e64b924f8f88963e34e6164de /base | |
parent | d0c978ce5327d7f6c6bfac5ea64cf3210769db51 (diff) | |
download | chromium_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.java | 93 | ||||
-rw-r--r-- | base/base.gyp | 2 | ||||
-rw-r--r-- | base/base.gypi | 3 | ||||
-rw-r--r-- | base/message_pump_android.cc | 51 | ||||
-rw-r--r-- | base/test/test_stub_android.cc | 24 |
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 |