// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/tracing/startup_tracing_controller.h"

#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/thread_annotations.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/tracing/public/cpp/perfetto/perfetto_config.h"
#include "services/tracing/public/cpp/perfetto/trace_packet_tokenizer.h"
#include "services/tracing/public/cpp/trace_startup_config.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h"
#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h"
#include "third_party/perfetto/include/perfetto/tracing/tracing.h"

#if BUILDFLAG(IS_ANDROID)
#include "content/browser/android/tracing_controller_android.h"
#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_IOS)
#include "base/apple/foundation_util.h"
#endif  // BUILDFLAG(IS_IOS)

namespace content {

// A helper class responsible for coordinating emergency trace finalisation
// (e.g. when the process is about to be killed), which can be initiated from
// any thread.
class EmergencyTraceFinalisationCoordinator {
 public:
  static EmergencyTraceFinalisationCoordinator& GetInstance() {
    static base::NoDestructor<EmergencyTraceFinalisationCoordinator> g_instance;
    return *g_instance;
  }

  void OnTracingStarted(scoped_refptr<base::SequencedTaskRunner> task_runner,
                        base::OnceClosure stop_tracing) {
    tracing_started_.Set();
    base::AutoLock lock(lock_);
    startup_tracing_controller_task_runner_ = std::move(task_runner);
    stop_tracing_ = std::move(stop_tracing);
  }

  void OnTracingStopped() { finalisation_.Signal(); }

  // May be called multiple times per session, e.g. if a second thread
  // encounters a crash after the first.
  void StopAndBlockUntilStopped() {
    // If DCHECK fires before tracing has started, there isn't much for us to
    // do.
    if (!tracing_started_.IsSet())
      return;

    base::OnceClosure stop_tracing;
    scoped_refptr<base::SequencedTaskRunner> task_runner;
    {
      base::AutoLock lock(lock_);
      task_runner = startup_tracing_controller_task_runner_;
      stop_tracing = std::move(stop_tracing_);
    }

    if (task_runner->RunsTasksInCurrentSequence()) {
      VLOG(0) << "Ignored an emergency tracing stop request from the "
                 "StartupTracingController sequence";
      return;
    }

    if (stop_tracing)
      task_runner->PostTask(FROM_HERE, std::move(stop_tracing));

    base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;

    // Wait for the tracing to be finished before processing.
    // Note that we should wait even if |stop_tracing| is null — if a second
    // thread hits DCHECK while the first has posted a task and waits for the
    // trace to be written, the second one should wait as well to avoid crashing
    // the process.
    finalisation_.Wait();
  }

 private:
  base::WaitableEvent finalisation_;
  base::AtomicFlag tracing_started_;

  base::Lock lock_;
  scoped_refptr<base::SequencedTaskRunner>
      startup_tracing_controller_task_runner_ GUARDED_BY(lock_);
  base::OnceClosure stop_tracing_ GUARDED_BY(lock_);
};

class StartupTracingController::BackgroundTracer {
 public:
  enum class WriteMode { kAfterStopping, kStreaming };

  BackgroundTracer(WriteMode write_mode,
                   TempFilePolicy temp_file_policy,
                   base::FilePath output_file,
                   tracing::TraceStartupConfig::OutputFormat output_format,
                   perfetto::TraceConfig trace_config,
                   base::OnceClosure on_tracing_finished)
      : state_(State::kTracing),
        write_mode_(write_mode),
        temp_file_policy_(temp_file_policy),
        task_runner_(base::SequencedTaskRunner::GetCurrentDefault()),
        output_file_(output_file),
        output_format_(output_format),
        on_tracing_finished_(std::move(on_tracing_finished)) {
    tracing_session_ =
        perfetto::Tracing::NewTrace(perfetto::BackendType::kCustomBackend);

    if (write_mode_ == WriteMode::kStreaming) {
#if !BUILDFLAG(IS_WIN)
      OpenFile(output_file_);
      tracing_session_->Setup(trace_config, file_.TakePlatformFile());
#else
      NOTREACHED() << "Streaming to file is not supported on Windows yet";
#endif
    } else {
      tracing_session_->Setup(trace_config);
    }

    // |StartBlocking| can take a non-trivial amount of time, so
    // EmergencyTraceFinalisationController should be set up before it to catch
    // DCHECKs early.
    EmergencyTraceFinalisationCoordinator::GetInstance().OnTracingStarted(
        task_runner_,
        base::BindOnce(&BackgroundTracer::Stop, weak_ptr_factory_.GetWeakPtr(),
                       std::nullopt));

    tracing_session_->SetOnStopCallback([&]() { OnTracingStopped(); });
    tracing_session_->StartBlocking();

    TRACE_EVENT("startup", "StartupTracingController::Start");
  }

