mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
3f4f606105
* Remove deprecated runBundle APIs * Remove code related to dynamic patching (including support for multiple bundle paths) * Change FlutterRunArugments.bundlePath to be the Android AssetManager path where the app's assets are located
187 lines
6.1 KiB
C++
187 lines
6.1 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#define FML_USED_ON_EMBEDDER
|
|
|
|
#include "flutter/shell/platform/android/flutter_main.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "flutter/fml/command_line.h"
|
|
#include "flutter/fml/file.h"
|
|
#include "flutter/fml/macros.h"
|
|
#include "flutter/fml/message_loop.h"
|
|
#include "flutter/fml/paths.h"
|
|
#include "flutter/fml/platform/android/jni_util.h"
|
|
#include "flutter/fml/platform/android/paths_android.h"
|
|
#include "flutter/fml/size.h"
|
|
#include "flutter/lib/ui/plugins/callback_cache.h"
|
|
#include "flutter/runtime/dart_vm.h"
|
|
#include "flutter/runtime/start_up.h"
|
|
#include "flutter/shell/common/shell.h"
|
|
#include "flutter/shell/common/switches.h"
|
|
#include "third_party/dart/runtime/include/dart_tools_api.h"
|
|
|
|
namespace flutter {
|
|
|
|
extern "C" {
|
|
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
|
|
// Used for debugging dart:* sources.
|
|
extern const uint8_t kPlatformStrongDill[];
|
|
extern const intptr_t kPlatformStrongDillSize;
|
|
#endif
|
|
}
|
|
|
|
namespace {
|
|
|
|
fml::jni::ScopedJavaGlobalRef<jclass>* g_flutter_jni_class = nullptr;
|
|
|
|
} // anonymous namespace
|
|
|
|
FlutterMain::FlutterMain(flutter::Settings settings)
|
|
: settings_(std::move(settings)), observatory_uri_callback_() {}
|
|
|
|
FlutterMain::~FlutterMain() = default;
|
|
|
|
static std::unique_ptr<FlutterMain> g_flutter_main;
|
|
|
|
FlutterMain& FlutterMain::Get() {
|
|
FML_CHECK(g_flutter_main) << "ensureInitializationComplete must have already "
|
|
"been called.";
|
|
return *g_flutter_main;
|
|
}
|
|
|
|
const flutter::Settings& FlutterMain::GetSettings() const {
|
|
return settings_;
|
|
}
|
|
|
|
void FlutterMain::Init(JNIEnv* env,
|
|
jclass clazz,
|
|
jobject context,
|
|
jobjectArray jargs,
|
|
jstring kernelPath,
|
|
jstring appStoragePath,
|
|
jstring engineCachesPath) {
|
|
std::vector<std::string> args;
|
|
args.push_back("flutter");
|
|
for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
|
|
args.push_back(std::move(arg));
|
|
}
|
|
auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());
|
|
|
|
auto settings = SettingsFromCommandLine(command_line);
|
|
|
|
// Restore the callback cache.
|
|
// TODO(chinmaygarde): Route all cache file access through FML and remove this
|
|
// setter.
|
|
flutter::DartCallbackCache::SetCachePath(
|
|
fml::jni::JavaStringToString(env, appStoragePath));
|
|
|
|
fml::paths::InitializeAndroidCachesPath(
|
|
fml::jni::JavaStringToString(env, engineCachesPath));
|
|
|
|
flutter::DartCallbackCache::LoadCacheFromDisk();
|
|
|
|
if (!flutter::DartVM::IsRunningPrecompiledCode() && kernelPath) {
|
|
// Check to see if the appropriate kernel files are present and configure
|
|
// settings accordingly.
|
|
auto application_kernel_path =
|
|
fml::jni::JavaStringToString(env, kernelPath);
|
|
|
|
if (fml::IsFile(application_kernel_path)) {
|
|
settings.application_kernel_asset = application_kernel_path;
|
|
}
|
|
}
|
|
|
|
settings.task_observer_add = [](intptr_t key, fml::closure callback) {
|
|
fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
|
|
};
|
|
|
|
settings.task_observer_remove = [](intptr_t key) {
|
|
fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
|
|
};
|
|
|
|
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
|
|
// There are no ownership concerns here as all mappings are owned by the
|
|
// embedder and not the engine.
|
|
auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
|
|
return [mapping, size]() {
|
|
return std::make_unique<fml::NonOwnedMapping>(mapping, size);
|
|
};
|
|
};
|
|
|
|
settings.dart_library_sources_kernel =
|
|
make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
|
|
#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
|
|
|
|
// Not thread safe. Will be removed when FlutterMain is refactored to no
|
|
// longer be a singleton.
|
|
g_flutter_main.reset(new FlutterMain(std::move(settings)));
|
|
|
|
g_flutter_main->SetupObservatoryUriCallback(env);
|
|
}
|
|
|
|
void FlutterMain::SetupObservatoryUriCallback(JNIEnv* env) {
|
|
g_flutter_jni_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
|
|
env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
|
|
if (g_flutter_jni_class->is_null()) {
|
|
return;
|
|
}
|
|
jfieldID uri_field = env->GetStaticFieldID(
|
|
g_flutter_jni_class->obj(), "observatoryUri", "Ljava/lang/String;");
|
|
if (uri_field == nullptr) {
|
|
return;
|
|
}
|
|
|
|
auto set_uri = [env, uri_field](std::string uri) {
|
|
fml::jni::ScopedJavaLocalRef<jstring> java_uri =
|
|
fml::jni::StringToJavaString(env, uri);
|
|
env->SetStaticObjectField(g_flutter_jni_class->obj(), uri_field,
|
|
java_uri.obj());
|
|
};
|
|
|
|
fml::MessageLoop::EnsureInitializedForCurrentThread();
|
|
fml::RefPtr<fml::TaskRunner> platform_runner =
|
|
fml::MessageLoop::GetCurrent().GetTaskRunner();
|
|
|
|
observatory_uri_callback_ = DartServiceIsolate::AddServerStatusCallback(
|
|
[platform_runner, set_uri](std::string uri) {
|
|
platform_runner->PostTask([uri, set_uri] { set_uri(uri); });
|
|
});
|
|
}
|
|
|
|
static void RecordStartTimestamp(JNIEnv* env,
|
|
jclass jcaller,
|
|
jlong initTimeMillis) {
|
|
int64_t initTimeMicros =
|
|
static_cast<int64_t>(initTimeMillis) * static_cast<int64_t>(1000);
|
|
flutter::engine_main_enter_ts = Dart_TimelineGetMicros() - initTimeMicros;
|
|
}
|
|
|
|
bool FlutterMain::Register(JNIEnv* env) {
|
|
static const JNINativeMethod methods[] = {
|
|
{
|
|
.name = "nativeInit",
|
|
.signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
|
|
"lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
|
.fnPtr = reinterpret_cast<void*>(&Init),
|
|
},
|
|
{
|
|
.name = "nativeRecordStartTimestamp",
|
|
.signature = "(J)V",
|
|
.fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
|
|
},
|
|
};
|
|
|
|
jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
|
|
|
|
if (clazz == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
|
|
}
|
|
|
|
} // namespace flutter
|