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