Flutter Engine
ui_dart_state.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/lib/ui/ui_dart_state.h"
6 
7 #include <iostream>
8 
9 #include "flutter/fml/message_loop.h"
10 #include "flutter/lib/ui/window/platform_configuration.h"
13 
14 #if defined(OS_ANDROID)
15 #include <android/log.h>
16 #elif defined(OS_IOS)
17 extern "C" {
18 // Cannot import the syslog.h header directly because of macro collision.
19 extern void syslog(int, const char*, ...);
20 }
21 #endif
22 
23 using tonic::ToDart;
24 
25 namespace flutter {
26 
28  : task_runners(task_runners) {}
29 
37  std::string advisory_script_uri,
38  std::string advisory_script_entrypoint,
39  std::shared_ptr<VolatilePathTracker> volatile_path_tracker)
40  : task_runners(task_runners),
41  snapshot_delegate(snapshot_delegate),
42  io_manager(io_manager),
43  unref_queue(unref_queue),
44  image_decoder(image_decoder),
45  image_generator_registry(image_generator_registry),
46  advisory_script_uri(advisory_script_uri),
47  advisory_script_entrypoint(advisory_script_entrypoint),
48  volatile_path_tracker(volatile_path_tracker) {}
49 
51  TaskObserverAdd add_callback,
52  TaskObserverRemove remove_callback,
53  std::string logger_prefix,
54  UnhandledExceptionCallback unhandled_exception_callback,
55  LogMessageCallback log_message_callback,
56  std::shared_ptr<IsolateNameServer> isolate_name_server,
57  bool is_root_isolate,
58  bool enable_skparagraph,
60  const UIDartState::Context& context)
61  : add_callback_(std::move(add_callback)),
62  remove_callback_(std::move(remove_callback)),
63  logger_prefix_(std::move(logger_prefix)),
64  is_root_isolate_(is_root_isolate),
65  unhandled_exception_callback_(unhandled_exception_callback),
66  log_message_callback_(log_message_callback),
67  isolate_name_server_(std::move(isolate_name_server)),
68  enable_skparagraph_(enable_skparagraph),
69  enable_display_list_(enable_display_list),
70  context_(std::move(context)) {
71  AddOrRemoveTaskObserver(true /* add */);
72 }
73 
75  AddOrRemoveTaskObserver(false /* remove */);
76 }
77 
78 const std::string& UIDartState::GetAdvisoryScriptURI() const {
79  return context_.advisory_script_uri;
80 }
81 
82 const std::string& UIDartState::GetAdvisoryScriptEntrypoint() const {
83  return context_.advisory_script_entrypoint;
84 }
85 
86 void UIDartState::DidSetIsolate() {
87  main_port_ = Dart_GetMainPortId();
88  std::ostringstream debug_name;
89  // main.dart$main-1234
90  debug_name << context_.advisory_script_uri << "$"
91  << context_.advisory_script_entrypoint << "-" << main_port_;
92  SetDebugName(debug_name.str());
93 }
94 
97  Dart_ThrowException(
98  tonic::ToDart("UI actions are only available on root isolate."));
99  }
100 }
101 
102 void UIDartState::SetDebugName(const std::string debug_name) {
103  debug_name_ = debug_name;
104  if (platform_configuration_) {
105  platform_configuration_->client()->UpdateIsolateDescription(debug_name_,
106  main_port_);
107  }
108 }
109 
111  return static_cast<UIDartState*>(DartState::Current());
112 }
113 
115  std::unique_ptr<PlatformConfiguration> platform_configuration) {
116  platform_configuration_ = std::move(platform_configuration);
117  if (platform_configuration_) {
118  platform_configuration_->client()->UpdateIsolateDescription(debug_name_,
119  main_port_);
120  }
121 }
122 
124  return context_.task_runners;
125 }
126 
128  return context_.io_manager;
129 }
130 
132  return context_.unref_queue;
133 }
134 
135 std::shared_ptr<VolatilePathTracker> UIDartState::GetVolatilePathTracker()
136  const {
137  return context_.volatile_path_tracker;
138 }
139 
141  if (tonic::LogIfError(closure) || !Dart_IsClosure(closure)) {
142  return;
143  }
144 
145  microtask_queue_.ScheduleMicrotask(closure);
146 }
147 
149  microtask_queue_.RunMicrotasks();
150 }
151 
152 void UIDartState::AddOrRemoveTaskObserver(bool add) {
153  auto task_runner = context_.task_runners.GetUITaskRunner();
154  if (!task_runner) {
155  // This may happen in case the isolate has no thread affinity (for example,
156  // the service isolate).
157  return;
158  }
159  FML_DCHECK(add_callback_ && remove_callback_);
160  if (add) {
161  add_callback_(reinterpret_cast<intptr_t>(this),
162  [this]() { this->FlushMicrotasksNow(); });
163  } else {
164  remove_callback_(reinterpret_cast<intptr_t>(this));
165  }
166 }
167 
169  return context_.snapshot_delegate;
170 }
171 
173  if (!context_.io_manager) {
174  return {};
175  }
176  return context_.io_manager->GetResourceContext();
177 }
178 
180  return context_.image_decoder;
181 }
182 
184  const {
185  return context_.image_generator_registry;
186 }
187 
188 std::shared_ptr<IsolateNameServer> UIDartState::GetIsolateNameServer() const {
189  return isolate_name_server_;
190 }
191 
194  if (error == tonic::kNoError) {
195  error = microtask_queue_.GetLastError();
196  }
197  return error;
198 }
199 
201  const std::string& stack_trace) {
202  if (unhandled_exception_callback_ &&
203  unhandled_exception_callback_(error, stack_trace)) {
204  return;
205  }
206 
207  // Either the exception handler was not set or it could not handle the error,
208  // just log the exception.
209  FML_LOG(ERROR) << "Unhandled Exception: " << error << std::endl
210  << stack_trace;
211 }
212 
213 void UIDartState::LogMessage(const std::string& tag,
214  const std::string& message) const {
215  if (log_message_callback_) {
216  log_message_callback_(tag, message);
217  } else {
218  // Fall back to previous behavior if unspecified.
219 #if defined(OS_ANDROID)
220  __android_log_print(ANDROID_LOG_INFO, tag.c_str(), "%.*s",
221  (int)message.size(), message.c_str());
222 #elif defined(OS_IOS)
223  std::stringstream stream;
224  if (tag.size() > 0) {
225  stream << tag << ": ";
226  }
227  stream << message;
228  std::string log = stream.str();
229  syslog(1 /* LOG_ALERT */, "%.*s", (int)log.size(), log.c_str());
230 #else
231  if (tag.size() > 0) {
232  std::cout << tag << ": ";
233  }
234  std::cout << message << std::endl;
235 #endif
236  }
237 }
238 
240  return enable_skparagraph_;
241 }
242 
244  return enable_display_list_;
245 }
246 
247 } // namespace flutter
std::function< bool(const std::string &, const std::string &)> UnhandledExceptionCallback
Definition: settings.h:77
void ReportUnhandledException(const std::string &error, const std::string &stack_trace)
fml::RefPtr< SkiaUnrefQueue > unref_queue
Definition: ui_dart_state.h:71
const uint8_t uint32_t uint32_t GError ** error
fml::WeakPtr< SnapshotDelegate > snapshot_delegate
Definition: ui_dart_state.h:64
#define FML_DCHECK(condition)
Definition: logging.h:86
fml::WeakPtr< IOManager > io_manager
The IO manager used by the isolate for asynchronous texture uploads.
Definition: ui_dart_state.h:67
std::function< void(intptr_t)> TaskObserverRemove
Definition: settings.h:74
tonic::DartErrorHandleType GetLastError()
fml::WeakPtr< SnapshotDelegate > GetSnapshotDelegate() const
std::function< void(const std::string &, const std::string &)> LogMessageCallback
Definition: settings.h:80
DartErrorHandleType isolate_last_error() const
Definition: ref_ptr.h:252
const std::string & logger_prefix() const
void SetDebugName(const std::string name)
#define FML_LOG(severity)
Definition: logging.h:65
fml::WeakPtr< GrDirectContext > GetResourceContext() const
fml::WeakPtr< ImageGeneratorRegistry > GetImageGeneratorRegistry() const
DartErrorHandleType
Definition: dart_error.h:18
bool enable_display_list() const
bool enable_skparagraph() const
void ScheduleMicrotask(Dart_Handle callback)
std::function< void()> closure
Definition: closure.h:14
bool IsRootIsolate() const
Definition: ui_dart_state.h:96
const std::string & GetAdvisoryScriptEntrypoint() const
std::function< void(intptr_t, fml::closure)> TaskObserverAdd
Definition: settings.h:73
fml::WeakPtr< ImageGeneratorRegistry > image_generator_registry
Definition: ui_dart_state.h:79
fml::WeakPtr< ImageDecoder > image_decoder
The image decoder.
Definition: ui_dart_state.h:74
const std::string & debug_name() const
static void ThrowIfUIOperationsProhibited()
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
Definition: ui_dart_state.h:43
PlatformConfiguration * platform_configuration() const
std::shared_ptr< VolatilePathTracker > volatile_path_tracker
Cache for tracking path volatility.
Definition: ui_dart_state.h:91
std::string advisory_script_entrypoint
Definition: ui_dart_state.h:88
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34
const TaskRunners task_runners
Definition: ui_dart_state.h:59
fml::RefPtr< flutter::SkiaUnrefQueue > GetSkiaUnrefQueue() const
const std::string & GetAdvisoryScriptURI() const
UIDartState(TaskObserverAdd add_callback, TaskObserverRemove remove_callback, std::string logger_prefix, UnhandledExceptionCallback unhandled_exception_callback, LogMessageCallback log_message_callback, std::shared_ptr< IsolateNameServer > isolate_name_server, bool is_root_isolate_, bool enable_skparagraph, bool enable_display_list, const UIDartState::Context &context)
fml::WeakPtr< ImageDecoder > GetImageDecoder() const
fml::WeakPtr< IOManager > GetIOManager() const
void LogMessage(const std::string &tag, const std::string &message) const
std::shared_ptr< IsolateNameServer > GetIsolateNameServer() const
const TaskRunners & GetTaskRunners() const
void ScheduleMicrotask(Dart_Handle handle)
Dart_Handle ToDart(const T &object)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
Context(const TaskRunners &task_runners)
void SetPlatformConfiguration(std::unique_ptr< PlatformConfiguration > platform_configuration)
DartMessageHandler & message_handler()
Definition: dart_state.h:60
static UIDartState * Current()
std::shared_ptr< VolatilePathTracker > GetVolatilePathTracker() const
DartErrorHandleType GetLastError()