  void Stop(std::optional<base::FilePath> output_file) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

    // Tracing might have already been finished due to a timeout.
    if (state_ != State::kTracing) {
      // Note: updating output files is not supported together with
      // timeout-based tracing.
      return;
    }
    state_ = State::kStopping;

    if (output_file)
      output_file_ = output_file.value();
    tracing_session_->StopBlocking();
  }

  void OnTracingStopped() {
    if (!task_runner_->RunsTasksInCurrentSequence()) {
      // The owner of BackgroundTracer is responsible for ensuring that
      // BackgroundTracer stays alive until |on_tracing_finished_| is called.
      task_runner_->PostTask(FROM_HERE,
                             base::BindOnce(&BackgroundTracer::OnTracingStopped,
                                            base::Unretained(this)));
      return;
    }

    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    // State will be kStopping if Stop() is called and kTracing if tracing
    // finishes due to a timeout.
    DCHECK(state_ == State::kStopping || state_ == State::kTracing);
    if (write_mode_ == WriteMode::kStreaming) {
      // No need to explicitly call ReadTrace as Perfetto has already written
      // the file.
      Finalise();
      return;
    }
    state_ = State::kWritingToFile;

    OpenFile(output_file_);

    // The owner of BackgroundTracer is responsible for ensuring that
    // BackgroundTracer stays alive until |on_tracing_finished_| is called.
    tracing_session_->ReadTrace(
        [this](perfetto::TracingSession::ReadTraceCallbackArgs args) {
          WriteData(args.data, args.size);

          if (args.has_more)
            return;

          Finalise();
        });
  }

 private:
  void WriteData(const char* data, size_t size) {
    // Last chunk can be empty.
    if (size == 0)
      return;

    // Proto files should be written directly to the file.
    if (output_format_ == tracing::TraceStartupConfig::OutputFormat::kProto) {
      UNSAFE_TODO(file_.WriteAtCurrentPos(data, size));
      return;
    }

    // For JSON, we need to extract raw data from the packet.
    if (!trace_packet_tokenizer_) {
      trace_packet_tokenizer_ =
          std::make_unique<tracing::TracePacketTokenizer>();
    }

    std::vector<perfetto::TracePacket> packets = trace_packet_tokenizer_->Parse(
        reinterpret_cast<const uint8_t*>(data), size);
    for (const auto& packet : packets) {
      for (const auto& slice : packet.slices()) {
        UNSAFE_TODO(file_.WriteAtCurrentPos(
            reinterpret_cast<const char*>(slice.start), slice.size));
      }
    }
  }

