blob: 197db23fb96f1da33ad678ff849b1ebdac3a2839 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]349ad582013-08-08 01:31:522// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakj0a448602015-03-10 00:31:165#ifndef BASE_ANDROID_JAVA_HANDLER_THREAD_H_
6#define BASE_ANDROID_JAVA_HANDLER_THREAD_H_
[email protected]349ad582013-08-08 01:31:527
8#include <jni.h>
9
dcheng093de9b2016-04-04 21:25:5110#include <memory>
11
[email protected]349ad582013-08-08 01:31:5212#include "base/android/scoped_java_ref.h"
Bo Liu88f2be12021-02-03 19:04:3413#include "base/dcheck_is_on.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
Alex Clarkee1cc1bb2019-06-06 17:24:2515#include "base/task/sequence_manager/sequence_manager.h"
16#include "base/task/sequence_manager/task_queue.h"
Patrick Monette643cdf62021-10-15 19:13:4217#include "base/task/single_thread_task_runner.h"
[email protected]349ad582013-08-08 01:31:5218
19namespace base {
20
Egor Pasko6da5a07c2024-03-11 19:56:2921class MessagePumpAndroid;
[email protected]349ad582013-08-08 01:31:5222
23namespace 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.
30class BASE_EXPORT JavaHandlerThread {
31 public:
boliu61687ec52017-03-29 20:09:3432 // Create new thread.
Eric Karlb2ce0202018-06-21 18:36:2933 explicit JavaHandlerThread(
34 const char* name,
Zhibo Wangd9e4a002022-07-07 04:34:5935 base::ThreadType thread_type = base::ThreadType::kDefault);
boliu61687ec52017-03-29 20:09:3436 // Wrap and connect to an existing JavaHandlerThread.
37 // |obj| is an instance of JavaHandlerThread.
38 explicit JavaHandlerThread(
Victor Miura29bb4ab2018-08-29 19:31:5239 const char* name,
boliu61687ec52017-03-29 20:09:3440 const base::android::ScopedJavaLocalRef<jobject>& obj);
[email protected]349ad582013-08-08 01:31:5241 virtual ~JavaHandlerThread();
42
Michael Thiessen7681cfee2017-08-18 16:55:3743 // Gets the TaskRunner associated with the message loop.
Michael Thiessend7ae7352018-07-10 00:57:1344 // Called from any thread.
Michael Thiessen7681cfee2017-08-18 16:55:3745 scoped_refptr<SingleThreadTaskRunner> task_runner() const {
Gabriel Charette35f26252019-08-12 12:01:2046 return state_ ? state_->default_task_queue->task_runner() : nullptr;
Michael Thiessen7681cfee2017-08-18 16:55:3747 }
48
Michael Thiessend7ae7352018-07-10 00:57:1349 // Called from the parent thread.
[email protected]349ad582013-08-08 01:31:5250 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.
torne70f3fac92015-12-02 16:31:1855 void InitializeThread(JNIEnv* env,
torne70f3fac92015-12-02 16:31:1856 jlong event);
Michael Thiessend7ae7352018-07-10 00:57:1357 // Called from java on this thread.
Eric Stevenson7aa9ce992019-07-31 14:13:2258 void OnLooperStopped(JNIEnv* env);
[email protected]349ad582013-08-08 01:31:5259
Michael Thiessend7ae7352018-07-10 00:57:1360 // Called from this thread.
Alex Clarkee1cc1bb2019-06-06 17:24:2561 void StopSequenceManagerForTesting();
Michael Thiessend7ae7352018-07-10 00:57:1362 // Called from this thread.
Michael Thiessen7681cfee2017-08-18 16:55:3763 void JoinForTesting();
64
Michael Thiessend7ae7352018-07-10 00:57:1365 // Called from this thread.
Michael Thiessen781ddeb2017-11-15 17:07:2366 // See comment in JavaHandlerThread.java regarding use of this function.
67 void ListenForUncaughtExceptionsForTesting();
Michael Thiessend7ae7352018-07-10 00:57:1368 // Called from this thread.
Michael Thiessen781ddeb2017-11-15 17:07:2369 ScopedJavaLocalRef<jthrowable> GetUncaughtExceptionIfAny();
70
Bo Liu88f2be12021-02-03 19:04:3471 // Returns the thread ID. Should not be called before the first Start*()
72 // call. This method is thread-safe.
73 PlatformThreadId GetThreadId() const;
74
gsenntonebe2e2032016-08-18 22:34:1275 protected:
Alex Clarkee1cc1bb2019-06-06 17:24:2576 // Struct exists so JavaHandlerThread destructor can intentionally leak in an
77 // abort scenario.
Gabriel Charette35f26252019-08-12 12:01:2078 struct State {
79 State();
80 ~State();
Alex Clarkee1cc1bb2019-06-06 17:24:2581
82 std::unique_ptr<sequence_manager::SequenceManager> sequence_manager;
Scott Haseleya8d3cff12023-06-26 18:12:3883 sequence_manager::TaskQueue::Handle default_task_queue;
Egor Pasko6da5a07c2024-03-11 19:56:2984 raw_ptr<MessagePumpAndroid> pump = nullptr;
Alex Clarkee1cc1bb2019-06-06 17:24:2585 };
86
Gabriel Charette35f26252019-08-12 12:01:2087 State* state() const { return state_.get(); }
Alex Clarkee1cc1bb2019-06-06 17:24:2588
Michael Thiessen7681cfee2017-08-18 16:55:3789 // 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 Charette35f26252019-08-12 12:01:2098 std::unique_ptr<State> state_;
gsenntonebe2e2032016-08-18 22:34:1299
100 private:
Michael Thiessend7ae7352018-07-10 00:57:13101 void StartMessageLoop();
102
103 void StopOnThread();
104 void QuitThreadSafely();
105
Victor Miura29bb4ab2018-08-29 19:31:52106 const char* name_;
Bo Liu88f2be12021-02-03 19:04:34107 base::PlatformThreadId thread_id_{};
[email protected]349ad582013-08-08 01:31:52108 ScopedJavaGlobalRef<jobject> java_thread_;
Bo Liu88f2be12021-02-03 19:04:34109#if DCHECK_IS_ON()
110 bool initialized_ = false;
111#endif
[email protected]349ad582013-08-08 01:31:52112};
113
114} // namespace android
115} // namespace base
116
danakj0a448602015-03-10 00:31:16117#endif // BASE_ANDROID_JAVA_HANDLER_THREAD_H_