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

# TODO(crbug.com/40188745): Complete crash reporting integration on Fuchsia.
assert(!is_fuchsia)

import("//base/debug/debug.gni")
import("//components/gwp_asan/buildflags/buildflags.gni")
import("//arkweb/build/features/features.gni")

if (is_android) {
  import("//build/config/android/config.gni")
}

if (is_arkweb) {
  import("//arkweb/chromium_ext/chromium_ext.gni")
}

static_library("url_constants") {
  sources = [ "url_constants.h" ]

  if (is_chrome_branded && is_official_build) {
    sources += [ "internal/url_constants.cc" ]
  } else {
    sources += [ "url_constants.cc" ]
  }

  deps = [ "//build:branding_buildflags" ]
}

source_set("lib") {
  visibility = [ ":*" ]

  sources = [
    "crash_reporter_client.cc",
    "crash_reporter_client.h",
  ]

  deps = [
    "//base",
    "//build:branding_buildflags",
  ]
}

source_set("crashpad_handler_main") {
  sources = [ "crashpad_handler_main.cc" ]

  deps = [
    "//base:debugging_buildflags",
    "//components/gwp_asan/buildflags",
    "//third_party/crashpad/crashpad/handler",
  ]

  if (enable_gwp_asan) {
    deps += [ "//components/gwp_asan/crash_handler" ]
  }

  if (build_allocation_stack_trace_recorder) {
    # The allocation stack trace report will be included only if the
    # recorder was enabled.
    deps += [ "//components/allocation_recorder/crash_handler" ]
  }
}

static_library("app") {
  sources = [
    "client_upload_info.cc",
    "client_upload_info.h",
    "crash_export_thunks.h",
    "crash_switches.cc",
    "crash_switches.h",
    "crashpad.cc",
    "crashpad.h",
  ]

  if (is_castos) {
    sources += [
      "breakpad_linux.cc",
      "breakpad_linux.h",
      "breakpad_linux_impl.cc",
      "breakpad_linux_impl.h",
    ]
  }

  if (defined(arkweb_crashpad) && arkweb_crashpad) {
    sources += arkweb_components_crash_core_app_sources
  }

  defines = [ "CRASH_IMPLEMENTATION" ]

  public_deps = [ ":lib" ]
  deps = [
    "//base",
    "//build:branding_buildflags",
    "//build:chromeos_buildflags",
    "//components/crash/core/common:crash_key",
    "//content/public/common:content_descriptors",
    "//third_party/crashpad/crashpad/client",
    "//third_party/crashpad/crashpad/util",
  ]

  if (is_linux || is_chromeos) {
    sources += [ "crashpad_linux.cc" ]
    data_deps = [ ":chrome_crashpad_handler" ]
  }

  if (is_ios) {
    deps -= [ "//content/public/common:content_descriptors" ]
    deps += [ "//third_party/crashpad/crashpad/handler:common" ]
    public_deps += [ "//third_party/crashpad/crashpad/client" ]
  }

  if (is_android) {
    sources += [ "crashpad_android.cc" ]
    deps += [
      ":crashpad_handler_main",
      "//components/crash/android:package_paths_jni",
      "//third_party/crashpad/crashpad/handler",
      "//third_party/crashpad/crashpad/snapshot",
    ]
    libs = [ "log" ]
  }

  if (is_android || is_linux || is_chromeos || is_ohos) {
    deps += [
      "//base:base_static",
      "//components/crash/core/common",
      "//sandbox",
    ]
  }

  if (is_castos || is_ohos) {
    deps += [ "//third_party/breakpad:client" ]
  }

  if (is_win) {
    sources += [
      "crashpad_win.cc",
      "dump_hung_process_with_ptype.cc",
      "dump_hung_process_with_ptype.h",
      "minidump_with_crashpad_info.cc",
      "minidump_with_crashpad_info.h",
    ]

    deps += [
      "//components/app_launch_prefetch",
      "//third_party/crashpad/crashpad/client",
      "//third_party/crashpad/crashpad/handler",
      "//third_party/crashpad/crashpad/minidump",
      "//third_party/crashpad/crashpad/util",
    ]
  }

  if (is_mac) {
    sources += [ "crashpad_mac.mm" ]
    deps += [
      "//third_party/crashpad/crashpad/minidump",
      "//third_party/crashpad/crashpad/snapshot",
    ]
  }

  if (is_ios) {
    sources += [ "crashpad_ios.mm" ]
    deps += [ "//third_party/crashpad/crashpad/minidump" ]
  }

  # TODO(crbug.com/40031409): Fix code that adds exit-time destructors and
  # enable the diagnostic by removing this line.
  configs += [ "//build/config/compiler:no_exit_time_destructors" ]
}

