Flutter Engine
android_shell_holder.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 #define FML_USED_ON_EMBEDDER
6 
7 #include "flutter/shell/platform/android/android_shell_holder.h"
8 
9 #include <pthread.h>
10 #include <sys/resource.h>
11 #include <sys/time.h>
12 
13 #include <sstream>
14 #include <string>
15 #include <utility>
16 
17 #include "flutter/fml/make_copyable.h"
18 #include "flutter/fml/message_loop.h"
19 #include "flutter/fml/platform/android/jni_util.h"
20 #include "flutter/shell/common/rasterizer.h"
21 #include "flutter/shell/platform/android/platform_view_android.h"
22 
23 namespace flutter {
24 
26  PlatformData platform_data;
27  platform_data.lifecycle_state = "AppLifecycleState.detached";
28  return platform_data;
29 }
30 
32  flutter::Settings settings,
33  std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
34  bool is_background_view)
35  : settings_(std::move(settings)), jni_facade_(jni_facade) {
36  static size_t shell_count = 1;
37  auto thread_label = std::to_string(shell_count++);
38 
39  FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) ==
40  0);
41 
42  if (is_background_view) {
43  thread_host_ = {thread_label, ThreadHost::Type::UI};
44  } else {
45  thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
46  ThreadHost::Type::IO};
47  }
48 
49  // Detach from JNI when the UI and raster threads exit.
50  auto jni_exit_task([key = thread_destruct_key_]() {
51  FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0);
52  });
53  thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
54  if (!is_background_view) {
55  thread_host_.raster_thread->GetTaskRunner()->PostTask(jni_exit_task);
56  }
57 
58  fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
59  Shell::CreateCallback<PlatformView> on_create_platform_view =
60  [is_background_view, &jni_facade, &weak_platform_view](Shell& shell) {
61  std::unique_ptr<PlatformViewAndroid> platform_view_android;
62  if (is_background_view) {
63  platform_view_android = std::make_unique<PlatformViewAndroid>(
64  shell, // delegate
65  shell.GetTaskRunners(), // task runners
66  jni_facade // JNI interop
67  );
68  } else {
69  platform_view_android = std::make_unique<PlatformViewAndroid>(
70  shell, // delegate
71  shell.GetTaskRunners(), // task runners
72  jni_facade, // JNI interop
73  shell.GetSettings()
74  .enable_software_rendering // use software rendering
75  );
76  }
77  weak_platform_view = platform_view_android->GetWeakPtr();
78  shell.OnDisplayUpdates(DisplayUpdateType::kStartup,
79  {Display(jni_facade->GetDisplayRefreshRate())});
80  return platform_view_android;
81  };
82 
83  Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
84  return std::make_unique<Rasterizer>(shell);
85  };
86 
87  // The current thread will be used as the platform thread. Ensure that the
88  // message loop is initialized.
93  fml::RefPtr<fml::TaskRunner> platform_runner =
95  if (is_background_view) {
96  auto single_task_runner = thread_host_.ui_thread->GetTaskRunner();
97  gpu_runner = single_task_runner;
98  ui_runner = single_task_runner;
99  io_runner = single_task_runner;
100  } else {
101  gpu_runner = thread_host_.raster_thread->GetTaskRunner();
102  ui_runner = thread_host_.ui_thread->GetTaskRunner();
103  io_runner = thread_host_.io_thread->GetTaskRunner();
104  }
105 
106  flutter::TaskRunners task_runners(thread_label, // label
107  platform_runner, // platform
108  gpu_runner, // raster
109  ui_runner, // ui
110  io_runner // io
111  );
112  task_runners.GetRasterTaskRunner()->PostTask([]() {
113  // Android describes -8 as "most important display threads, for
114  // compositing the screen and retrieving input events". Conservatively
115  // set the raster thread to slightly lower priority than it.
116  if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
117  // Defensive fallback. Depending on the OEM, it may not be possible
118  // to set priority to -5.
119  if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
120  FML_LOG(ERROR) << "Failed to set GPU task runner priority";
121  }
122  }
123  });
124  task_runners.GetUITaskRunner()->PostTask([]() {
125  if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
126  FML_LOG(ERROR) << "Failed to set UI task runner priority";
127  }
128  });
129 
130  shell_ =
131  Shell::Create(task_runners, // task runners
132  GetDefaultPlatformData(), // window data
133  settings_, // settings
134  on_create_platform_view, // platform view create callback
135  on_create_rasterizer // rasterizer create callback
136  );
137 
138  platform_view_ = weak_platform_view;
139  FML_DCHECK(platform_view_);
140  is_valid_ = shell_ != nullptr;
141 }
142 
144  shell_.reset();
145  thread_host_.Reset();
146  FML_CHECK(pthread_key_delete(thread_destruct_key_) == 0);
147 }
148 
149 void AndroidShellHolder::ThreadDestructCallback(void* value) {
151 }
152 
154  return is_valid_;
155 }
156 
158  return settings_;
159 }
160 
162  if (!IsValid()) {
163  return;
164  }
165 
166  shell_->RunEngine(std::move(config));
167 }
168 
171  bool base64_encode) {
172  if (!IsValid()) {
173  return {nullptr, SkISize::MakeEmpty()};
174  }
175  return shell_->Screenshot(type, base64_encode);
176 }
177 
179  FML_DCHECK(platform_view_);
180  return platform_view_;
181 }
182 
184  FML_DCHECK(shell_);
185  shell_->NotifyLowMemoryWarning();
186 }
187 } // namespace flutter
std::unique_ptr< fml::Thread > ui_thread
Definition: thread_host.h:26
Settings settings_
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition: shell.h:99
#define FML_DCHECK(condition)
Definition: logging.h:86
Rasterizer::Screenshot Screenshot(Rasterizer::ScreenshotType type, bool base64_encode)
Definition: ref_ptr.h:252
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
void Launch(RunConfiguration configuration)
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
#define FML_LOG(severity)
Definition: logging.h:65
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
Definition: task_runners.cc:42
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: message_loop.cc:56
AndroidShellHolder(flutter::Settings settings, std::shared_ptr< PlatformViewAndroidJNI > jni_facade, bool is_background_view)
A POD type used to return the screenshot data along with the size of the frame.
Definition: rasterizer.h:279
uint8_t value
ScreenshotType
The type of the screenshot to obtain of the previously rendered layer tree.
Definition: rasterizer.h:249
Specifies all the configuration required by the runtime library to launch the root isolate...
fml::WeakPtr< PlatformViewAndroid > GetPlatformView()
const flutter::Settings & GetSettings() const
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34
static PlatformData GetDefaultPlatformData()
#define FML_CHECK(condition)
Definition: logging.h:68
std::unique_ptr< fml::Thread > io_thread
Definition: thread_host.h:28
void DetachFromVM()
Definition: jni_util.cc:46
static std::unique_ptr< Shell > Create(TaskRunners task_runners, Settings settings, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer)
Creates a shell instance using the provided settings. The callbacks to create the various shell subco...
Definition: shell.cc:239
std::unique_ptr< fml::Thread > raster_thread
Definition: thread_host.h:27
std::string lifecycle_state
Definition: platform_data.h:40