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
    : app_(app), binding_(this) {
26
  if (controller.is_valid()) {
A
Adam Barth 已提交
27
    binding_.Bind(std::move(controller));
28
    binding_.set_error_handler([this] {
A
Adam Barth 已提交
29 30 31 32 33 34
      app_->Destroy(this);
      // |this| has been deleted at this point.
    });
  }

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

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

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

50 51 52 53 54 55 56
  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) {
57 58
        view_provider_bindings_.AddBinding(this, std::move(request));
      });
59 60 61 62 63

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

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

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

ApplicationControllerImpl::~ApplicationControllerImpl() = default;

79 80
constexpr char kServiceRootPath[] = "/svc";

81
fdio_ns_t* ApplicationControllerImpl::SetupNamespace(
82
    const app::FlatNamespacePtr& flat) {
83 84 85
  fdio_ns_t* fdio_namespc;
  zx_status_t status = fdio_ns_create(&fdio_namespc);
  if (status != ZX_OK) {
86
    FXL_LOG(ERROR) << "Failed to create namespace";
87 88 89 90 91 92 93
    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;
    }
94 95
    zx::channel dir = std::move(flat->directories[i]);
    zx_handle_t dir_handle = dir.release();
96
    const char* path = flat->paths[i].data();
97 98
    status = fdio_ns_bind(fdio_namespc, path, dir_handle);
    if (status != ZX_OK) {
99
      FXL_LOG(ERROR) << "Failed to bind " << flat->paths[i] << " to namespace";
100 101
      zx_handle_close(dir_handle);
      fdio_ns_destroy(fdio_namespc);
102 103 104
      return nullptr;
    }
  }
105
  return fdio_namespc;
106 107
}

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

void ApplicationControllerImpl::Detach() {
116
  binding_.set_error_handler(fxl::Closure());
A
Adam Barth 已提交
117 118
}

119 120 121 122 123 124 125 126 127 128 129
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 已提交
130 131
void ApplicationControllerImpl::CreateView(
    fidl::InterfaceRequest<mozart::ViewOwner> view_owner_request,
132
    fidl::InterfaceRequest<app::ServiceProvider> services) {
A
Adam Barth 已提交
133 134 135 136
  runtime_holder_->CreateView(url_, std::move(view_owner_request),
                              std::move(services));
}

137 138 139 140 141 142 143 144 145 146 147 148 149
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 已提交
150
}  // namespace flutter_runner