// 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/embedder/main.h"

#include "base/allocator/features.h"
#include "base/at_exit.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/debug/activity_tracker.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/process/launch.h"
#include "base/process/memory.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/task_scheduler/task_scheduler.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread.h"
#include "base/trace_event/trace_config.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
#include "components/tracing/common/trace_to_console.h"
#include "components/tracing/common/tracing_switches.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/scoped_ipc_support.h"
#include "services/service_manager/embedder/main_delegate.h"
#include "services/service_manager/embedder/process_type.h"
#include "services/service_manager/embedder/set_process_title.h"
#include "services/service_manager/embedder/shared_file_util.h"
#include "services/service_manager/embedder/switches.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_context.h"
#include "services/service_manager/public/cpp/standalone_service/standalone_service.h"
#include "services/service_manager/runner/common/client_util.h"
#include "services/service_manager/runner/common/switches.h"
#include "services/service_manager/runner/init.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"

#if defined(OS_WIN)
#include <windows.h>

#include "base/win/process_startup_helper.h"
#include "ui/base/win/atl_module.h"
#endif

#if defined(OS_POSIX) && !defined(OS_ANDROID)
#include <locale.h>
#include <signal.h>

#include "base/file_descriptor_store.h"
#include "base/posix/global_descriptors.h"
#endif

#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#include "services/service_manager/embedder/mac_init.h"

#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
#include "base/allocator/allocator_shim.h"
#endif
#endif  // defined(OS_MACOSX)

namespace service_manager {

namespace {

// Maximum message size allowed to be read from a Mojo message pipe in any
// service manager embedder process.
constexpr size_t kMaximumMojoMessageSize = 128 * 1024 * 1024;

class ServiceProcessLauncherDelegateImpl
    : public service_manager::ServiceProcessLauncher::Delegate {
 public:
  explicit ServiceProcessLauncherDelegateImpl(MainDelegate* main_delegate)
      : main_delegate_(main_delegate) {}
  ~ServiceProcessLauncherDelegateImpl() override {}

 private:
  // service_manager::ServiceProcessLauncher::Delegate:
  void AdjustCommandLineArgumentsForTarget(
      const service_manager::Identity& target,
      base::CommandLine* command_line) override {
    if (main_delegate_->ShouldLaunchAsServiceProcess(target)) {
      command_line->AppendSwitchASCII(switches::kProcessType,
                                      switches::kProcessTypeService);
#if defined(OS_WIN)
      command_line->AppendArg(switches::kDefaultServicePrefetchArgument);
#endif
    }

    main_delegate_->AdjustServiceProcessCommandLine(target, command_line);
  }

  MainDelegate* const main_delegate_;

  DISALLOW_COPY_AND_ASSIGN(ServiceProcessLauncherDelegateImpl);
};

#if defined(OS_POSIX) && !defined(OS_ANDROID)

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  // Sanitise our signal handling state. Signals that were ignored by our
  // parent will also be ignored by us. We also inherit our parent's sigmask.
  sigset_t empty_signal_set;
  CHECK_EQ(0, sigemptyset(&empty_signal_set));
  CHECK_EQ(0, sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] = {
      SIGHUP,  SIGINT,  SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
      SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
    CHECK_EQ(0, sigaction(signals_to_reset[i], &sigact, NULL));
  }

  // Always ignore SIGPIPE.  We check the return value of write().
  CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
}

void PopulateFDsFromCommandLine() {
  const std::string& shared_file_param =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kSharedFiles);
  if (shared_file_param.empty())
    return;

  base::Optional<std::map<int, std::string>> shared_file_descriptors =
      service_manager::ParseSharedFileSwitchValue(shared_file_param);
  if (!shared_file_descriptors)
    return;

  for (const auto& descriptor : *shared_file_descriptors) {
    base::MemoryMappedFile::Region region;
    const std::string& key = descriptor.second;
    base::ScopedFD fd = base::GlobalDescriptors::GetInstance()->TakeFD(
        descriptor.first, &region);
    base::FileDescriptorStore::GetInstance().Set(key, std::move(fd), region);
  }
}

#endif  // defined(OS_POSIX) && !defined(OS_ANDROID)

void CommonSubprocessInit() {
#if defined(OS_WIN)
  // HACK: Let Windows know that we have started.  This is needed to suppress
  // the IDC_APPSTARTING cursor from being displayed for a prolonged period
  // while a subprocess is starting.
  PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
  MSG msg;
  PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
#endif
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
  // Various things break when you're using a locale where the decimal
  // separator isn't a period.  See e.g. bugs 22782 and 39964.  For
  // all processes except the browser process (where we call system
  // APIs that may rely on the correct locale for formatting numbers
  // when presenting them to the user), reset the locale for numeric
  // formatting.
  // Note that this is not correct for plugin processes -- they can
  // surface UI -- but it's likely they get this wrong too so why not.
  setlocale(LC_NUMERIC, "C");
#endif

#if !defined(OFFICIAL_BUILD) && defined(OS_WIN)
  base::RouteStdioToConsole(false);
  LoadLibraryA("dbghelp.dll");
#endif
}

