// 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/buildflags.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/message_loop/message_loop.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/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/core/embedder/configuration.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/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_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::ServiceProcessLauncherDelegate {
 public:
  explicit ServiceProcessLauncherDelegateImpl(MainDelegate* main_delegate)
      : main_delegate_(main_delegate) {}
  ~ServiceProcessLauncherDelegateImpl() override {}

 private:
  // service_manager::ServiceProcessLauncherDelegate:
  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) && !defined(OS_FUCHSIA)

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableInProcessStackTraces)) {
    // Don't interfere with sanitizer signal handlers.
    return;
  }

  // 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) && !defined(OS_FUCHSIA)

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_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.
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableInProcessStackTraces)) {
    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);
}

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

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

  base::Thread ipc_thread("IPC thread");
  ipc_thread.StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
  mojo::core::ScopedIPCSupport ipc_support(
      ipc_thread.task_runner(),
      mojo::core::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;
  delegate->OnServiceManagerInitialized(run_loop.QuitClosure(),
                                        &background_service_manager);
  run_loop.Run();

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

  return 0;
}

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);

  int exit_code = -1;
  base::debug::GlobalActivityTracker* tracker = nullptr;
  ProcessType process_type = delegate->OverrideProcessType();
#if defined(OS_MACOSX)
  std::unique_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool;
#endif

  // A flag to indicate whether Main() has been called before. On Android, we
  // may re-run Main() without restarting the browser process. This flag
  // prevents initializing things more than once.
  static bool is_initialized = false;
#if !defined(OS_ANDROID)
  DCHECK(!is_initialized);
#endif
  if (!is_initialized) {
    is_initialized = true;
#if defined(OS_MACOSX) && BUILDFLAG(USE_ALLOCATOR_SHIM)
    base::allocator::InitializeAllocatorShim();
#endif
    base::EnableTerminationOnOutOfMemory();

#if defined(OS_LINUX)
    // The various desktop environments set this environment variable that
    // allows the dbus client library to connect directly to the bus. When this
    // variable is not set (test environments like xvfb-run), the dbus client
    // library will fall back to auto-launch mode. Auto-launch is dangerous as
    // it can cause hangs (crbug.com/715658) . This one line disables the dbus
    // auto-launch, by clobbering the DBUS_SESSION_BUS_ADDRESS env variable if
    // not already set. The old auto-launch behavior, if needed, can be restored
    // by setting DBUS_SESSION_BUS_ADDRESS="autolaunch:" before launching
    // chrome.
    const int kNoOverrideIfAlreadySet = 0;
    setenv("DBUS_SESSION_BUS_ADDRESS", "disabled:", kNoOverrideIfAlreadySet);
#endif

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

#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_WIN)
    // 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)

// 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) && !defined(OS_FUCHSIA)
    // Set C library locale to make sure CommandLine can parse argument values
    // in the correct encoding.
    setlocale(LC_ALL, "");

    SetupSignalHandlers();
#endif

    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.
    autorelease_pool = std::make_unique<base::mac::ScopedNSAutoreleasePool>();
    init_params.autorelease_pool = autorelease_pool.get();
    InitializeMac();
#endif

    mojo::core::Configuration mojo_config;
    if (process_type == ProcessType::kDefault &&
        command_line.GetSwitchValueASCII(switches::kProcessType) ==
            switches::kProcessTypeServiceManager) {
      mojo_config.is_broker_process = true;
    }
    mojo_config.max_message_num_bytes = kMaximumMojoMessageSize;
    delegate->OverrideMojoConfiguration(&mojo_config);
    mojo::core::Init(mojo_config);

    ui::RegisterPathProvider();

    tracker = base::debug::GlobalActivityTracker::Get();
    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;
    }

#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

    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);
    }
  }

  const auto& command_line = *base::CommandLine::ForCurrentProcess();
  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;
    }
  }
  switch (process_type) {
    case ProcessType::kDefault:
      NOTREACHED();
      break;

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

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

    case ProcessType::kEmbedder:
      if (delegate->IsEmbedderSubprocess())
        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
