1 // Copyright 2013 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_ANDROID_JAVA_HANDLER_THREAD_H_ 6 #define BASE_ANDROID_JAVA_HANDLER_THREAD_H_ 7 8 #include <jni.h> 9 10 #include <memory> 11 12 #include "base/android/scoped_java_ref.h" 13 #include "base/dcheck_is_on.h" 14 #include "base/memory/raw_ptr.h" 15 #include "base/task/sequence_manager/sequence_manager.h" 16 #include "base/task/sequence_manager/task_queue.h" 17 #include "base/task/single_thread_task_runner.h" 18 19 namespace base { 20 21 class MessagePumpAndroid; 22 23 namespace android { 24 25 // A Java Thread with a native message loop. To run tasks, post them 26 // to the message loop and they will be scheduled along with Java tasks 27 // on the thread. 28 // This is useful for callbacks where the receiver expects a thread 29 // with a prepared Looper. 30 class BASE_EXPORT JavaHandlerThread { 31 public: 32 // Create new thread. 33 explicit JavaHandlerThread( 34 const char* name, 35 base::ThreadType thread_type = base::ThreadType::kDefault); 36 // Wrap and connect to an existing JavaHandlerThread. 37 // |obj| is an instance of JavaHandlerThread. 38 explicit JavaHandlerThread( 39 const char* name, 40 const base::android::ScopedJavaLocalRef<jobject>& obj); 41 virtual ~JavaHandlerThread(); 42 43 // Gets the TaskRunner associated with the message loop. 44 // Called from any thread. task_runner()45 scoped_refptr<SingleThreadTaskRunner> task_runner() const { 46 return state_ ? state_->default_task_queue->task_runner() : nullptr; 47 } 48 49 // Called from the parent thread. 50 void Start(); 51 void Stop(); 52 53 // Called from java on the newly created thread. 54 // Start() will not return before this methods has finished. 55 void InitializeThread(JNIEnv* env, 56 jlong event); 57 // Called from java on this thread. 58 void OnLooperStopped(JNIEnv* env); 59 60 // Called from this thread. 61 void StopSequenceManagerForTesting(); 62 // Called from this thread. 63 void JoinForTesting(); 64 65 // Called from this thread. 66 // See comment in JavaHandlerThread.java regarding use of this function. 67 void ListenForUncaughtExceptionsForTesting(); 68 // Called from this thread. 69 ScopedJavaLocalRef<jthrowable> GetUncaughtExceptionIfAny(); 70 71 // Returns the thread ID. Should not be called before the first Start*() 72 // call. This method is thread-safe. 73 PlatformThreadId GetThreadId() const; 74 75 protected: 76 // Struct exists so JavaHandlerThread destructor can intentionally leak in an 77 // abort scenario. 78 struct State { 79 State(); 80 ~State(); 81 82 std::unique_ptr<sequence_manager::SequenceManager> sequence_manager; 83 sequence_manager::TaskQueue::Handle default_task_queue; 84 raw_ptr<MessagePumpAndroid> pump = nullptr; 85 }; 86 state()87 State* state() const { return state_.get(); } 88 89 // Semantically the same as base::Thread#Init(), but unlike base::Thread the 90 // Android Looper will already be running. This Init() call will still run 91 // before other tasks are posted to the thread. Init()92 virtual void Init() {} 93 94 // Semantically the same as base::Thread#CleanUp(), called after the message 95 // loop ends. The Android Looper will also have been quit by this point. CleanUp()96 virtual void CleanUp() {} 97 98 std::unique_ptr<State> state_; 99 100 private: 101 void StartMessageLoop(); 102 103 void StopOnThread(); 104 void QuitThreadSafely(); 105 106 const char* name_; 107 base::PlatformThreadId thread_id_{}; 108 ScopedJavaGlobalRef<jobject> java_thread_; 109 #if DCHECK_IS_ON() 110 bool initialized_ = false; 111 #endif 112 }; 113 114 } // namespace android 115 } // namespace base 116 117 #endif // BASE_ANDROID_JAVA_HANDLER_THREAD_H_ 118