// Copyright 2022 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/network_sandbox.h"

#include "base/dcheck_is_on.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/network_sandbox_grant_result.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/network_service_util.h"
#include "content/public/common/content_client.h"
#include "sql/database.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include "base/win/security_util.h"
#include "base/win/sid.h"
#include "content/browser/network_service_instance_impl.h"
#include "content/common/features.h"
#include "sandbox/policy/features.h"
#endif  // BUILDFLAG(IS_WIN)

namespace content {

namespace {

// A filename that represents that the data contained within `data_directory`
// has been migrated successfully and the data in `unsandboxed_data_path` is now
// invalid.
const base::FilePath::CharType kCheckpointFileName[] =
    FILE_PATH_LITERAL("NetworkDataMigrated");

// A platform specific set of parameters that is used when granting the sandbox
// access to the network context data.
struct SandboxParameters {
#if BUILDFLAG(IS_WIN)
  std::wstring lpac_capability_name;
#if DCHECK_IS_ON()
  bool sandbox_enabled;
#endif  // DCHECK_IS_ON()
#endif  // BUILDFLAG(IS_WIN)
};

// Deletes the old data for a data file called `filename` from `old_path`. If
// `file_path` refers to an SQL database then `is_sql` should be set to true,
// and the journal file will also be deleted.
//
// Returns SandboxGrantResult::kSuccess if the all delete operations completed
// successfully. Returns SandboxGrantResult::kFailedToDeleteData if a file could
// not be deleted.
SandboxGrantResult MaybeDeleteOldData(
    const base::FilePath& old_path,
    const std::optional<base::FilePath>& filename,
    bool is_sql) {
  // The path to the specific data file might not have been specified in the
  // network context params. In that case, nothing to delete.
  if (!filename.has_value())
    return SandboxGrantResult::kSuccess;

  // Check old path exists, and is a directory.
  DCHECK(base::DirectoryExists(old_path));

  base::FilePath old_file_path = old_path.Append(*filename);

  SandboxGrantResult last_error = SandboxGrantResult::kSuccess;
  // File might have already been deleted, or simply does not exist yet.
  if (base::PathExists(old_file_path)) {
    if (!base::DeleteFile(old_file_path)) {
      PLOG(ERROR) << "Failed to delete file " << old_file_path;
      // Continue on error.
      last_error = SandboxGrantResult::kFailedToDeleteOldData;
    }
  }

  if (!is_sql)
    return last_error;

  base::FilePath old_journal_path = sql::Database::JournalPath(old_file_path);
  // There might not be a journal file, or it's already been deleted.
  if (!base::PathExists(old_journal_path))
    return last_error;

  if (base::PathExists(old_journal_path)) {
    if (!base::DeleteFile(old_journal_path)) {
      PLOG(ERROR) << "Failed to delete file " << old_journal_path;
      // Continue on error.
      last_error = SandboxGrantResult::kFailedToDeleteOldData;
    }
  }

  return last_error;
}

// Copies data file called `filename` from `old_path` to `new_path` (which must
// both be directories). If `file_path` refers to an SQL database then `is_sql`
// should be set to true, and the journal file will also be migrated.
// Destination files will be overwritten if they exist already.
//
// Returns SandboxGrantResult::kSuccess if the operation completed successfully.
// Returns SandboxGrantResult::kFailedToCopyData if a file could not be copied.
SandboxGrantResult MaybeCopyData(const base::FilePath& old_path,
                                 const base::FilePath& new_path,
                                 const std::optional<base::FilePath>& filename,
                                 bool is_sql) {
  // The path to the specific data file might not have been specified in the
  // network context params. In that case, no files need to be moved.
  if (!filename.has_value())
    return SandboxGrantResult::kSuccess;

  // Check both paths exist, and are directories.
  DCHECK(base::DirectoryExists(old_path) && base::DirectoryExists(new_path));

  base::FilePath old_file_path = old_path.Append(*filename);
  base::FilePath new_file_path = new_path.Append(*filename);

  // Note that this code will overwrite the new file with the old file even if
  // it exists already.
  if (base::PathExists(old_file_path)) {
    // Delete file to make sure that inherited permissions are set on the new
    // file.
    base::DeleteFile(new_file_path);
    if (!base::CopyFile(old_file_path, new_file_path)) {
      PLOG(ERROR) << "Failed to copy file " << old_file_path << " to "
                  << new_file_path;
      // Do not attempt to copy journal file if copy of main database file
      // fails.
      return SandboxGrantResult::kFailedToCopyData;
    }
  }

  if (!is_sql)
    return SandboxGrantResult::kSuccess;

  base::FilePath old_journal_path = sql::Database::JournalPath(old_file_path);
  // There might not be a journal file, or it's already been moved.
  if (!base::PathExists(old_journal_path))
    return SandboxGrantResult::kSuccess;

  base::FilePath new_journal_path = sql::Database::JournalPath(new_file_path);

  // Delete file to make sure that inherited permissions are set on the new
  // file.
  base::DeleteFile(new_journal_path);

  if (!base::CopyFile(old_journal_path, new_journal_path)) {
    PLOG(ERROR) << "Failed to copy file " << old_journal_path << " to "
                << new_journal_path;
    return SandboxGrantResult::kFailedToCopyData;
  }

  return SandboxGrantResult::kSuccess;
}

// Deletes old data from `unsandboxed_data_path` if a migration operation has
// been successful.
SandboxGrantResult CleanUpOldData(
    network::mojom::NetworkContextParams* params) {
  // Never delete old data unless the checkpoint file exists.
  DCHECK(base::PathExists(
      params->file_paths->data_directory.path().Append(kCheckpointFileName)));

  SandboxGrantResult last_error = SandboxGrantResult::kSuccess;
  SandboxGrantResult result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->cookie_database_name, /*is_sql=*/true);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->http_server_properties_file_name, /*is_sql=*/false);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->transport_security_persister_file_name,
      /*is_sql=*/false);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->reporting_and_nel_store_database_name,
      /*is_sql=*/true);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(*params->file_paths->unsandboxed_data_path,
                              params->file_paths->trust_token_database_name,
                              /*is_sql=*/true);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;
  return last_error;
}

