Flutter Engine
engine_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/shell/common/engine.h"
6 
7 #include <cstring>
8 
9 #include "flutter/runtime/dart_vm_lifecycle.h"
10 #include "flutter/shell/common/thread_host.h"
11 #include "flutter/testing/testing.h"
12 #include "gmock/gmock.h"
13 #include "rapidjson/document.h"
14 #include "rapidjson/stringbuffer.h"
15 #include "rapidjson/writer.h"
16 
17 ///\note Deprecated MOCK_METHOD macros used until this issue is resolved:
18 // https://github.com/google/googletest/issues/2490
19 
20 namespace flutter {
21 
22 namespace {
23 class MockDelegate : public Engine::Delegate {
24  MOCK_METHOD2(OnEngineUpdateSemantics,
26  MOCK_METHOD1(OnEngineHandlePlatformMessage,
28  MOCK_METHOD0(OnPreEngineRestart, void());
29  MOCK_METHOD0(OnRootIsolateCreated, void());
30  MOCK_METHOD2(UpdateIsolateDescription, void(const std::string, int64_t));
31  MOCK_METHOD1(SetNeedsReportTimings, void(bool));
32  MOCK_METHOD1(ComputePlatformResolvedLocale,
33  std::unique_ptr<std::vector<std::string>>(
34  const std::vector<std::string>&));
35 };
36 
37 class MockResponse : public PlatformMessageResponse {
38  public:
39  MOCK_METHOD1(Complete, void(std::unique_ptr<fml::Mapping> data));
40  MOCK_METHOD0(CompleteEmpty, void());
41 };
42 
43 class MockRuntimeDelegate : public RuntimeDelegate {
44  public:
45  MOCK_METHOD0(DefaultRouteName, std::string());
46  MOCK_METHOD1(ScheduleFrame, void(bool));
47  MOCK_METHOD1(Render, void(std::unique_ptr<flutter::LayerTree>));
48  MOCK_METHOD2(UpdateSemantics,
50  MOCK_METHOD1(HandlePlatformMessage, void(fml::RefPtr<PlatformMessage>));
51  MOCK_METHOD0(GetFontCollection, FontCollection&());
52  MOCK_METHOD0(OnRootIsolateCreated, void());
53  MOCK_METHOD2(UpdateIsolateDescription, void(const std::string, int64_t));
54  MOCK_METHOD1(SetNeedsReportTimings, void(bool));
55  MOCK_METHOD1(ComputePlatformResolvedLocale,
56  std::unique_ptr<std::vector<std::string>>(
57  const std::vector<std::string>&));
58 };
59 
60 class MockRuntimeController : public RuntimeController {
61  public:
62  MockRuntimeController(RuntimeDelegate& client, TaskRunners p_task_runners)
63  : RuntimeController(client, p_task_runners) {}
64  MOCK_METHOD0(IsRootIsolateRunning, bool());
66 };
67 
68 fml::RefPtr<PlatformMessage> MakePlatformMessage(
69  const std::string& channel,
70  const std::map<std::string, std::string>& values,
72  rapidjson::Document document;
73  auto& allocator = document.GetAllocator();
74  document.SetObject();
75 
76  for (const auto& pair : values) {
77  rapidjson::Value key(pair.first.c_str(), strlen(pair.first.c_str()),
78  allocator);
79  rapidjson::Value value(pair.second.c_str(), strlen(pair.second.c_str()),
80  allocator);
81  document.AddMember(key, value, allocator);
82  }
83 
84  rapidjson::StringBuffer buffer;
85  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
86  document.Accept(writer);
87  const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.GetString());
88 
89  fml::RefPtr<PlatformMessage> message = fml::MakeRefCounted<PlatformMessage>(
90  channel, std::vector<uint8_t>(data, data + buffer.GetSize()), response);
91  return message;
92 }
93 
94 class EngineTest : public ::testing::Test {
95  public:
96  EngineTest()
97  : thread_host_("EngineTest",
98  ThreadHost::Type::Platform | ThreadHost::Type::IO |
99  ThreadHost::Type::UI | ThreadHost::Type::GPU),
100  task_runners_({
101  "EngineTest",
102  thread_host_.platform_thread->GetTaskRunner(), // platform
103  thread_host_.raster_thread->GetTaskRunner(), // raster
104  thread_host_.ui_thread->GetTaskRunner(), // ui
105  thread_host_.io_thread->GetTaskRunner() // io
106  }) {}
107 
108  void PostUITaskSync(const std::function<void()>& function) {
110  task_runners_.GetUITaskRunner()->PostTask([&] {
111  function();
112  latch.Signal();
113  });
114  latch.Wait();
115  }
116 
117  protected:
118  void SetUp() override {
119  dispatcher_maker_ = [](PointerDataDispatcher::Delegate&) {
120  return nullptr;
121  };
122  }
123 
124  MockDelegate delegate_;
126  ThreadHost thread_host_;
127  TaskRunners task_runners_;
128  Settings settings_;
129  std::unique_ptr<Animator> animator_;
131  std::unique_ptr<RuntimeController> runtime_controller_;
132  std::shared_ptr<fml::ConcurrentTaskRunner> image_decoder_task_runner_;
133 };
134 } // namespace
135 
136 TEST_F(EngineTest, Create) {
137  PostUITaskSync([this] {
138  auto engine = std::make_unique<Engine>(
139  /*delegate=*/delegate_,
140  /*dispatcher_maker=*/dispatcher_maker_,
141  /*image_decoder_task_runner=*/image_decoder_task_runner_,
142  /*task_runners=*/task_runners_,
143  /*settings=*/settings_,
144  /*animator=*/std::move(animator_),
145  /*io_manager=*/io_manager_,
146  /*runtime_controller=*/std::move(runtime_controller_));
147  EXPECT_TRUE(engine);
148  });
149 }
150 
151 TEST_F(EngineTest, DispatchPlatformMessageUnknown) {
152  PostUITaskSync([this] {
153  MockRuntimeDelegate client;
154  auto mock_runtime_controller =
155  std::make_unique<MockRuntimeController>(client, task_runners_);
156  EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
157  .WillRepeatedly(::testing::Return(false));
158  auto engine = std::make_unique<Engine>(
159  /*delegate=*/delegate_,
160  /*dispatcher_maker=*/dispatcher_maker_,
161  /*image_decoder_task_runner=*/image_decoder_task_runner_,
162  /*task_runners=*/task_runners_,
163  /*settings=*/settings_,
164  /*animator=*/std::move(animator_),
165  /*io_manager=*/io_manager_,
166  /*runtime_controller=*/std::move(mock_runtime_controller));
167 
169  fml::MakeRefCounted<MockResponse>();
171  fml::MakeRefCounted<PlatformMessage>("foo", response);
172  engine->DispatchPlatformMessage(message);
173  });
174 }
175 
176 TEST_F(EngineTest, DispatchPlatformMessageInitialRoute) {
177  PostUITaskSync([this] {
178  MockRuntimeDelegate client;
179  auto mock_runtime_controller =
180  std::make_unique<MockRuntimeController>(client, task_runners_);
181  EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
182  .WillRepeatedly(::testing::Return(false));
183  auto engine = std::make_unique<Engine>(
184  /*delegate=*/delegate_,
185  /*dispatcher_maker=*/dispatcher_maker_,
186  /*image_decoder_task_runner=*/image_decoder_task_runner_,
187  /*task_runners=*/task_runners_,
188  /*settings=*/settings_,
189  /*animator=*/std::move(animator_),
190  /*io_manager=*/io_manager_,
191  /*runtime_controller=*/std::move(mock_runtime_controller));
192 
194  fml::MakeRefCounted<MockResponse>();
195  std::map<std::string, std::string> values{
196  {"method", "setInitialRoute"},
197  {"args", "test_initial_route"},
198  };
200  MakePlatformMessage("flutter/navigation", values, response);
201  engine->DispatchPlatformMessage(message);
202  EXPECT_EQ(engine->InitialRoute(), "test_initial_route");
203  });
204 }
205 
206 TEST_F(EngineTest, DispatchPlatformMessageInitialRouteIgnored) {
207  PostUITaskSync([this] {
208  MockRuntimeDelegate client;
209  auto mock_runtime_controller =
210  std::make_unique<MockRuntimeController>(client, task_runners_);
211  EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
212  .WillRepeatedly(::testing::Return(true));
213  EXPECT_CALL(*mock_runtime_controller, DispatchPlatformMessage(::testing::_))
214  .WillRepeatedly(::testing::Return(true));
215  auto engine = std::make_unique<Engine>(
216  /*delegate=*/delegate_,
217  /*dispatcher_maker=*/dispatcher_maker_,
218  /*image_decoder_task_runner=*/image_decoder_task_runner_,
219  /*task_runners=*/task_runners_,
220  /*settings=*/settings_,
221  /*animator=*/std::move(animator_),
222  /*io_manager=*/io_manager_,
223  /*runtime_controller=*/std::move(mock_runtime_controller));
224 
226  fml::MakeRefCounted<MockResponse>();
227  std::map<std::string, std::string> values{
228  {"method", "setInitialRoute"},
229  {"args", "test_initial_route"},
230  };
232  MakePlatformMessage("flutter/navigation", values, response);
233  engine->DispatchPlatformMessage(message);
234  EXPECT_EQ(engine->InitialRoute(), "");
235  });
236 }
237 
238 } // namespace flutter
Settings settings_
PointerDataDispatcherMaker dispatcher_maker_
ThreadHost thread_host_
Dart_NativeFunction function
Definition: fuchsia.cc:51
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
std::unique_ptr< Animator > animator_
std::unique_ptr< RuntimeController > runtime_controller_
TaskRunners task_runners_
MockDelegate delegate_
std::shared_ptr< fml::ConcurrentTaskRunner > image_decoder_task_runner_
uint8_t value
TEST_F(EngineTest, Create)
Dart_Handle ComputePlatformResolvedLocale(Dart_Handle supportedLocalesHandle)
static void DispatchPlatformMessage(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jobject message, jint position, jint responseId)
fml::WeakPtr< IOManager > io_manager_
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates