Flutter Engine
flutter_main.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/flutter_main.h"
8 
9 #include <vector>
10 
11 #include "flutter/fml/command_line.h"
12 #include "flutter/fml/file.h"
13 #include "flutter/fml/macros.h"
14 #include "flutter/fml/message_loop.h"
15 #include "flutter/fml/paths.h"
16 #include "flutter/fml/platform/android/jni_util.h"
17 #include "flutter/fml/platform/android/paths_android.h"
18 #include "flutter/fml/size.h"
19 #include "flutter/lib/ui/plugins/callback_cache.h"
20 #include "flutter/runtime/dart_vm.h"
21 #include "flutter/shell/common/shell.h"
22 #include "flutter/shell/common/switches.h"
23 #include "third_party/dart/runtime/include/dart_tools_api.h"
24 #include "third_party/skia/include/core/SkFontMgr.h"
25 
26 namespace flutter {
27 
28 extern "C" {
29 #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
30 // Used for debugging dart:* sources.
31 extern const uint8_t kPlatformStrongDill[];
32 extern const intptr_t kPlatformStrongDillSize;
33 #endif
34 }
35 
36 namespace {
37 
39 
40 } // anonymous namespace
41 
42 FlutterMain::FlutterMain(flutter::Settings settings)
43  : settings_(std::move(settings)), observatory_uri_callback_() {}
44 
45 FlutterMain::~FlutterMain() = default;
46 
47 static std::unique_ptr<FlutterMain> g_flutter_main;
48 
50  FML_CHECK(g_flutter_main) << "ensureInitializationComplete must have already "
51  "been called.";
52  return *g_flutter_main;
53 }
54 
56  return settings_;
57 }
58 
59 void FlutterMain::Init(JNIEnv* env,
60  jclass clazz,
61  jobject context,
62  jobjectArray jargs,
63  jstring kernelPath,
64  jstring appStoragePath,
65  jstring engineCachesPath,
66  jlong initTimeMillis) {
67  std::vector<std::string> args;
68  args.push_back("flutter");
69  for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
70  args.push_back(std::move(arg));
71  }
72  auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());
73 
74  auto settings = SettingsFromCommandLine(command_line);
75 
76  int64_t init_time_micros = initTimeMillis * 1000;
77  settings.engine_start_timestamp =
78  std::chrono::microseconds(Dart_TimelineGetMicros() - init_time_micros);
79 
80  // Restore the callback cache.
81  // TODO(chinmaygarde): Route all cache file access through FML and remove this
82  // setter.
84  fml::jni::JavaStringToString(env, appStoragePath));
85 
87  fml::jni::JavaStringToString(env, engineCachesPath));
88 
90 
91  if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
92  // Check to see if the appropriate kernel files are present and configure
93  // settings accordingly.
94  auto application_kernel_path =
95  fml::jni::JavaStringToString(env, kernelPath);
96 
97  if (fml::IsFile(application_kernel_path)) {
98  settings.application_kernel_asset = application_kernel_path;
99  }
100  }
101 
102  settings.task_observer_add = [](intptr_t key, fml::closure callback) {
103  fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
104  };
105 
106  settings.task_observer_remove = [](intptr_t key) {
108  };
109 
110 #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
111  // There are no ownership concerns here as all mappings are owned by the
112  // embedder and not the engine.
113  auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
114  return [mapping, size]() {
115  return std::make_unique<fml::NonOwnedMapping>(mapping, size);
116  };
117  };
118 
119  settings.dart_library_sources_kernel =
120  make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
121 #endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
122 
123  // Not thread safe. Will be removed when FlutterMain is refactored to no
124  // longer be a singleton.
125  g_flutter_main.reset(new FlutterMain(std::move(settings)));
126 
127  g_flutter_main->SetupObservatoryUriCallback(env);
128 }
129 
130 void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) {
132  env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
133  if (g_flutter_jni_class->is_null()) {
134  return;
135  }
136  jfieldID uri_field = env->GetStaticFieldID(
137  g_flutter_jni_class->obj(), "observatoryUri", "Ljava/lang/String;");
138  if (uri_field == nullptr) {
139  return;
140  }
141 
142  auto set_uri = [env, uri_field](std::string uri) {
145  env->SetStaticObjectField(g_flutter_jni_class->obj(), uri_field,
146  java_uri.obj());
147  };
148 
150  fml::RefPtr<fml::TaskRunner> platform_runner =
152 
153  observatory_uri_callback_ = DartServiceIsolate::AddServerStatusCallback(
154  [platform_runner, set_uri](std::string uri) {
155  platform_runner->PostTask([uri, set_uri] { set_uri(uri); });
156  });
157 }
158 
159 static void PrefetchDefaultFontManager(JNIEnv* env, jclass jcaller) {
160  // Initialize a singleton owned by Skia.
161  SkFontMgr::RefDefault();
162 }
163 
164 bool FlutterMain::Register(JNIEnv* env) {
165  static const JNINativeMethod methods[] = {
166  {
167  .name = "nativeInit",
168  .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
169  "lang/String;Ljava/lang/String;Ljava/lang/String;J)V",
170  .fnPtr = reinterpret_cast<void*>(&Init),
171  },
172  {
173  .name = "nativePrefetchDefaultFontManager",
174  .signature = "()V",
175  .fnPtr = reinterpret_cast<void*>(&PrefetchDefaultFontManager),
176  },
177  };
178 
179  jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
180 
181  if (clazz == nullptr) {
182  return false;
183  }
184 
185  return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
186 }
187 
188 } // namespace flutter
Settings settings_
static std::unique_ptr< FlutterMain > g_flutter_main
Definition: flutter_main.cc:47
void AddTaskObserver(intptr_t key, const fml::closure &callback)
Definition: message_loop.cc:64
const intptr_t kPlatformStrongDillSize
static void PrefetchDefaultFontManager(JNIEnv *env, jclass jcaller)
ScopedJavaLocalRef< jstring > StringToJavaString(JNIEnv *env, const std::string &u8_string)
Definition: jni_util.cc:78
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
static void SetCachePath(const std::string &path)
Settings SettingsFromCommandLine(const fml::CommandLine &command_line)
Definition: switches.cc:216
const flutter::Settings & GetSettings() const
Definition: flutter_main.cc:55
static CallbackHandle AddServerStatusCallback(const ObservatoryServerStateCallback &callback)
Add a callback that will get invoked when the observatory starts up. If the observatory has already s...
static fml::jni::ScopedJavaGlobalRef< jclass > * g_flutter_jni_class
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: message_loop.cc:56
const uint8_t kPlatformStrongDill[]
std::function< void()> closure
Definition: closure.h:14
static FlutterMain & Get()
Definition: flutter_main.cc:49
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition: dart_vm.cc:199
static bool Register(JNIEnv *env)
void InitializeAndroidCachesPath(std::string caches_path)
#define FML_CHECK(condition)
Definition: logging.h:68
bool IsFile(const std::string &path)
Definition: file_posix.cc:143
void RemoveTaskObserver(intptr_t key)
Definition: message_loop.cc:68
std::string JavaStringToString(JNIEnv *env, jstring str)
Definition: jni_util.cc:58
std::vector< std::string > StringArrayToVector(JNIEnv *env, jobjectArray array)
Definition: jni_util.cc:88
CommandLine CommandLineFromIterators(InputIterator first, InputIterator last)
Definition: command_line.h:201