// Grants the sandbox access to the specified `path`, which must be a directory
// that exists.  On Windows, the LPAC capability name should be supplied in the
// `sandbox_params` to specify the name of the LPAC capability to be applied to
// the path.  On platforms which support directory transfer, the directory is
// opened as a handle which is then sent to the NetworkService.
// Returns true if the sandbox was successfully granted access to the path.
bool MaybeGrantAccessToDataPath(const SandboxParameters& sandbox_params,
                                network::TransferableDirectory* directory) {
  // There is no need to set file permissions if the network service is running
  // in-process.
  if (IsInProcessNetworkService())
    return true;
  // Only do this on directories.
  if (!base::DirectoryExists(directory->path())) {
    return false;
  }

#if BUILDFLAG(IS_WIN)
  // On platforms that don't support the LPAC sandbox, do nothing.
  if (!sandbox::policy::features::IsNetworkSandboxSupported()) {
    return true;
  }
  DCHECK(!sandbox_params.lpac_capability_name.empty());
  auto ac_sids = base::win::Sid::FromNamedCapabilityVector(
      {sandbox_params.lpac_capability_name});

  static constexpr DWORD kAccessMask =
      GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
  static constexpr DWORD kInheritance =
      CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;

  // For cache dir only, ACL the parent above the "Cache_Data" directory to
  // ensure that rename/delete operations can take place correctly.
  base::FilePath directory_to_acl = directory->path();

  if (directory_to_acl.BaseName() == base::FilePath(kCacheDataDirectoryName)) {
    directory_to_acl = directory_to_acl.DirName();
  }
  // If LPAC capability already has access to the directory then avoid
  // granting access again. This is a performance optimization.
  if (HasAccessToPath(directory_to_acl, ac_sids, kAccessMask, kInheritance)) {
    return true;
  }

  // Grant recursive access to directory. This also means new files in the
  // directory will inherit the ACE.
  return base::win::GrantAccessToPath(directory_to_acl, ac_sids, kAccessMask,
                                      kInheritance, /*recursive=*/true);
#else
  if (directory->IsOpenForTransferRequired()) {
    directory->OpenForTransfer();
    return true;
  }

  return true;
#endif  // BUILDFLAG(IS_WIN)
}

// Logs the system error code to UMA. The name of the histogram will be
// `histogram_base_name` suffixed with either ".Windows" or ".Posix" depending
// on the platform (Fuchsia counts as "Posix" here because it uses `errno`).
// Both variants must be added to "histograms.xml":
//
// ```
// <histogram name="NetworkService.****Error.Posix"
//     enum="PopularOSErrno" expires_after="">
//   <owner></owner>
//   <owner></owner>
//   <summary>
//     The system error code ...
//
//     Logged when ...
//
//     Only logged for non-Windows platforms.
//   </summary>
// </histogram>
//
// <histogram name="NetworkService.****Error.Windows"
//     enum="WinGetLastError" expires_after="">
//   <owner></owner>
//   <owner></owner>
//   <summary>
//     The system error code ...
//
//     Logged when ...
//
//     Only logged on Windows.
//   </summary>
// </histogram>
// ```
void LogSystemErrorCode(std::string_view histogram_base_name) {
  std::string_view suffix = ".Posix";
  if constexpr (BUILDFLAG(IS_WIN)) {
    suffix = ".Windows";
  }
  base::UmaHistogramSparse(base::StrCat({histogram_base_name, suffix}),
                           logging::GetLastSystemErrorCode());
}

