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 "flutter/fml/message_loop.h"
8 #include "flutter/lib/ui/window/platform_configuration.h"
11 
12 using tonic::ToDart;
13 
14 namespace flutter {
15 
17  TaskRunners task_runners,
18  TaskObserverAdd add_callback,
19  TaskObserverRemove remove_callback,
20  fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
21  fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
22  fml::WeakPtr<IOManager> io_manager,
23  fml::RefPtr<SkiaUnrefQueue> skia_unref_queue,
24  fml::WeakPtr<ImageDecoder> image_decoder,
25  std::string advisory_script_uri,
26  std::string advisory_script_entrypoint,
27  std::string logger_prefix,
28  UnhandledExceptionCallback unhandled_exception_callback,
29  std::shared_ptr<IsolateNameServer> isolate_name_server,
30  bool is_root_isolate)
31  : task_runners_(std::move(task_runners)),
32  add_callback_(std::move(add_callback)),
33  remove_callback_(std::move(remove_callback)),
34  snapshot_delegate_(std::move(snapshot_delegate)),
35  hint_freed_delegate_(std::move(hint_freed_delegate)),
36  io_manager_(std::move(io_manager)),
37  skia_unref_queue_(std::move(skia_unref_queue)),
38  image_decoder_(std::move(image_decoder)),
39  advisory_script_uri_(std::move(advisory_script_uri)),
40  advisory_script_entrypoint_(std::move(advisory_script_entrypoint)),
41  logger_prefix_(std::move(logger_prefix)),
42  is_root_isolate_(is_root_isolate),
43  unhandled_exception_callback_(unhandled_exception_callback),
44  isolate_name_server_(std::move(isolate_name_server)) {
45  AddOrRemoveTaskObserver(true /* add */);
46 }
47 
49  AddOrRemoveTaskObserver(false /* remove */);
50 }
51 
52 const std::string& UIDartState::GetAdvisoryScriptURI() const {
53  return advisory_script_uri_;
54 }
55 
56 const std::string& UIDartState::GetAdvisoryScriptEntrypoint() const {
57  return advisory_script_entrypoint_;
58 }
59 
60 void UIDartState::DidSetIsolate() {
61  main_port_ = Dart_GetMainPortId();
62  std::ostringstream debug_name;
63  // main.dart$main-1234
64  debug_name << advisory_script_uri_ << "$" << advisory_script_entrypoint_
65  << "-" << main_port_;
66  SetDebugName(debug_name.str());
67 }
68 
71  Dart_ThrowException(
72  tonic::ToDart("UI actions are only available on root isolate."));
73  }
74 }
75 
76 void UIDartState::SetDebugName(const std::string debug_name) {
77  debug_name_ = debug_name;
78  if (platform_configuration_) {
79  platform_configuration_->client()->UpdateIsolateDescription(debug_name_,
80  main_port_);
81  }
82 }
83 
85  return static_cast<UIDartState*>(DartState::Current());
86 }
87 
89  std::unique_ptr<PlatformConfiguration> platform_configuration) {
90  platform_configuration_ = std::move(platform_configuration);
91  if (platform_configuration_) {
92  platform_configuration_->client()->UpdateIsolateDescription(debug_name_,
93  main_port_);
94  }
95 }
96 
98  return task_runners_;
99 }
100 
102  return io_manager_;
103 }
104 
106  return skia_unref_queue_;
107 }
108 
110  if (tonic::LogIfError(closure) || !Dart_IsClosure(closure)) {
111  return;
112  }
113 
114  microtask_queue_.ScheduleMicrotask(closure);
115 }
116 
118  microtask_queue_.RunMicrotasks();
119 }
120 
121 void UIDartState::AddOrRemoveTaskObserver(bool add) {
122  auto task_runner = task_runners_.GetUITaskRunner();
123  if (!task_runner) {
124  // This may happen in case the isolate has no thread affinity (for example,
125  // the service isolate).
126  return;
127  }
128  FML_DCHECK(add_callback_ && remove_callback_);
129  if (add) {
130  add_callback_(reinterpret_cast<intptr_t>(this),
131  [this]() { this->FlushMicrotasksNow(); });
132  } else {
133  remove_callback_(reinterpret_cast<intptr_t>(this));
134  }
135 }
136 
138  return snapshot_delegate_;
139 }
140 
142  return hint_freed_delegate_;
143 }
144 
146  if (!io_manager_) {
147  return {};
148  }
149  return io_manager_->GetResourceContext();
150 }
151 
153  return image_decoder_;
154 }
155 
156 std::shared_ptr<IsolateNameServer> UIDartState::GetIsolateNameServer() const {
157  return isolate_name_server_;
158 }
159 
162  if (error == tonic::kNoError) {
163  error = microtask_queue_.GetLastError();
164  }
165  return error;
166 }
167 
169  const std::string& stack_trace) {
170  if (unhandled_exception_callback_ &&
171  unhandled_exception_callback_(error, stack_trace)) {
172  return;
173  }
174 
175  // Either the exception handler was not set or it could not handle the error,
176  // just log the exception.
177  FML_LOG(ERROR) << "Unhandled Exception: " << error << std::endl
178  << stack_trace;
179 }
180 
181 } // namespace flutter
std::function< bool(const std::string &, const std::string &)> UnhandledExceptionCallback
Definition: settings.h:52
void ReportUnhandledException(const std::string &error, const std::string &stack_trace)
#define FML_DCHECK(condition)
Definition: logging.h:86
std::function< void(intptr_t)> TaskObserverRemove
Definition: settings.h:49
tonic::DartErrorHandleType GetLastError()
FlMethodResponse GError ** error
fml::WeakPtr< SnapshotDelegate > GetSnapshotDelegate() const
DartErrorHandleType isolate_last_error() const
Definition: ref_ptr.h:252
void SetDebugName(const std::string name)
#define FML_LOG(severity)
Definition: logging.h:65
fml::WeakPtr< GrDirectContext > GetResourceContext() const
UIDartState(TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > skia_unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, std::string logger_prefix, UnhandledExceptionCallback unhandled_exception_callback, std::shared_ptr< IsolateNameServer > isolate_name_server, bool is_root_isolate_)
DartErrorHandleType
Definition: dart_error.h:18
TaskRunners task_runners_
void ScheduleMicrotask(Dart_Handle callback)
std::function< void()> closure
Definition: closure.h:14
bool IsRootIsolate() const
Definition: ui_dart_state.h:39
const std::string & GetAdvisoryScriptEntrypoint() const
std::function< void(intptr_t, fml::closure)> TaskObserverAdd
Definition: settings.h:48
const std::string & debug_name() const
Definition: ui_dart_state.h:44
static void ThrowIfUIOperationsProhibited()
PlatformConfiguration * platform_configuration() const
Definition: ui_dart_state.h:48
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34
fml::RefPtr< flutter::SkiaUnrefQueue > GetSkiaUnrefQueue() const
const std::string & GetAdvisoryScriptURI() const
fml::WeakPtr< IOManager > io_manager_
fml::WeakPtr< ImageDecoder > GetImageDecoder() const
fml::WeakPtr< IOManager > GetIOManager() const
fml::WeakPtr< HintFreedDelegate > GetHintFreedDelegate() 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
void SetPlatformConfiguration(std::unique_ptr< PlatformConfiguration > platform_configuration)
DartMessageHandler & message_handler()
Definition: dart_state.h:59
static UIDartState * Current()
DartErrorHandleType GetLastError()