application_controller_impl.cc 4.5 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 11
#include <magenta/status.h>
#include <mxio/namespace.h>

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;
G
George Kulakowski 已提交
35
  if (!fsl::VectorFromVmo(std::move(application->data), &bundle)) {
36
    FXL_LOG(ERROR) << "Failed to receive bundle.";
A
Adam Barth 已提交
37 38 39
    return;
  }

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
  mxio_ns_t* mxio_ns = SetupNamespace(startup_info->flat_namespace);
  if (mxio_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_->Init(
70
      mxio_ns, app::ApplicationContext::CreateFrom(std::move(startup_info)),
71
      std::move(request), std::move(bundle));
A
Adam Barth 已提交
72 73 74 75
}

ApplicationControllerImpl::~ApplicationControllerImpl() = default;

76 77 78 79 80 81 82
constexpr char kServiceRootPath[] = "/svc";

mxio_ns_t* ApplicationControllerImpl::SetupNamespace(
    const app::FlatNamespacePtr& flat) {
  mxio_ns_t* mxio_namespc;
  mx_status_t status = mxio_ns_create(&mxio_namespc);
  if (status != MX_OK) {
83
    FXL_LOG(ERROR) << "Failed to create namespace";
84 85 86 87 88 89 90 91 92 93 94 95
    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;
    }
    mx::channel dir = std::move(flat->directories[i]);
    mx_handle_t dir_handle = dir.release();
    const char* path = flat->paths[i].data();
    status = mxio_ns_bind(mxio_namespc, path, dir_handle);
    if (status != MX_OK) {
96
      FXL_LOG(ERROR) << "Failed to bind " << flat->paths[i] << " to namespace";
97 98 99 100 101 102 103 104
      mx_handle_close(dir_handle);
      mxio_ns_destroy(mxio_namespc);
      return nullptr;
    }
  }
  return mxio_namespc;
}

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

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

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

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