void NonEmbedderProcessInit() {
  service_manager::InitializeLogging();

#if !defined(OFFICIAL_BUILD)
  // Initialize stack dumping before initializing sandbox to make sure symbol
  // names in all loaded libraries will be cached.
  // NOTE: On Chrome OS, crash reporting for the root process and non-browser
  // service processes is handled by the OS-level crash_reporter.
  base::debug::EnableInProcessStackDumping();
#endif

  base::TaskScheduler::CreateAndStartWithDefaultParams("ServiceManagerProcess");
}

void WaitForDebuggerIfNecessary() {
  if (!ServiceManagerIsRemote())
    return;

  const auto& command_line = *base::CommandLine::ForCurrentProcess();
  const std::string service_name =
      command_line.GetSwitchValueASCII(switches::kServiceName);
  if (service_name !=
      command_line.GetSwitchValueASCII(::switches::kWaitForDebugger)) {
    return;
  }

  // Include the pid as logging may not have been initialized yet (the pid
  // printed out by logging is wrong).
  LOG(WARNING) << "waiting for debugger to attach for service " << service_name
               << " pid=" << base::Process::Current().Pid();
  base::debug::WaitForDebugger(120, true);
}

// Quits |run_loop| if the |identity| of the quitting service is critical to the
// system (e.g. the window manager). Used in the main process.
void OnInstanceQuit(MainDelegate* delegate,
                    base::RunLoop* run_loop,
                    int* exit_code,
                    const service_manager::Identity& identity) {
  if (delegate->ShouldTerminateServiceManagerOnInstanceQuit(identity,
                                                            exit_code)) {
    run_loop->Quit();
  }
}

int RunServiceManager(MainDelegate* delegate) {
  NonEmbedderProcessInit();

#if defined(OS_WIN)
  // Route stdio to parent console (if any) or create one.
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableLogging)) {
    base::RouteStdioToConsole(true);
  }
#endif

  base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);

  base::SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess();

  base::Thread ipc_thread("IPC thread");
  ipc_thread.StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
  mojo::edk::ScopedIPCSupport ipc_support(
      ipc_thread.task_runner(),
      mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST);

  ServiceProcessLauncherDelegateImpl service_process_launcher_delegate(
      delegate);
  service_manager::BackgroundServiceManager background_service_manager(
      &service_process_launcher_delegate, delegate->CreateServiceCatalog());

  base::RunLoop run_loop;
  int exit_code = 0;
  background_service_manager.SetInstanceQuitCallback(
      base::Bind(&OnInstanceQuit, delegate, &run_loop, &exit_code));

  delegate->OnServiceManagerInitialized(run_loop.QuitClosure(),
                                        &background_service_manager);
  run_loop.Run();

  ipc_thread.Stop();
  base::TaskScheduler::GetInstance()->Shutdown();

  return exit_code;
}

void InitializeResources() {
  const std::string locale =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          ::switches::kLang);
  // This loads the embedder's common resources (e.g. chrome_100_percent.pak for
  // Chrome.)
  ui::ResourceBundle::InitSharedInstanceWithLocale(
      locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
}

int RunService(MainDelegate* delegate) {
  NonEmbedderProcessInit();
  WaitForDebuggerIfNecessary();

  InitializeResources();

  int exit_code = 0;
  RunStandaloneService(base::Bind(
      [](MainDelegate* delegate, int* exit_code,
         mojom::ServiceRequest request) {
        // TODO(rockot): Make the default MessageLoop type overridable for
        // services. This is TYPE_UI because at least one service (the "ui"
        // service) needs it to be.
        base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
        base::RunLoop run_loop;

        std::string service_name =
            base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
                switches::kServiceName);
        if (service_name.empty()) {
          LOG(ERROR) << "Service process requires --service-name";
          *exit_code = 1;
          return;
        }

        std::unique_ptr<Service> service =
            delegate->CreateEmbeddedService(service_name);
        if (!service) {
          LOG(ERROR) << "Failed to start embedded service: " << service_name;
          *exit_code = 1;
          return;
        }

        ServiceContext context(std::move(service), std::move(request));
        context.SetQuitClosure(run_loop.QuitClosure());
        run_loop.Run();
      },
      delegate, &exit_code));

  return exit_code;
}

}  // namespace

MainParams::MainParams(MainDelegate* delegate) : delegate(delegate) {}

MainParams::~MainParams() {}