  // Open |file_| for writing and set |written_to_file_| accordingly.
  // In order to atomically commit the trace file, create a temporary file first
  // which then will be subsequently renamed.
  void OpenFile(const base::FilePath& path) {
    if (temp_file_policy_ == TempFilePolicy::kUseTemporaryFile) {
      file_ = base::CreateAndOpenTemporaryFileInDir(path.DirName(),
                                                    &written_to_file_);
      if (file_.IsValid())
        return;

      VLOG(1) << "Failed to create temporary file, using file '" << path
              << "' directly instead";
    }

    // On Android, it might not be possible to create a temporary file.
    // In that case, we should use the file directly.
    file_.Initialize(output_file_,
                     base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
    written_to_file_ = output_file_;

    if (!file_.IsValid())
      LOG(ERROR) << "Startup tracing failed: couldn't open file: " << path;
  }

  // Close the file and rename if needed.
  void Finalise() {
    DCHECK_NE(state_, State::kFinished);
    file_.Close();

    if (written_to_file_ != output_file_) {
      base::File::Error error;
      if (!base::ReplaceFile(written_to_file_, output_file_, &error)) {
        LOG(ERROR) << "Cannot move file '" << written_to_file_ << "' to '"
                   << output_file_
                   << "' : " << base::File::ErrorToString(error);
      } else {
        written_to_file_ = output_file_;
      }
    }

    VLOG(0) << "Completed startup tracing to " << written_to_file_;
    EmergencyTraceFinalisationCoordinator::GetInstance().OnTracingStopped();

    state_ = State::kFinished;
    std::move(on_tracing_finished_).Run();
  }

  enum class State {
    kTracing,
    kStopping,
    kWritingToFile,
    kFinished,
  };
  State state_;

  const WriteMode write_mode_;
  const TempFilePolicy temp_file_policy_;

  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  // Output file might be customised during the execution (e.g. test result
  // becomes available), which means that if Perfetto has already started
  // streaming the trace, the trace file should be renamed after trace
  // completes.
  base::FilePath output_file_;
  base::FilePath written_to_file_;

  base::File file_;

  const tracing::TraceStartupConfig::OutputFormat output_format_;

  // Tokenizer to extract the json data from the data received from the tracing
  // service.
  std::unique_ptr<tracing::TracePacketTokenizer> trace_packet_tokenizer_;

  base::OnceClosure on_tracing_finished_;

  std::unique_ptr<perfetto::TracingSession> tracing_session_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<BackgroundTracer> weak_ptr_factory_{this};
};

// static
StartupTracingController& StartupTracingController::GetInstance() {
  // Note: no DCHECK_CURRENTLY_ON, as it can be called prior to initialisation
  // of BrowserThreads.

  static base::NoDestructor<StartupTracingController> g_instance;
  return *g_instance;
}

namespace {

base::FilePath BasenameToPath(std::string basename) {
#if BUILDFLAG(IS_ANDROID)
  return TracingControllerAndroid::GenerateTracingFilePath(basename);
#elif BUILDFLAG(IS_IOS)
  // On iOS blink, write to the documents directory associated with the app.
  return base::apple::GetUserDocumentPath().AppendASCII(basename);
#else
  // Default to saving the startup trace into the current dir.
  return base::FilePath().AppendASCII(basename);
#endif
}

}  // namespace

StartupTracingController::StartupTracingController() = default;
StartupTracingController::~StartupTracingController() = default;

base::FilePath StartupTracingController::GetOutputPath() {
  auto* command_line = base::CommandLine::ForCurrentProcess();

  base::FilePath path_from_config =
      tracing::TraceStartupConfig::GetInstance().GetResultFile();
  if (!path_from_config.empty())
    return path_from_config;

  // If --trace-startup-file is specified, use it.
  if (command_line->HasSwitch(switches::kTraceStartupFile)) {
    base::FilePath result =
        command_line->GetSwitchValuePath(switches::kTraceStartupFile);
    if (result.empty())
      return BasenameToPath("chrometrace.log");
    return result;
  }

  base::FilePath result =
      command_line->GetSwitchValuePath(switches::kEnableTracingOutput);
  if (result.empty() && command_line->HasSwitch(switches::kTraceStartup)) {
    // If --trace-startup is present, return chrometrace.log for backwards
    // compatibility.
    return BasenameToPath("chrometrace.log");
  }

  // If a non-directory path is specified, use it.
  if (!result.empty() && !result.EndsWithSeparator())
    return result;

  std::string basename = default_basename_;
  if (basename.empty())
    basename = "chrometrace.log";

  // If a non-empty directory is specified, use it.
  if (!result.empty())
    return result.AppendASCII(basename);

  // If the directory is empty, go through BasenameToPath to generate a valid
  // path on Android.
  return BasenameToPath(basename);
}

void StartupTracingController::StartIfNeeded() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK_NE(state_, State::kRunning);

  auto& trace_startup_config = tracing::TraceStartupConfig::GetInstance();
  if (!trace_startup_config.AttemptAdoptBySessionOwner(
          tracing::TraceStartupConfig::SessionOwner::kTracingController)) {
    return;
  }

  state_ = State::kRunning;

  // Use USER_VISIBLE priority for the drainer because BEST_EFFORT tasks are not
  // run at startup and we want the trace file to be written soon.
  auto background_task_runner = base::ThreadPool::CreateSequencedTaskRunner(
      {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
       base::TaskShutdownBehavior::BLOCK_SHUTDOWN});

