1 // Copyright 2019 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.
5 #include "base/android/java_handler_thread.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "base/task/sequence_manager/sequence_manager_impl.h"
9 #include "base/task/task_observer.h"
10 #include "base/test/android/java_handler_thread_helpers.h"
11 #include "base/test/bind.h"
12 #include "testing/gtest/include/gtest/gtest.h"
17 class JavaHandlerThreadForTest : public android::JavaHandlerThread {
19 explicit JavaHandlerThreadForTest(
21 base::ThreadType thread_type = base::ThreadType::kDefault)
22 : android::JavaHandlerThread(name, thread_type) {}
24 using android::JavaHandlerThread::state;
25 using android::JavaHandlerThread::State;
28 class DummyTaskObserver : public TaskObserver {
30 explicit DummyTaskObserver(int num_tasks)
31 : num_tasks_started_(0), num_tasks_processed_(0), num_tasks_(num_tasks) {}
33 DummyTaskObserver(int num_tasks, int num_tasks_started)
34 : num_tasks_started_(num_tasks_started),
35 num_tasks_processed_(0),
36 num_tasks_(num_tasks) {}
38 DummyTaskObserver(const DummyTaskObserver&) = delete;
39 DummyTaskObserver& operator=(const DummyTaskObserver&) = delete;
41 ~DummyTaskObserver() override = default;
43 void WillProcessTask(const PendingTask& /* pending_task */,
44 bool /* was_blocked_or_low_priority */) override {
46 EXPECT_LE(num_tasks_started_, num_tasks_);
47 EXPECT_EQ(num_tasks_started_, num_tasks_processed_ + 1);
50 void DidProcessTask(const PendingTask& pending_task) override {
51 num_tasks_processed_++;
52 EXPECT_LE(num_tasks_started_, num_tasks_);
53 EXPECT_EQ(num_tasks_started_, num_tasks_processed_);
56 int num_tasks_started() const { return num_tasks_started_; }
57 int num_tasks_processed() const { return num_tasks_processed_; }
60 int num_tasks_started_;
61 int num_tasks_processed_;
65 void PostNTasks(int posts_remaining) {
66 if (posts_remaining > 1) {
67 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
68 FROM_HERE, BindOnce(&PostNTasks, posts_remaining - 1));
74 class JavaHandlerThreadTest : public ::testing::Test {};
76 void RunTest_AbortDontRunMoreTasks(bool delayed, bool init_java_first) {
77 WaitableEvent test_done_event;
78 std::unique_ptr<android::JavaHandlerThread> java_thread;
79 if (init_java_first) {
80 java_thread = android::JavaHandlerThreadHelpers::CreateJavaFirst();
82 java_thread = std::make_unique<android::JavaHandlerThread>(
83 "JavaHandlerThreadForTesting from AbortDontRunMoreTasks");
86 java_thread->ListenForUncaughtExceptionsForTesting();
89 BindOnce(&android::JavaHandlerThreadHelpers::ThrowExceptionAndAbort,
92 java_thread->task_runner()->PostDelayedTask(FROM_HERE, std::move(target),
95 java_thread->task_runner()->PostTask(FROM_HERE, std::move(target));
96 java_thread->task_runner()->PostTask(FROM_HERE,
97 MakeExpectedNotRunClosure(FROM_HERE));
99 test_done_event.Wait();
101 android::ScopedJavaLocalRef<jthrowable> exception =
102 java_thread->GetUncaughtExceptionIfAny();
104 android::JavaHandlerThreadHelpers::IsExceptionTestException(exception));
107 TEST_F(JavaHandlerThreadTest, JavaExceptionAbort) {
108 constexpr bool delayed = false;
109 constexpr bool init_java_first = false;
110 RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
113 TEST_F(JavaHandlerThreadTest, DelayedJavaExceptionAbort) {
114 constexpr bool delayed = true;
115 constexpr bool init_java_first = false;
116 RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
119 TEST_F(JavaHandlerThreadTest, JavaExceptionAbortInitJavaFirst) {
120 constexpr bool delayed = false;
121 constexpr bool init_java_first = true;
122 RunTest_AbortDontRunMoreTasks(delayed, init_java_first);
125 TEST_F(JavaHandlerThreadTest, RunTasksWhileShuttingDownJavaThread) {
126 const int kNumPosts = 6;
127 DummyTaskObserver observer(kNumPosts, 1);
129 auto java_thread = std::make_unique<JavaHandlerThreadForTest>("test");
130 java_thread->Start();
132 sequence_manager::internal::SequenceManagerImpl* sequence_manager =
133 static_cast<sequence_manager::internal::SequenceManagerImpl*>(
134 java_thread->state()->sequence_manager.get());
136 java_thread->task_runner()->PostTask(
137 FROM_HERE, BindLambdaForTesting([&]() {
138 sequence_manager->AddTaskObserver(&observer);
139 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
140 FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), Days(1));
141 java_thread->StopSequenceManagerForTesting();
142 PostNTasks(kNumPosts);
145 java_thread->JoinForTesting();
148 EXPECT_EQ(kNumPosts, observer.num_tasks_started());
149 EXPECT_EQ(kNumPosts, observer.num_tasks_processed());