int Main(const MainParams& params) {
  MainDelegate* delegate = params.delegate;
  DCHECK(delegate);

#if defined(OS_MACOSX) && BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
  base::allocator::InitializeAllocatorShim();
#endif
  base::EnableTerminationOnOutOfMemory();

#if defined(OS_WIN)
  base::win::RegisterInvalidParamHandler();
  ui::win::CreateATLModuleIfNeeded();
#endif  // defined(OS_WIN)

// On Android setlocale() is not supported, and we don't override the signal
// handlers so we can get a stack trace when crashing.
#if defined(OS_POSIX) && !defined(OS_ANDROID)
  // Set C library locale to make sure CommandLine can parse argument values in
  // the correct encoding.
  setlocale(LC_ALL, "");

  SetupSignalHandlers();
#endif

#if !defined(OS_ANDROID)
  // On Android, the command line is initialized when library is loaded.
  int argc = 0;
  const char** argv = nullptr;

#if defined(OS_POSIX)
  // argc/argv are ignored on Windows; see command_line.h for details.
  argc = params.argc;
  argv = params.argv;
#endif

  base::CommandLine::Init(argc, argv);

#if defined(OS_POSIX)
  PopulateFDsFromCommandLine();
#endif

  base::EnableTerminationOnHeapCorruption();

  SetProcessTitleFromCommandLine(argv);
#endif  // !defined(OS_ANDROID)

  const auto& command_line = *base::CommandLine::ForCurrentProcess();

#if defined(OS_WIN)
  base::win::SetupCRT(command_line);
#endif

  MainDelegate::InitializeParams init_params;

#if defined(OS_MACOSX)
  // We need this pool for all the objects created before we get to the event
  // loop, but we don't want to leave them hanging around until the app quits.
  // Each "main" needs to flush this pool right before it goes into its main
  // event loop to get rid of the cruft.
  std::unique_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool =
      base::MakeUnique<base::mac::ScopedNSAutoreleasePool>();
  init_params.autorelease_pool = autorelease_pool.get();
  InitializeMac();
#endif

  mojo::edk::SetMaxMessageSize(kMaximumMojoMessageSize);
  mojo::edk::Init();

  ui::RegisterPathProvider();

  base::debug::GlobalActivityTracker* tracker =
      base::debug::GlobalActivityTracker::Get();
  int exit_code = delegate->Initialize(init_params);
  if (exit_code >= 0) {
    if (tracker) {
      tracker->SetProcessPhase(
          base::debug::GlobalActivityTracker::PROCESS_LAUNCH_FAILED);
      tracker->process_data().SetInt("exit-code", exit_code);
    }
    return exit_code;
  }

  ProcessType process_type = delegate->OverrideProcessType();
  if (process_type == ProcessType::kDefault) {
    std::string type_switch =
        command_line.GetSwitchValueASCII(switches::kProcessType);
    if (type_switch == switches::kProcessTypeServiceManager) {
      process_type = ProcessType::kServiceManager;
    } else if (type_switch == switches::kProcessTypeService) {
      process_type = ProcessType::kService;
    } else {
      process_type = ProcessType::kEmbedder;
    }
  }

  base::Optional<base::AtExitManager> at_exit;

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          ::switches::kTraceToConsole)) {
    base::trace_event::TraceConfig trace_config =
        tracing::GetConfigForTraceToConsole();
    base::trace_event::TraceLog::GetInstance()->SetEnabled(
        trace_config, base::trace_event::TraceLog::RECORDING_MODE);
  }

  switch (process_type) {
    case ProcessType::kDefault:
      NOTREACHED();
      break;

    case ProcessType::kServiceManager:
      at_exit.emplace();
      exit_code = RunServiceManager(delegate);
      break;

    case ProcessType::kService:
      CommonSubprocessInit();
      at_exit.emplace();
      exit_code = RunService(delegate);
      break;

    case ProcessType::kEmbedder:
      if (ServiceManagerIsRemote())
        CommonSubprocessInit();
      exit_code = delegate->RunEmbedderProcess();
      break;
  }

  if (tracker) {
    if (exit_code == 0) {
      tracker->SetProcessPhaseIfEnabled(
          base::debug::GlobalActivityTracker::PROCESS_EXITED_CLEANLY);
    } else {
      tracker->SetProcessPhaseIfEnabled(
          base::debug::GlobalActivityTracker::PROCESS_EXITED_WITH_CODE);
      tracker->process_data().SetInt("exit-code", exit_code);
    }
  }

#if defined(OS_MACOSX)
  autorelease_pool.reset();
#endif

  if (process_type == ProcessType::kEmbedder)
    delegate->ShutDownEmbedderProcess();

  return exit_code;
}

}  // namespace service_manager
