// Copyright 2017 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 "services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.h"

#include <lib/fdio/spawn.h>
#include <stdio.h>
#include <zircon/processargs.h>

#include <fuchsia/fonts/cpp/fidl.h>
#include <fuchsia/mediacodec/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <memory>
#include <utility>

#include "base/base_paths_fuchsia.h"
#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/files/file_util.h"
#include "base/fuchsia/component_context.h"
#include "base/fuchsia/filtered_service_directory.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/threading/thread_task_runner_handle.h"
#include "services/service_manager/sandbox/switches.h"

namespace service_manager {
namespace {

constexpr const char* const kRendererServices[] = {
    fuchsia::fonts::Provider::Name_, fuchsia::mediacodec::CodecFactory::Name_};

constexpr const char* const kGpuServices[] = {
    fuchsia::ui::scenic::Scenic::Name_};

base::span<const char* const> GetServicesListForSandboxType(
    service_manager::SandboxType type) {
  switch (type) {
    case service_manager::SANDBOX_TYPE_RENDERER:
      return base::make_span(kRendererServices);
    case service_manager::SANDBOX_TYPE_GPU:
      return base::make_span(kGpuServices);
    default:
      return base::span<const char* const>();
  }
}

}  // namespace

SandboxPolicyFuchsia::SandboxPolicyFuchsia() = default;

SandboxPolicyFuchsia::~SandboxPolicyFuchsia() {
  if (service_directory_) {
    service_directory_task_runner_->DeleteSoon(FROM_HERE,
                                               std::move(service_directory_));
  }
}

void SandboxPolicyFuchsia::Initialize(service_manager::SandboxType type) {
  DCHECK_NE(type, service_manager::SANDBOX_TYPE_INVALID);
  DCHECK_EQ(type_, service_manager::SANDBOX_TYPE_INVALID);

  type_ = type;

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          service_manager::switches::kNoSandbox)) {
    type_ = service_manager::SANDBOX_TYPE_NO_SANDBOX;
  }

  // If we need to pass some services for the given sandbox type then create
  // |sandbox_directory_| and initialize it with the corresponding list of
  // services. FilteredServiceDirectory must be initialized on a thread that has
  // async_dispatcher.
  auto services_list = GetServicesListForSandboxType(type_);
  if (!services_list.empty()) {
    service_directory_task_runner_ = base::ThreadTaskRunnerHandle::Get();
    service_directory_ =
        std::make_unique<base::fuchsia::FilteredServiceDirectory>(
            base::fuchsia::ComponentContext::GetDefault());
    for (const char* service_name : services_list)
      service_directory_->AddService(service_name);

    // Bind the service directory and store the client channel for
    // UpdateLaunchOptionsForSandbox()'s use.
    service_directory_client_channel_ = service_directory_->ConnectClient();
    CHECK(service_directory_client_channel_);
  }
}

void SandboxPolicyFuchsia::UpdateLaunchOptionsForSandbox(
    base::LaunchOptions* options) {
  DCHECK_NE(type_, service_manager::SANDBOX_TYPE_INVALID);

  // Always clone stderr to get logs output.
  options->fds_to_remap.push_back(std::make_pair(STDERR_FILENO, STDERR_FILENO));

  if (type_ == service_manager::SANDBOX_TYPE_NO_SANDBOX) {
    options->spawn_flags = FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_JOB;
    options->clear_environ = false;
    return;
  }

  // Map /pkg (read-only files deployed from the package) into the child's
  // namespace.
  base::FilePath package_root;
  base::PathService::Get(base::DIR_SOURCE_ROOT, &package_root);
  options->paths_to_clone.push_back(package_root);

  // Clear environmental variables to better isolate the child from
  // this process.
  options->clear_environ = true;

  // Don't clone anything by default.
  options->spawn_flags = 0;

  if (service_directory_) {
    // Provide the child process with a restricted set of services.
    options->paths_to_transfer.push_back(base::PathToTransfer{
        base::FilePath("/svc"), service_directory_client_channel_.release()});
  }
}

}  // namespace service_manager
