// 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_ANDROID_JAVA_HANDLER_THREAD_H_ #define BASE_ANDROID_JAVA_HANDLER_THREAD_H_ #include #include #include "base/android/scoped_java_ref.h" #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" namespace base { class MessageLoop; 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: // Create new thread. explicit JavaHandlerThread( const char* name, base::ThreadPriority priority = base::ThreadPriority::NORMAL); // Wrap and connect to an existing JavaHandlerThread. // |obj| is an instance of JavaHandlerThread. explicit JavaHandlerThread( const char* name, const base::android::ScopedJavaLocalRef& obj); virtual ~JavaHandlerThread(); // Called from any thread. base::MessageLoop* message_loop() const { return message_loop_.get(); } // Gets the TaskRunner associated with the message loop. // Called from any thread. scoped_refptr task_runner() const { return message_loop_ ? message_loop_->task_runner() : nullptr; } // Called from the parent thread. 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, const JavaParamRef& obj, jlong event); // Called from java on this thread. void OnLooperStopped(JNIEnv* env, const JavaParamRef& obj); // Called from this thread. void StopMessageLoopForTesting(); // Called from this thread. void JoinForTesting(); // Called from this thread. // See comment in JavaHandlerThread.java regarding use of this function. void ListenForUncaughtExceptionsForTesting(); // Called from this thread. ScopedJavaLocalRef GetUncaughtExceptionIfAny(); protected: // Semantically the same as base::Thread#Init(), but unlike base::Thread the // Android Looper will already be running. This Init() call will still run // before other tasks are posted to the thread. virtual void Init() {} // Semantically the same as base::Thread#CleanUp(), called after the message // loop ends. The Android Looper will also have been quit by this point. virtual void CleanUp() {} std::unique_ptr message_loop_; private: void StartMessageLoop(); void StopOnThread(); void QuitThreadSafely(); const char* name_; ScopedJavaGlobalRef java_thread_; }; } // namespace android } // namespace base #endif // BASE_ANDROID_JAVA_HANDLER_THREAD_H_