summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorkristianm@chromium.org <kristianm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-08 01:31:52 +0000
committerkristianm@chromium.org <kristianm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-08 01:31:52 +0000
commit349ad5872a8ff25729e1b67ad24a09b64571c04c (patch)
treeec401c4675c4a02b546b4f849b8c2a41d50fe1c7 /base
parent29aaa27acf958c13926a5199e717aa79124fe779 (diff)
downloadchromium_src-349ad5872a8ff25729e1b67ad24a09b64571c04c.zip
chromium_src-349ad5872a8ff25729e1b67ad24a09b64571c04c.tar.gz
chromium_src-349ad5872a8ff25729e1b67ad24a09b64571c04c.tar.bz2
Making a way to create thread with a Java Looper for Android
We need to create a new message loop type for this as for testing the Android UI message pump type is not the standard Java, but gets overridden to a different one that can handle nested message loops. Using the new Java thread for the java bridge thread, so the thread used for AJI callbacks will have a prepared Looper. BUG=b/8680913 TBR=jochen@chromium.org Review URL: https://chromiumcodereview.appspot.com/18584006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216349 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/android/base_jni_registrar.cc2
-rw-r--r--base/android/java/src/org/chromium/base/JavaHandlerThread.java41
-rw-r--r--base/android/java_handler_thread.cc62
-rw-r--r--base/android/java_handler_thread.h48
-rw-r--r--base/base.gyp1
-rw-r--r--base/base.gypi2
-rw-r--r--base/message_loop/message_loop.cc6
-rw-r--r--base/message_loop/message_loop.h11
-rw-r--r--base/threading/thread_restrictions.h5
9 files changed, 176 insertions, 2 deletions
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index ea4c37b..0645c73 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -8,6 +8,7 @@
#include "base/android/build_info.h"
#include "base/android/cpu_features.h"
#include "base/android/important_file_writer_android.h"
+#include "base/android/java_handler_thread.h"
#include "base/android/jni_android.h"
#include "base/android/jni_registrar.h"
#include "base/android/memory_pressure_listener_android.h"
@@ -38,6 +39,7 @@ static RegistrationMethod kBaseRegisteredMethods[] = {
base::android::RegisterImportantFileWriterAndroid },
{ "MemoryPressureListenerAndroid",
base::android::MemoryPressureListenerAndroid::Register },
+ { "JavaHandlerThread", base::android::JavaHandlerThread::RegisterBindings },
{ "PathService", base::android::RegisterPathService },
{ "PathUtils", base::android::RegisterPathUtils },
{ "SystemMessageHandler", base::MessagePumpForUI::RegisterBindings },
diff --git a/base/android/java/src/org/chromium/base/JavaHandlerThread.java b/base/android/java/src/org/chromium/base/JavaHandlerThread.java
new file mode 100644
index 0000000..5f9960e
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/JavaHandlerThread.java
@@ -0,0 +1,41 @@
+// Copyright 2013 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.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+
+/**
+ * This class is an internal detail of the native counterpart.
+ * It is instantiated and owned by the native object.
+ */
+@JNINamespace("base::android")
+class JavaHandlerThread {
+ final HandlerThread mThread;
+
+ private JavaHandlerThread(String name) {
+ mThread = new HandlerThread(name);
+ }
+
+ @CalledByNative
+ private static JavaHandlerThread create(String name) {
+ return new JavaHandlerThread(name);
+ }
+
+ @CalledByNative
+ private void start(final int nativeThread, final int nativeEvent) {
+ mThread.start();
+ new Handler(mThread.getLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ nativeInitializeThread(nativeThread, nativeEvent);
+ }
+ });
+ }
+
+ private native void nativeInitializeThread(int nativeJavaHandlerThread, int nativeEvent);
+} \ No newline at end of file
diff --git a/base/android/java_handler_thread.cc b/base/android/java_handler_thread.cc
new file mode 100644
index 0000000..0528fe7
--- /dev/null
+++ b/base/android/java_handler_thread.cc
@@ -0,0 +1,62 @@
+// Copyright 2013 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.
+
+#include "base/android/java_handler_thread.h"
+
+#include <jni.h>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/message_loop/message_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread_restrictions.h"
+#include "jni/JavaHandlerThread_jni.h"
+
+namespace base {
+
+namespace android {
+
+JavaHandlerThread::JavaHandlerThread(const char* name) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ java_thread_.Reset(Java_JavaHandlerThread_create(
+ env, ConvertUTF8ToJavaString(env, name).Release()));
+}
+
+JavaHandlerThread::~JavaHandlerThread() {
+}
+
+void JavaHandlerThread::Start() {
+ // Check the thread has not already been started.
+ DCHECK(!message_loop_);
+
+ JNIEnv* env = base::android::AttachCurrentThread();
+ base::WaitableEvent initialize_event(false, false);
+ Java_JavaHandlerThread_start(env,
+ java_thread_.obj(),
+ reinterpret_cast<jint>(this),
+ reinterpret_cast<jint>(&initialize_event));
+ // Wait for thread to be initialized so it is ready to be used when Start
+ // returns.
+ base::ThreadRestrictions::ScopedAllowWait wait_allowed;
+ initialize_event.Wait();
+}
+
+void JavaHandlerThread::Stop() {
+}
+
+void JavaHandlerThread::InitializeThread(JNIEnv* env, jobject obj, jint event) {
+ // TYPE_JAVA to get the Android java style message loop.
+ message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_JAVA));
+ static_cast<MessageLoopForUI*>(message_loop_.get())->Start();
+ reinterpret_cast<base::WaitableEvent*>(event)->Signal();
+}
+
+// static
+bool JavaHandlerThread::RegisterBindings(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/java_handler_thread.h b/base/android/java_handler_thread.h
new file mode 100644
index 0000000..9f66d66
--- /dev/null
+++ b/base/android/java_handler_thread.h
@@ -0,0 +1,48 @@
+// Copyright 2013 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.
+
+#ifndef BASE_THREADING_JAVA_THREAD_H_
+#define BASE_THREADING_JAVA_THREAD_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+
+class MessageLoop;
+class WaitableEvent;
+
+namespace android {
+
+// A Java Thread with a native message loop. To run tasks, post them
+// to the message loop and they will be scheduled along with Java tasks
+// on the thread.
+// This is useful for callbacks where the receiver expects a thread
+// with a prepared Looper.
+class BASE_EXPORT JavaHandlerThread {
+ public:
+ JavaHandlerThread(const char* name);
+ virtual ~JavaHandlerThread();
+
+ base::MessageLoop* message_loop() const { return message_loop_.get(); }
+ void Start();
+ void Stop();
+
+ // Called from java on the newly created thread.
+ // Start() will not return before this methods has finished.
+ void InitializeThread(JNIEnv* env, jobject obj, jint event);
+
+ static bool RegisterBindings(JNIEnv* env);
+
+ private:
+ scoped_ptr<base::MessageLoop> message_loop_;
+ ScopedJavaGlobalRef<jobject> java_thread_;
+};
+
+} // namespace android
+} // namespace base
+
+#endif // BASE_THREADING_JAVA_THREAD_H_
diff --git a/base/base.gyp b/base/base.gyp
index 15776f3..4b92a91 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -1160,6 +1160,7 @@
'android/java/src/org/chromium/base/CpuFeatures.java',
'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java',
'android/java/src/org/chromium/base/MemoryPressureListener.java',
+ 'android/java/src/org/chromium/base/JavaHandlerThread.java',
'android/java/src/org/chromium/base/PathService.java',
'android/java/src/org/chromium/base/PathUtils.java',
'android/java/src/org/chromium/base/PowerMonitor.java',
diff --git a/base/base.gypi b/base/base.gypi
index fef37a1..bfe5a57 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -58,6 +58,8 @@
'android/jni_string.h',
'android/memory_pressure_listener_android.cc',
'android/memory_pressure_listener_android.h',
+ 'android/java_handler_thread.cc',
+ 'android/java_handler_thread.h',
'android/path_service_android.cc',
'android/path_service_android.h',
'android/path_utils.cc',
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index d2eafbd8..826c757 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -92,7 +92,7 @@ MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL;
// time for every task that is added to the MessageLoop incoming queue.
bool AlwaysNotifyPump(MessageLoop::Type type) {
#if defined(OS_ANDROID)
- return type == MessageLoop::TYPE_UI;
+ return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA;
#else
return false;
#endif
@@ -184,6 +184,10 @@ MessageLoop::MessageLoop(Type type)
pump_.reset(MESSAGE_PUMP_UI);
} else if (type_ == TYPE_IO) {
pump_.reset(MESSAGE_PUMP_IO);
+#if defined(OS_ANDROID)
+ } else if (type_ == TYPE_JAVA) {
+ pump_.reset(MESSAGE_PUMP_UI);
+#endif
} else {
DCHECK_EQ(TYPE_DEFAULT, type_);
pump_.reset(new MessagePumpDefault());
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index 6f71a85..f22c904 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -109,10 +109,19 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
// This type of ML also supports asynchronous IO. See also
// MessageLoopForIO.
//
+ // TYPE_JAVA
+ // This type of ML is backed by a Java message handler which is responsible
+ // for running the tasks added to the ML. This is only for use on Android.
+ // TYPE_JAVA behaves in essence like TYPE_UI, except during construction
+ // where it does not use the main thread specific pump factory.
+ //
enum Type {
TYPE_DEFAULT,
TYPE_UI,
- TYPE_IO
+ TYPE_IO,
+#if defined(OS_ANDROID)
+ TYPE_JAVA,
+#endif // defined(OS_ANDROID)
};
// Normally, it is not necessary to instantiate a MessageLoop. Instead, it
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index 6490b04..595b970 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -73,6 +73,10 @@ class AutoThread;
namespace base {
+namespace android {
+class JavaHandlerThread;
+}
+
class SequencedWorkerPool;
class SimpleThread;
class Thread;
@@ -185,6 +189,7 @@ class BASE_EXPORT ThreadRestrictions {
friend class Thread;
friend class ThreadTestHelper;
friend class PlatformThread;
+ friend class android::JavaHandlerThread;
// END ALLOWED USAGE.
// BEGIN USAGE THAT NEEDS TO BE FIXED.