if (is_win) {
  static_library("run_as_crashpad_handler") {
    sources = [
      "crash_switches.cc",
      "crash_switches.h",
      "fallback_crash_handler_launcher_win.cc",
      "fallback_crash_handler_launcher_win.h",
      "fallback_crash_handler_win.cc",
      "fallback_crash_handler_win.h",
      "fallback_crash_handling_win.cc",
      "fallback_crash_handling_win.h",
      "minidump_with_crashpad_info.cc",
      "minidump_with_crashpad_info.h",
      "run_as_crashpad_handler_win.cc",
      "run_as_crashpad_handler_win.h",
    ]

    deps = [
      "//base",
      "//components/app_launch_prefetch",
      "//components/gwp_asan/buildflags",
      "//components/stability_report",
      "//third_party/crashpad/crashpad/client",
      "//third_party/crashpad/crashpad/handler",
      "//third_party/crashpad/crashpad/minidump",
      "//third_party/crashpad/crashpad/util",
    ]

    if (enable_gwp_asan) {
      deps += [ "//components/gwp_asan/crash_handler" ]
    }
  }

  # This source set contains the include file that declares the export thunks.
  # Any target that gets compiled into both test and release code needs to
  # depend on this for the include alone. The binary it's linked into then needs
  # to depend on either :crash_export_thunks or :test_support, or in the case of
  # release binaries, on //chrome_elf, which re-exports the thunks.
  source_set("crash_export_thunk_include") {
    sources = [ "crash_export_thunks.h" ]
  }

  # This source set contains a set of functions that allow using the crashpad
  # handler across a module boundary. The intent is for these functions to be
  # built into a dynamic library, which the user of the crashpad handler then
  # has a link-time dependency on. This will result in an import dependency
  # from the user to the dynamic library that will be bound at load time.
  # In a single-module project, this source set can alternatively be included in
  # the sole module, in which case the implementation will be bound at link
  # time.
  source_set("crash_export_thunks") {
    sources = [
      "crash_export_thunks.cc",
      "crash_export_thunks.h",
    ]

    defines = [ "CRASH_IMPLEMENTATION" ]

    deps = [
      ":app",
      "//base",
      "//third_party/crashpad/crashpad/client",
    ]
  }

  # This source set contains a set of test stubs for the functions above.
  # time.
  source_set("crash_export_stubs") {
    testonly = true
    defines = [ "CRASH_IMPLEMENTATION" ]

    sources = [
      "crash_export_stubs.cc",
      "crash_export_thunks.h",
    ]

    deps = [
      ":app",
      "//base",
    ]
  }
}

if (is_mac || is_android || is_linux || is_chromeos) {
  # We build a chromium-specific crashpad_handler executable so that we can
  # define custom UserStreamDataSources.
  executable("chrome_crashpad_handler") {
    sources = [ "chrome_crashpad_handler.cc" ]

    deps = [
      ":crashpad_handler_main",
      "//third_party/crashpad/crashpad/handler",
    ]

    if (is_mac && (is_component_build || is_asan || is_ubsan_any)) {
      ldflags = [
        # The handler is in
        # Chromium.app/Contents/Frameworks/Chromium Framework.framework/Versions/A/Helpers/
        # or
        # Content Shell.app/Contents/Frameworks/Content Shell Framework.framework/Versions/C/Helpers/
        # so set rpath up to the base. This is the only case needed for is_asan.
        "-Wl,-rpath,@loader_path/../../../../../../..",

        # The handler can also be executed in an unbundled framework at
        # Chromium Framework.framework/Versions/A/Helpers/
        "-Wl,-rpath,@loader_path/../../../..",

        # The handler can be executed from headless_browsertests in Helpers/
        "-Wl,-rpath,@loader_path/..",
      ]
    }

    if (build_allocation_stack_trace_recorder) {
      # The allocation stack trace report will be included only if the
      # recorder was enabled.
      deps += [ "//components/allocation_recorder/crash_client" ]
    }
  }
}

if (defined(arkweb_crashpad) && arkweb_crashpad) {
  shared_library("arkweb_crashpad_handler") {
    deps = [
      ":crashpad_handler_main",
    ]
  }
}

if (is_android) {
  # There is not any normal way to package native executables in an Android APK.
  # It is normal to package native code as a loadable module but Android's APK
  # installer will ignore files not named like a shared object, so give the
  # handler executable an acceptable name.
  copy("chrome_crashpad_handler_named_as_so") {
    deps = [ ":chrome_crashpad_handler" ]

    sources = [ "$root_out_dir/chrome_crashpad_handler" ]

    outputs = [ "$root_out_dir/libchrome_crashpad_handler.so" ]
  }
}

# This source set provides the functionality required for tests, which on Windows
# link the export thunks directly into the test binary.
source_set("test_support") {
  testonly = true

  deps = [ ":lib" ]

  if (is_win) {
    deps += [ ":crash_export_stubs" ]
  }
}

source_set("unit_tests") {
  testonly = true
  sources = []
  deps = [
    ":lib",
    "//base",
    "//base/test:test_support",
    "//testing/gmock",
    "//testing/gtest",
  ]

  if (defined(arkweb_crashpad) && arkweb_crashpad) {
    sources += arkweb_components_crashpad_ohos_unittest
    deps += [
      "//third_party/crashpad/crashpad/util",
    ]
    defines = [ "CRASH_IMPLEMENTATION" ]
  }
  if (is_win) {
    sources += [
      "fallback_crash_handler_launcher_win_unittest.cc",
      "fallback_crash_handler_win_unittest.cc",
      "fallback_crash_handling_win_unittest.cc",
    ]
    deps += [
      ":run_as_crashpad_handler",
      "//components/crash/win:unit_tests",
      "//third_party/breakpad:client",
      "//third_party/crashpad/crashpad/client",
      "//third_party/crashpad/crashpad/snapshot",
      "//third_party/crashpad/crashpad/util",
    ]
  }
  if (is_ios) {
    sources += [ "crashpad_ios_unittest.mm" ]
    deps += [
      ":app",
      "//components/crash/core/common:reporter_running_ios",
      "//third_party/crashpad/crashpad/client:common",
      "//third_party/crashpad/crashpad/test",
    ]
  }
}