// Creates the directory `path`, which must not be std::nullopt, and then grants
// sandbox access in line with `sandbox_params`. If an error occurs it is logged
// using `directory_name_for_logging` as the name to use to describe the
// directory.
void CreateAndGrantAccessLoggingError(
    const SandboxParameters& sandbox_params,
    network::TransferableDirectory& path,
    std::string_view directory_name_for_histogram) {
  // The path must exist for the cache ACL to be set. Create if needed.
  if (base::CreateDirectory(path.path())) {
    if (!MaybeGrantAccessToDataPath(sandbox_params, &path)) {
      PLOG(ERROR) << "Failed to grant sandbox access to "
                  << directory_name_for_histogram << " directory "
                  << path.path();
      LogSystemErrorCode(
          base::StrCat({"NetworkService.GrantAccessToDataPathError.",
                        directory_name_for_histogram}));
    }
  }
}

// See the description in the header file.
//
// This process has a few stages:
// 1. Create and grant the sandbox access to the cache dir.
// 2. If `data_directory` is not specified then the caller is using in-memory
// storage and so there's nothing to do. END.
// 3. If `unsandboxed_data_path` is not specified then the caller is not aware
// of the sandbox or migration, and the steps terminate here with
// `data_directory` used by the network context and END.
// 4. If migration has already taken place, regardless of whether it's requested
// this time, grant the sandbox access to the `data_directory` (since this needs
// to be done every time), and terminate here with `data_directory` being used.
// END.
// 5. If migration is not requested, then terminate here with
// `unsandboxed_data_path` being used. END.
// 6. At this point, migration has been requested and hasn't already happened,
// so begin a migration attempt. If any of these steps fail, then bail out, and
// `unsandboxed_data_path` is used.
// 7. Grant the sandbox access to the `data_directory` (this is done before
// copying the files to use inherited ACLs when copying files on Windows).
// 8. Copy all the data files one by one from the `unsandboxed_data_path` to the
// `data_directory`.
// 9. Once all the files have been copied, lay down the Checkpoint file in the
// `data_directory`.
// 10. Delete all the original files (if they exist) from
// `unsandboxed_data_path`.
SandboxGrantResult MaybeGrantSandboxAccessToNetworkContextData(
    const SandboxParameters& sandbox_params,
    network::mojom::NetworkContextParams* params) {
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
#if BUILDFLAG(IS_WIN)
#if DCHECK_IS_ON()
  params->win_permissions_set = true;
#endif
#endif  // BUILDFLAG(IS_WIN)

  // No file paths (e.g. in-memory context) so nothing to do.
  if (!params->file_paths) {
    return SandboxGrantResult::kDidNotAttemptToGrantSandboxAccess;
  }

  // HTTP cache path is special, and not under `data_directory` so must also
  // be granted access. Continue attempting to grant access to the other files
  // if this part fails.
  if (params->file_paths->http_cache_directory && params->http_cache_enabled) {
    // The path must exist for the cache ACL to be set. Create if needed.
    if (base::CreateDirectory(
            params->file_paths->http_cache_directory->path())) {
      // Note, this code always grants access to the cache directory even when
      // the sandbox is not enabled. This is a optimization (on Windows)
      // because by setting the ACL on the directory earlier rather than
      // later, it ensures that any new files created by the cache subsystem
      // get the inherited ACE rather than having to set them manually later.
      SCOPED_UMA_HISTOGRAM_TIMER("NetworkService.TimeToGrantCacheAccess");
      TRACE_EVENT("startup", "NetworkSandbox.MaybeGrantAccessToDataPath");
      if (!MaybeGrantAccessToDataPath(
              sandbox_params, &*params->file_paths->http_cache_directory)) {
        PLOG(ERROR) << "Failed to grant sandbox access to cache directory "
                    << params->file_paths->http_cache_directory->path();
      }
    }

    // This is only used if disk caching is enabled.
    if (params->file_paths->no_vary_search_directory) {
      SCOPED_UMA_HISTOGRAM_TIMER(
          "NetworkService.TimeToGrantNoVarySearchAccess");
      CreateAndGrantAccessLoggingError(
          sandbox_params, params->file_paths->no_vary_search_directory.value(),
          "NoVarySearch");
    }
  }
  if (params->file_paths->shared_dictionary_directory &&
      params->shared_dictionary_enabled) {
    SCOPED_UMA_HISTOGRAM_TIMER(
        "NetworkService.TimeToGrantSharedDictionaryAccess");
    CreateAndGrantAccessLoggingError(
        sandbox_params, params->file_paths->shared_dictionary_directory.value(),
        "SharedDictionary");
  }

  // No data directory, so rest of the files and databases are in memory.
  // Nothing to do.
  if (params->file_paths->data_directory.path().empty()) {
    return SandboxGrantResult::kDidNotAttemptToGrantSandboxAccess;
  }

  if (!params->file_paths->unsandboxed_data_path.has_value()) {
#if BUILDFLAG(IS_WIN) && DCHECK_IS_ON()
    // On Windows, if network sandbox is enabled then there a migration must
    // happen, so a `unsandboxed_data_path` must be specified.
    DCHECK(!sandbox_params.sandbox_enabled);
#endif
    // Trigger migration should never be requested if `unsandboxed_data_path` is
    // not set.
    DCHECK(!params->file_paths->trigger_migration);
    // Nothing to do here if `unsandboxed_data_path` is not specified.
    return SandboxGrantResult::kDidNotAttemptToGrantSandboxAccess;
  }

  // If these paths are ever the same then this is a mistake, as the file
  // permissions will be applied to the top level path which could contain other
  // data that should not be accessible by the network sandbox.
  DCHECK_NE(params->file_paths->data_directory.path(),
            *params->file_paths->unsandboxed_data_path);

  // Four cases need to be handled here.
  //
  // 1. No Checkpoint file, and `trigger_migration` is false: Data is still in
  // `unsandboxed_data_path` and sandbox does not need to be granted access. No
  // migration happens.
  // 2. No Checkpoint file, and `trigger_migration` is true: Data is in
  // `unsandboxed_data_path` and needs to be migrated to `data_directory`, and
  // the sandbox needs to be granted access to `data_directory`.
  // 3. Checkpoint file, and `trigger_migration` is false: Data is in
  // `data_directory` (already migrated) and sandbox needs to be granted access
  // to `data_directory`.
  // 4. Checkpoint file, and `trigger_migration` is true: Data is in
  // `data_directory` (already migrated) and sandbox needs to be granted access
  // to `data_directory`. This is the same as above and `trigger_migration`
  // changes nothing, as it's already happened.
  base::FilePath checkpoint_filename =
      params->file_paths->data_directory.path().Append(kCheckpointFileName);
  bool migration_already_happened = base::PathExists(checkpoint_filename);

  // Case 1. above where nothing is done.
  if (!params->file_paths->trigger_migration && !migration_already_happened) {
#if BUILDFLAG(IS_WIN) && DCHECK_IS_ON()
    // On Windows, if network sandbox is enabled then there a migration must
    // happen, so `trigger_migration` must be true, or a migration must have
    // already happened.
    DCHECK(!sandbox_params.sandbox_enabled);
#endif
    return SandboxGrantResult::kNoMigrationRequested;
  }

  // Create the `data_directory` if necessary so access can be granted to it.
  // Note that if a migration has already happened then this does nothing, as
  // the directory already exists.
  if (!base::CreateDirectory(params->file_paths->data_directory.path())) {
    PLOG(ERROR) << "Failed to create network context data directory "
                << params->file_paths->data_directory.path();
    // This is a fatal error, if the `data_directory` does not exist then
    // migration cannot be attempted. In this case the network context will
    // operate using `unsandboxed_data_path` and the migration attempt will be
    // retried the next time the same network context is created with
    // `trigger_migration` set.
    return SandboxGrantResult::kFailedToCreateDataDirectory;
  }

  {
    SCOPED_UMA_HISTOGRAM_TIMER("NetworkService.TimeToGrantDataAccess");
    // This must be done on each load of the network context for two
    // platform-specific reasons:
    //
    // 1. On Windows Chrome, the LPAC SID for each channel is different so it is
    // possible that this data might be read by a different channel and we need
    // to explicitly support that.
    // 2. Other platforms such as macOS and Linux need to grant access each time
    // as they do not rely on filesystem permissions, but runtime sandbox broker
    // permissions.
    if (!MaybeGrantAccessToDataPath(sandbox_params,
                                    &params->file_paths->data_directory)) {
      PLOG(ERROR)
          << "Failed to grant sandbox access to network context data directory "
          << params->file_paths->data_directory.path();
      // If migration has already happened there isn't much that can be done
      // about this, the data has already moved, but the sandbox might not have
      // access.
      if (migration_already_happened)
        return SandboxGrantResult::kMigrationAlreadySucceededWithNoAccess;
      // If migration hasn't happened yet, then fail here, and do not attempt to
      // migrate or proceed further. Better to just leave the data where it is.
      // In this case `unsandboxed_data_path` will continue to be used and the
      // migration attempt will be retried the next time the same network
      // context is created with `trigger_migration` set.
      return SandboxGrantResult::kFailedToGrantSandboxAccessToData;
    }
  }  // SCOPED_UMA_HISTOGRAM_TIMER

  // This covers cases 3. and 4. where a migration has already happened.
  if (migration_already_happened) {
    // Migration succeeded in an earlier attempt and `data_directory` is valid,
    // but clean up any old data that might have failed to delete in the last
    // attempt.
    SandboxGrantResult cleanup_result = CleanUpOldData(params);
    if (cleanup_result != SandboxGrantResult::kSuccess)
      return cleanup_result;
    return SandboxGrantResult::kMigrationAlreadySucceeded;
  }

  SandboxGrantResult result;
  // Reaching here means case 2. where a migration hasn't yet happened, but it's
  // been requested.
  //
  // Now attempt to migrate the data from the `unsandboxed_data_path` to the new
  // `data_directory`. This code can be removed from content once migration has
  // taken place.
  //
  // This code has a three stage process.
  // 1. An attempt is made to copy all the data files from the old location to
  // the new location.
  // 2. A checkpoint file ("NetworkData") is then placed in the new directory to
  // mark that the data there is valid and should be used.
  // 3. The old files are deleted.
  //
  // A failure half way through stage 1 or 2 will mean that the old data should
  // be used instead of the new data. A failure to delete the files will cause
  // a retry attempt next time the same network context is created.
  {
    // Stage 1: Copy the data files. Note: This might copy files over the top of
    // existing files if it was partially successful in an earlier attempt.
    SCOPED_UMA_HISTOGRAM_TIMER("NetworkService.TimeToMigrateData");
    result = MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                           params->file_paths->data_directory.path(),
                           params->file_paths->cookie_database_name,
                           /*is_sql=*/true);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result = MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                           params->file_paths->data_directory.path(),
                           params->file_paths->http_server_properties_file_name,
                           /*is_sql=*/false);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result = MaybeCopyData(
        *params->file_paths->unsandboxed_data_path,
        params->file_paths->data_directory.path(),
        params->file_paths->transport_security_persister_file_name,
        /*is_sql=*/false);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result =
        MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                      params->file_paths->data_directory.path(),
                      params->file_paths->reporting_and_nel_store_database_name,
                      /*is_sql=*/true);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result = MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                           params->file_paths->data_directory.path(),
                           params->file_paths->trust_token_database_name,
                           /*is_sql=*/true);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    // Files all copied successfully. Can now proceed to Stage 2 and write the
    // checkpoint filename.
    base::File checkpoint_file(
        checkpoint_filename,
        base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
    if (!checkpoint_file.IsValid())
      return SandboxGrantResult::kFailedToCreateCheckpointFile;
  }  // SCOPED_UMA_HISTOGRAM_TIMER

  // Double check the checkpoint file is there. This should never happen.
  if (!base::PathExists(checkpoint_filename))
    return SandboxGrantResult::kFailedToCreateCheckpointFile;

  // Success, proceed to Stage 3 and clean up old files.
  SandboxGrantResult cleanup_result = CleanUpOldData(params);
  if (cleanup_result != SandboxGrantResult::kSuccess)
    return cleanup_result;

  return SandboxGrantResult::kSuccess;
}

}  // namespace

void GrantSandboxAccessOnThreadPool(
    network::mojom::NetworkContextParamsPtr params,
    base::OnceCallback<void(network::mojom::NetworkContextParamsPtr,
                            SandboxGrantResult)> result_callback) {
  SandboxParameters sandbox_params = {};
#if BUILDFLAG(IS_WIN)
  sandbox_params.lpac_capability_name =
      GetContentClient()->browser()->GetLPACCapabilityNameForNetworkService();
#if DCHECK_IS_ON()
  sandbox_params.sandbox_enabled =
      GetContentClient()->browser()->ShouldSandboxNetworkService();
#endif  // DCHECK_IS_ON()
#endif  // BUILDFLAG(IS_WIN)
  base::OnceCallback<SandboxGrantResult()> worker_task =
      base::BindOnce(&MaybeGrantSandboxAccessToNetworkContextData,
                     sandbox_params, params.get());
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
      std::move(worker_task),
      base::BindOnce(std::move(result_callback), std::move(params)));
}

}  // namespace content
