Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | ||||
4 | |||||
danakj | 0a44860 | 2015-03-10 00:31:16 | [diff] [blame] | 5 | #ifndef BASE_ANDROID_JAVA_HANDLER_THREAD_H_ |
6 | #define BASE_ANDROID_JAVA_HANDLER_THREAD_H_ | ||||
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 7 | |
8 | #include <jni.h> | ||||
9 | |||||
dcheng | 093de9b | 2016-04-04 21:25:51 | [diff] [blame] | 10 | #include <memory> |
11 | |||||
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 12 | #include "base/android/scoped_java_ref.h" |
Bo Liu | 88f2be1 | 2021-02-03 19:04:34 | [diff] [blame] | 13 | #include "base/dcheck_is_on.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 14 | #include "base/memory/raw_ptr.h" |
Alex Clarke | e1cc1bb | 2019-06-06 17:24:25 | [diff] [blame] | 15 | #include "base/task/sequence_manager/sequence_manager.h" |
16 | #include "base/task/sequence_manager/task_queue.h" | ||||
Patrick Monette | 643cdf6 | 2021-10-15 19:13:42 | [diff] [blame] | 17 | #include "base/task/single_thread_task_runner.h" |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 18 | |
19 | namespace base { | ||||
20 | |||||
Egor Pasko | 6da5a07c | 2024-03-11 19:56:29 | [diff] [blame] | 21 | class MessagePumpAndroid; |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 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: | ||||
boliu | 61687ec5 | 2017-03-29 20:09:34 | [diff] [blame] | 32 | // Create new thread. |
Eric Karl | b2ce020 | 2018-06-21 18:36:29 | [diff] [blame] | 33 | explicit JavaHandlerThread( |
34 | const char* name, | ||||
Zhibo Wang | d9e4a00 | 2022-07-07 04:34:59 | [diff] [blame] | 35 | base::ThreadType thread_type = base::ThreadType::kDefault); |
boliu | 61687ec5 | 2017-03-29 20:09:34 | [diff] [blame] | 36 | // Wrap and connect to an existing JavaHandlerThread. |
37 | // |obj| is an instance of JavaHandlerThread. | ||||
38 | explicit JavaHandlerThread( | ||||
Victor Miura | 29bb4ab | 2018-08-29 19:31:52 | [diff] [blame] | 39 | const char* name, |
boliu | 61687ec5 | 2017-03-29 20:09:34 | [diff] [blame] | 40 | const base::android::ScopedJavaLocalRef<jobject>& obj); |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 41 | virtual ~JavaHandlerThread(); |
42 | |||||
Michael Thiessen | 7681cfee | 2017-08-18 16:55:37 | [diff] [blame] | 43 | // Gets the TaskRunner associated with the message loop. |
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 44 | // Called from any thread. |
Michael Thiessen | 7681cfee | 2017-08-18 16:55:37 | [diff] [blame] | 45 | scoped_refptr<SingleThreadTaskRunner> task_runner() const { |
Gabriel Charette | 35f2625 | 2019-08-12 12:01:20 | [diff] [blame] | 46 | return state_ ? state_->default_task_queue->task_runner() : nullptr; |
Michael Thiessen | 7681cfee | 2017-08-18 16:55:37 | [diff] [blame] | 47 | } |
48 | |||||
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 49 | // Called from the parent thread. |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 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. | ||||
torne | 70f3fac9 | 2015-12-02 16:31:18 | [diff] [blame] | 55 | void InitializeThread(JNIEnv* env, |
torne | 70f3fac9 | 2015-12-02 16:31:18 | [diff] [blame] | 56 | jlong event); |
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 57 | // Called from java on this thread. |
Eric Stevenson | 7aa9ce99 | 2019-07-31 14:13:22 | [diff] [blame] | 58 | void OnLooperStopped(JNIEnv* env); |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 59 | |
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 60 | // Called from this thread. |
Alex Clarke | e1cc1bb | 2019-06-06 17:24:25 | [diff] [blame] | 61 | void StopSequenceManagerForTesting(); |
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 62 | // Called from this thread. |
Michael Thiessen | 7681cfee | 2017-08-18 16:55:37 | [diff] [blame] | 63 | void JoinForTesting(); |
64 | |||||
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 65 | // Called from this thread. |
Michael Thiessen | 781ddeb | 2017-11-15 17:07:23 | [diff] [blame] | 66 | // See comment in JavaHandlerThread.java regarding use of this function. |
67 | void ListenForUncaughtExceptionsForTesting(); | ||||
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 68 | // Called from this thread. |
Michael Thiessen | 781ddeb | 2017-11-15 17:07:23 | [diff] [blame] | 69 | ScopedJavaLocalRef<jthrowable> GetUncaughtExceptionIfAny(); |
70 | |||||
Bo Liu | 88f2be1 | 2021-02-03 19:04:34 | [diff] [blame] | 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 | |||||
gsennton | ebe2e203 | 2016-08-18 22:34:12 | [diff] [blame] | 75 | protected: |
Alex Clarke | e1cc1bb | 2019-06-06 17:24:25 | [diff] [blame] | 76 | // Struct exists so JavaHandlerThread destructor can intentionally leak in an |
77 | // abort scenario. | ||||
Gabriel Charette | 35f2625 | 2019-08-12 12:01:20 | [diff] [blame] | 78 | struct State { |
79 | State(); | ||||
80 | ~State(); | ||||
Alex Clarke | e1cc1bb | 2019-06-06 17:24:25 | [diff] [blame] | 81 | |
82 | std::unique_ptr<sequence_manager::SequenceManager> sequence_manager; | ||||
Scott Haseley | a8d3cff1 | 2023-06-26 18:12:38 | [diff] [blame] | 83 | sequence_manager::TaskQueue::Handle default_task_queue; |
Egor Pasko | 6da5a07c | 2024-03-11 19:56:29 | [diff] [blame] | 84 | raw_ptr<MessagePumpAndroid> pump = nullptr; |
Alex Clarke | e1cc1bb | 2019-06-06 17:24:25 | [diff] [blame] | 85 | }; |
86 | |||||
Gabriel Charette | 35f2625 | 2019-08-12 12:01:20 | [diff] [blame] | 87 | State* state() const { return state_.get(); } |
Alex Clarke | e1cc1bb | 2019-06-06 17:24:25 | [diff] [blame] | 88 | |
Michael Thiessen | 7681cfee | 2017-08-18 16:55:37 | [diff] [blame] | 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. | ||||
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. | ||||
96 | virtual void CleanUp() {} | ||||
97 | |||||
Gabriel Charette | 35f2625 | 2019-08-12 12:01:20 | [diff] [blame] | 98 | std::unique_ptr<State> state_; |
gsennton | ebe2e203 | 2016-08-18 22:34:12 | [diff] [blame] | 99 | |
100 | private: | ||||
Michael Thiessen | d7ae735 | 2018-07-10 00:57:13 | [diff] [blame] | 101 | void StartMessageLoop(); |
102 | |||||
103 | void StopOnThread(); | ||||
104 | void QuitThreadSafely(); | ||||
105 | |||||
Victor Miura | 29bb4ab | 2018-08-29 19:31:52 | [diff] [blame] | 106 | const char* name_; |
Bo Liu | 88f2be1 | 2021-02-03 19:04:34 | [diff] [blame] | 107 | base::PlatformThreadId thread_id_{}; |
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 108 | ScopedJavaGlobalRef<jobject> java_thread_; |
Bo Liu | 88f2be1 | 2021-02-03 19:04:34 | [diff] [blame] | 109 | #if DCHECK_IS_ON() |
110 | bool initialized_ = false; | ||||
111 | #endif | ||||
[email protected] | 349ad58 | 2013-08-08 01:31:52 | [diff] [blame] | 112 | }; |
113 | |||||
114 | } // namespace android | ||||
115 | } // namespace base | ||||
116 | |||||
danakj | 0a44860 | 2015-03-10 00:31:16 | [diff] [blame] | 117 | #endif // BASE_ANDROID_JAVA_HANDLER_THREAD_H_ |