flutter_main.cc 3.8 KB
Newer Older
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#define FML_USED_ON_EMBEDDER

7 8 9
#include "flutter/shell/platform/android/flutter_main.h"

#include <vector>
10

11 12
#include "flutter/fml/message_loop.h"
#include "flutter/fml/paths.h"
13
#include "flutter/fml/platform/android/jni_util.h"
14
#include "flutter/runtime/dart_vm.h"
15
#include "flutter/runtime/start_up.h"
16
#include "flutter/shell/common/shell.h"
17
#include "flutter/shell/common/switches.h"
18 19
#include "lib/fxl/arraysize.h"
#include "lib/fxl/command_line.h"
20
#include "lib/fxl/files/file.h"
21
#include "lib/fxl/macros.h"
22
#include "third_party/dart/runtime/include/dart_tools_api.h"
23 24 25

namespace shell {

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
FlutterMain::FlutterMain(blink::Settings settings)
    : settings_(std::move(settings)) {}

FlutterMain::~FlutterMain() = default;

static std::unique_ptr<FlutterMain> g_flutter_main;

FlutterMain& FlutterMain::Get() {
  FXL_CHECK(g_flutter_main) << "ensureInitializationComplete must have already "
                               "been called.";
  return *g_flutter_main;
}

const blink::Settings& FlutterMain::GetSettings() const {
  return settings_;
}

void FlutterMain::Init(JNIEnv* env,
                       jclass clazz,
                       jobject context,
                       jobjectArray jargs,
                       jstring bundlePath) {
48
  std::vector<std::string> args;
49
  args.push_back("flutter");
50 51 52
  for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
    args.push_back(std::move(arg));
  }
53
  auto command_line = fxl::CommandLineFromIterators(args.begin(), args.end());
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

  auto settings = SettingsFromCommandLine(command_line);

  settings.assets_path = fml::jni::JavaStringToString(env, bundlePath);

  if (!blink::DartVM::IsRunningPrecompiledCode()) {
    // Check to see if the appropriate kernel files are present and configure
    // settings accordingly.
    auto platform_kernel_path =
        fml::paths::JoinPaths({settings.assets_path, "platform.dill"});
    auto application_kernel_path =
        fml::paths::JoinPaths({settings.assets_path, "kernel_blob.bin"});

    if (files::IsFile(platform_kernel_path) &&
        files::IsFile(application_kernel_path)) {
      settings.kernel_snapshot_path = platform_kernel_path;
      settings.application_kernel_asset = application_kernel_path;
    }
  }

  settings.task_observer_add = [](intptr_t key, fxl::Closure callback) {
    fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
  };

  settings.task_observer_remove = [](intptr_t key) {
    fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
  };
  // 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)));
84 85
}

86 87 88 89 90
static void RecordStartTimestamp(JNIEnv* env,
                                 jclass jcaller,
                                 jlong initTimeMillis) {
  int64_t initTimeMicros =
      static_cast<int64_t>(initTimeMillis) * static_cast<int64_t>(1000);
91 92 93
  blink::engine_main_enter_ts = Dart_TimelineGetMicros() - initTimeMicros;
}

94
bool FlutterMain::Register(JNIEnv* env) {
95 96 97
  static const JNINativeMethod methods[] = {
      {
          .name = "nativeInit",
98 99
          .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
                       "lang/String;)V",
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
          .fnPtr = reinterpret_cast<void*>(&Init),
      },
      {
          .name = "nativeRecordStartTimestamp",
          .signature = "(J)V",
          .fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
      },
  };

  jclass clazz = env->FindClass("io/flutter/view/FlutterMain");

  if (clazz == nullptr) {
    return false;
  }

  return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
116 117
}

118
}  // namespace shell