application_controller_impl.cc 4.6 KB
Newer Older
A
Adam Barth 已提交
1 2 3 4 5 6 7 8
// 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/application_controller_impl.h"

#include <utility>

9 10
#include <fdio/namespace.h>
#include <zircon/status.h>
11

A
Adam Barth 已提交
12 13
#include "flutter/content_handler/app.h"
#include "flutter/content_handler/runtime_holder.h"
14
#include "lib/app/cpp/connect.h"
G
George Kulakowski 已提交
15
#include "lib/fsl/vmo/vector.h"
16
#include "lib/fxl/logging.h"
A
Adam Barth 已提交
17 18 19 20 21

namespace flutter_runner {

ApplicationControllerImpl::ApplicationControllerImpl(
    App* app,
22 23 24
    app::ApplicationPackagePtr application,
    app::ApplicationStartupInfoPtr startup_info,
    fidl::InterfaceRequest<app::ApplicationController> controller)
A
Adam Barth 已提交
25 26 27 28 29 30 31 32 33 34
    : app_(app), binding_(this) {
  if (controller.is_pending()) {
    binding_.Bind(std::move(controller));
    binding_.set_connection_error_handler([this] {
      app_->Destroy(this);
      // |this| has been deleted at this point.
    });
  }

  std::vector<char> bundle;
35 36 37
  if (!fsl::VectorFromVmo(std::move(application->data), &bundle)) {
    FXL_LOG(ERROR) << "Failed to receive bundle.";
    return;
A
Adam Barth 已提交
38 39
  }

40 41 42 43
  // TODO(jeffbrown): Decide what to do with command-line arguments and
  // startup handles.

  if (startup_info->launch_info->services) {
44 45
    service_provider_bridge_.AddBinding(
        std::move(startup_info->launch_info->services));
A
Adam Barth 已提交
46 47
  }

48 49 50 51 52 53 54
  if (startup_info->launch_info->service_request.is_valid()) {
    service_provider_bridge_.ServeDirectory(
        std::move(startup_info->launch_info->service_request));
  }

  service_provider_bridge_.AddService<mozart::ViewProvider>(
      [this](fidl::InterfaceRequest<mozart::ViewProvider> request) {
55 56
        view_provider_bindings_.AddBinding(this, std::move(request));
      });
57 58 59 60 61

  app::ServiceProviderPtr service_provider;
  auto request = service_provider.NewRequest();
  service_provider_bridge_.set_backend(std::move(service_provider));

62 63
  fdio_ns_t* fdio_ns = SetupNamespace(startup_info->flat_namespace);
  if (fdio_ns == nullptr) {
64
    FXL_LOG(ERROR) << "Failed to initialize namespace";
65 66
  }

67
  url_ = startup_info->launch_info->url;
A
Adam Barth 已提交
68
  runtime_holder_.reset(new RuntimeHolder());
69
  runtime_holder_->SetMainIsolateShutdownCallback([this]() { Kill(); });
70
  runtime_holder_->Init(
71
      fdio_ns, app::ApplicationContext::CreateFrom(std::move(startup_info)),
72
      std::move(request), std::move(bundle));
A
Adam Barth 已提交
73 74 75 76
}

ApplicationControllerImpl::~ApplicationControllerImpl() = default;

77 78
constexpr char kServiceRootPath[] = "/svc";

79
fdio_ns_t* ApplicationControllerImpl::SetupNamespace(
80
    const app::FlatNamespacePtr& flat) {
81 82 83
  fdio_ns_t* fdio_namespc;
  zx_status_t status = fdio_ns_create(&fdio_namespc);
  if (status != ZX_OK) {
84
    FXL_LOG(ERROR) << "Failed to create namespace";
85 86 87 88 89 90 91
    return nullptr;
  }
  for (size_t i = 0; i < flat->paths.size(); ++i) {
    if (flat->paths[i] == kServiceRootPath) {
      // Ownership of /svc goes to the ApplicationContext created above.
      continue;
    }
92 93
    zx::channel dir = std::move(flat->directories[i]);
    zx_handle_t dir_handle = dir.release();
94
    const char* path = flat->paths[i].data();
95 96
    status = fdio_ns_bind(fdio_namespc, path, dir_handle);
    if (status != ZX_OK) {
97
      FXL_LOG(ERROR) << "Failed to bind " << flat->paths[i] << " to namespace";
98 99
      zx_handle_close(dir_handle);
      fdio_ns_destroy(fdio_namespc);
100 101 102
      return nullptr;
    }
  }
103
  return fdio_namespc;
104 105
}

106
void ApplicationControllerImpl::Kill() {
107
  SendReturnCode(runtime_holder_->return_code());
A
Adam Barth 已提交
108 109 110 111 112 113
  runtime_holder_.reset();
  app_->Destroy(this);
  // |this| has been deleted at this point.
}

void ApplicationControllerImpl::Detach() {
114
  binding_.set_connection_error_handler(fxl::Closure());
A
Adam Barth 已提交
115 116
}

117 118 119 120 121 122 123 124 125 126 127
void ApplicationControllerImpl::Wait(const WaitCallback& callback) {
  wait_callbacks_.push_back(callback);
}

void ApplicationControllerImpl::SendReturnCode(int32_t return_code) {
  for (const auto& iter : wait_callbacks_) {
    iter(return_code);
  }
  wait_callbacks_.clear();
}

A
Adam Barth 已提交
128 129
void ApplicationControllerImpl::CreateView(
    fidl::InterfaceRequest<mozart::ViewOwner> view_owner_request,
130
    fidl::InterfaceRequest<app::ServiceProvider> services) {
A
Adam Barth 已提交
131 132 133 134
  runtime_holder_->CreateView(url_, std::move(view_owner_request),
                              std::move(services));
}

135 136 137 138 139 140 141 142 143 144 145 146 147
Dart_Port ApplicationControllerImpl::GetUIIsolateMainPort() {
  if (!runtime_holder_)
    return ILLEGAL_PORT;
  return runtime_holder_->GetUIIsolateMainPort();
}

std::string ApplicationControllerImpl::GetUIIsolateName() {
  if (!runtime_holder_) {
    return "";
  }
  return runtime_holder_->GetUIIsolateName();
}

A
Adam Barth 已提交
148
}  // namespace flutter_runner