app.cc 5.2 KB
Newer Older
A
Adam Barth 已提交
1 2 3 4 5 6 7 8 9
// Copyright 2016 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.

#include "flutter/content_handler/app.h"

#include <thread>
#include <utility>

10
#include "apps/icu_data/lib/icu_data.h"
A
Adam Barth 已提交
11
#include "apps/tracing/lib/trace/provider.h"
A
Adam Barth 已提交
12 13 14 15 16 17 18 19 20 21
#include "flutter/common/settings.h"
#include "flutter/common/threads.h"
#include "flutter/sky/engine/platform/fonts/fuchsia/FontCacheFuchsia.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/tasks/task_runner.h"
#include "lib/mtl/tasks/message_loop.h"

namespace flutter_runner {
namespace {

22 23
static App* g_app = nullptr;

A
Adam Barth 已提交
24 25 26 27
void QuitMessageLoop() {
  mtl::MessageLoop::GetCurrent()->QuitNow();
}

28 29 30 31 32 33 34
std::string GetLabelFromURL(const std::string& url) {
  size_t last_slash = url.rfind('/');
  if (last_slash == std::string::npos || last_slash + 1 == url.length())
    return url;
  return url.substr(last_slash + 1);
}

A
Adam Barth 已提交
35 36 37
}  // namespace

App::App() {
38
  g_app = this;
39
  context_ = app::ApplicationContext::CreateFromStartupInfo();
A
Adam Barth 已提交
40

A
Adam Barth 已提交
41
  tracing::InitializeTracer(context_.get(), {});
A
Adam Barth 已提交
42

43 44
  gpu_thread_ = std::make_unique<mtl::Thread>();
  io_thread_ = std::make_unique<mtl::Thread>();
A
Adam Barth 已提交
45

46 47 48 49 50
  auto gpu_thread_success = gpu_thread_->Run();
  auto io_thread_success = io_thread_->Run();

  FTL_CHECK(gpu_thread_success) << "Must be able to create the GPU thread";
  FTL_CHECK(io_thread_success) << "Must be able to create the IO thread";
A
Adam Barth 已提交
51

52 53 54
  auto ui_task_runner = mtl::MessageLoop::GetCurrent()->task_runner();
  auto gpu_task_runner = gpu_thread_->TaskRunner();
  auto io_task_runner = io_thread_->TaskRunner();
A
Adam Barth 已提交
55 56

  // Notice that the Platform and UI threads are actually the same.
57 58 59 60 61
  blink::Threads::Set(blink::Threads(ui_task_runner,   // Platform
                                     gpu_task_runner,  // GPU
                                     ui_task_runner,   // UI
                                     io_task_runner    // IO
                                     ));
62

63
  if (!icu_data::Initialize(context_.get())) {
64 65 66
    FTL_LOG(ERROR) << "Could not initialize ICU data.";
  }

67 68
  blink::Settings settings;
  settings.enable_observatory = true;
69
  settings.enable_dart_profiling = true;
70
  blink::Settings::Set(settings);
71

A
Adam Barth 已提交
72 73 74
  blink::SetFontProvider(
      context_->ConnectToEnvironmentService<fonts::FontProvider>());

75 76
  context_->outgoing_services()->AddService<app::ApplicationRunner>(
      [this](fidl::InterfaceRequest<app::ApplicationRunner> request) {
A
Adam Barth 已提交
77 78 79 80 81
        runner_bindings_.AddBinding(this, std::move(request));
      });
}

App::~App() {
82
  icu_data::Release();
83 84
  blink::Threads::Gpu()->PostTask(QuitMessageLoop);
  blink::Threads::IO()->PostTask(QuitMessageLoop);
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
  g_app = nullptr;
}

App& App::Shared() {
  FTL_DCHECK(g_app);
  return *g_app;
}

void App::WaitForPlatformViewIds(
    std::vector<PlatformViewInfo>* platform_view_ids) {
  ftl::AutoResetWaitableEvent latch;

  blink::Threads::UI()->PostTask([this, platform_view_ids, &latch]() {
    WaitForPlatformViewsIdsUIThread(platform_view_ids, &latch);
  });

  latch.Wait();
}

void App::WaitForPlatformViewsIdsUIThread(
    std::vector<PlatformViewInfo>* platform_view_ids,
    ftl::AutoResetWaitableEvent* latch) {
  for (auto it = controllers_.begin(); it != controllers_.end(); it++) {
    ApplicationControllerImpl* controller = it->first;

    if (!controller) {
      continue;
    }

    PlatformViewInfo info;
    // TODO(zra): We should create real IDs for these instead of relying on the
    // address of the controller. Maybe just use the UI Isolate main port?
    info.view_id = reinterpret_cast<uintptr_t>(controller);
    info.isolate_id = controller->GetUIIsolateMainPort();
    info.isolate_name = controller->GetUIIsolateName();
    platform_view_ids->push_back(info);
  }
  latch->Signal();
A
Adam Barth 已提交
123 124 125
}

void App::StartApplication(
126 127 128
    app::ApplicationPackagePtr application,
    app::ApplicationStartupInfoPtr startup_info,
    fidl::InterfaceRequest<app::ApplicationController> controller) {
129 130 131 132
  if (controllers_.empty()) {
    // Name this process after the url of the first application being launched.
    base_label_ = "flutter:" + GetLabelFromURL(startup_info->launch_info->url);
  }
133

A
Adam Barth 已提交
134 135 136 137 138 139
  std::unique_ptr<ApplicationControllerImpl> impl =
      std::make_unique<ApplicationControllerImpl>(this, std::move(application),
                                                  std::move(startup_info),
                                                  std::move(controller));
  ApplicationControllerImpl* key = impl.get();
  controllers_.emplace(key, std::move(impl));
140 141

  UpdateProcessLabel();
A
Adam Barth 已提交
142 143 144 145 146 147 148
}

void App::Destroy(ApplicationControllerImpl* controller) {
  auto it = controllers_.find(controller);
  if (it == controllers_.end())
    return;
  controllers_.erase(it);
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
  UpdateProcessLabel();
}

void App::UpdateProcessLabel() {
  std::string label;
  if (controllers_.size() < 2) {
    label = base_label_;
  } else {
    std::string suffix = " (+" + std::to_string(controllers_.size() - 1) + ")";
    if (base_label_.size() + suffix.size() <= MX_MAX_NAME_LEN - 1) {
      label = base_label_ + suffix;
    } else {
      label = base_label_.substr(0, MX_MAX_NAME_LEN - 1 - suffix.size() - 3) +
              "..." + suffix;
    }
  }
  mx::process::self().set_property(MX_PROP_NAME, label.c_str(), label.size());
A
Adam Barth 已提交
166 167 168
}

}  // namespace flutter_runner