  auto output_format =
      tracing::TraceStartupConfig::GetInstance().GetOutputFormat();

  BackgroundTracer::WriteMode write_mode;
#if BUILDFLAG(IS_WIN)
  // TODO(crbug.com/1158482/): Perfetto does not (yet) support writing directly
  // to a file on Windows.
  write_mode = BackgroundTracer::WriteMode::kAfterStopping;
#else
  // Only protos can be incrementally written to a file - legacy json needs to
  // go through an additional conversion step after, which requires the entire
  // trace to be available.
  write_mode =
      output_format == tracing::TraceStartupConfig::OutputFormat::kProto
          ? BackgroundTracer::WriteMode::kStreaming
          : BackgroundTracer::WriteMode::kAfterStopping;
#endif

  auto perfetto_config =
      tracing::TraceStartupConfig::GetInstance().GetPerfettoConfig();

  background_tracer_ = base::SequenceBound<BackgroundTracer>(
      std::move(background_task_runner), write_mode, temp_file_policy_,
      GetOutputPath(), output_format, perfetto_config,
      base::BindOnce(
          [](StartupTracingController* controller) {
            GetUIThreadTaskRunner({})->PostTask(
                FROM_HERE,
                base::BindOnce(&StartupTracingController::OnStoppedOnUIThread,
                               base::Unretained(controller)));
          },
          this));
}

void StartupTracingController::Stop(base::OnceClosure on_tracing_finished) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (state_ != State::kRunning) {
    // Both kStopped and kNotRunning are valid states.
    std::move(on_tracing_finished).Run();
    return;
  }

  DCHECK(!on_tracing_finished_) << "Stop() should be called only once.";
  on_tracing_finished_ = std::move(on_tracing_finished);

  background_tracer_.AsyncCall(&BackgroundTracer::Stop)
      .WithArgs(GetOutputPath());
}

void StartupTracingController::OnStoppedOnUIThread() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK_EQ(state_, State::kRunning);
  state_ = State::kStopped;
  background_tracer_.Reset();

  if (on_tracing_finished_)
    std::move(on_tracing_finished_).Run();

  tracing::TraceStartupConfig::GetInstance().SetDisabled();
}

void StartupTracingController::SetUsingTemporaryFile(
    StartupTracingController::TempFilePolicy temp_file_policy) {
  DCHECK_EQ(state_, State::kNotEnabled) << "Should be called before Start()";
  temp_file_policy_ = temp_file_policy;
}

void StartupTracingController::SetDefaultBasename(
    std::string basename,
    ExtensionType extension_type) {
  if (!tracing::TraceStartupConfig::GetInstance().IsEnabled()) {
    return;
  }

  if (basename_for_test_set_)
    return;

  if (extension_type == ExtensionType::kAppendAppropriate) {
    switch (tracing::TraceStartupConfig::GetInstance().GetOutputFormat()) {
      case tracing::TraceStartupConfig::OutputFormat::kLegacyJSON:
        basename += ".json";
        break;
      case tracing::TraceStartupConfig::OutputFormat::kProto:
        basename += ".pftrace";
        break;
    }
  }
  default_basename_ = basename;
}

void StartupTracingController::SetDefaultBasenameForTest(
    std::string basename,
    ExtensionType extension_type) {
  basename_for_test_set_ = false;
  SetDefaultBasename(basename, extension_type);
  basename_for_test_set_ = true;
}

void StartupTracingController::WaitUntilStopped() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  base::RunLoop run_loop;
  Stop(run_loop.QuitClosure());
  run_loop.Run();
}

void StartupTracingController::ShutdownAndWaitForStopIfNeeded() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (should_continue_on_shutdown_)
    return;

  WaitUntilStopped();
}

// static
void StartupTracingController::EmergencyStop() {
  if (GetIOThreadTaskRunner({})->RunsTasksInCurrentSequence()) {
    VLOG(0) << "Emergency tracing stop request from IO thread is ignored - not "
               "possible to finalise trace without running tasks on IO thread";
    return;
  }

  EmergencyTraceFinalisationCoordinator::GetInstance()
      .StopAndBlockUntilStopped();
}

}  // namespace content
