chromium/chrome/browser/lacros/download_controller_client_lacros.cc

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

#include "chrome/browser/lacros/download_controller_client_lacros.h"

#include "base/functional/bind.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chromeos/crosapi/mojom/download_controller.mojom.h"
#include "chromeos/lacros/lacros_service.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_item_utils.h"
#include "components/download/public/common/simple_download_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_item_utils.h"
#include "mojo/public/cpp/bindings/pending_remote.h"

namespace {

crosapi::mojom::DownloadItemPtr ConvertToMojoDownloadItem(
    download::DownloadItem* item) {
  return download::download_item_utils::ConvertToMojoDownloadItem(
      item, /*is_from_incognito_profile=*/Profile::FromBrowserContext(
                content::DownloadItemUtils::GetBrowserContext(item))
                ->IsIncognitoProfile());
}

}  // namespace

DownloadControllerClientLacros::DownloadControllerClientLacros() {
  profile_manager_observation_.Observe(g_browser_process->profile_manager());
  auto profiles = g_browser_process->profile_manager()->GetLoadedProfiles();
  for (auto* profile : profiles)
    OnProfileAdded(profile);

  auto* service = chromeos::LacrosService::Get();
  if (!service->IsAvailable<crosapi::mojom::DownloadController>())
    return;

  int remote_version =
      service->GetInterfaceVersion<crosapi::mojom::DownloadController>();
  if (remote_version < 0 ||
      static_cast<uint32_t>(remote_version) <
          crosapi::mojom::DownloadController::kBindClientMinVersion) {
    return;
  }

  service->GetRemote<crosapi::mojom::DownloadController>()->BindClient(
      client_receiver_.BindNewPipeAndPassRemoteWithVersion());
}

DownloadControllerClientLacros::~DownloadControllerClientLacros() = default;

void DownloadControllerClientLacros::GetAllDownloads(
    crosapi::mojom::DownloadControllerClient::GetAllDownloadsCallback
        callback) {
  std::vector<crosapi::mojom::DownloadItemPtr> downloads;

  // Aggregate all downloads.
  for (download::DownloadItem* download :
       download_notifier_.GetAllDownloads()) {
    downloads.push_back(ConvertToMojoDownloadItem(download));
  }

  // Sort chronologically by start time.
  std::sort(downloads.begin(), downloads.end(),
            [](const auto& a, const auto& b) {
              return a->start_time.value_or(base::Time()) <
                     b->start_time.value_or(base::Time());
            });

  std::move(callback).Run(std::move(downloads));
}

void DownloadControllerClientLacros::Pause(const std::string& download_guid) {
  auto* download = download_notifier_.GetDownloadByGuid(download_guid);
  if (download)
    download->Pause();
}

void DownloadControllerClientLacros::Resume(const std::string& download_guid,
                                            bool user_resume) {
  auto* download = download_notifier_.GetDownloadByGuid(download_guid);
  if (download)
    download->Resume(user_resume);
}

void DownloadControllerClientLacros::Cancel(const std::string& download_guid,
                                            bool user_cancel) {
  auto* download = download_notifier_.GetDownloadByGuid(download_guid);
  if (download)
    download->Cancel(user_cancel);
}

void DownloadControllerClientLacros::SetOpenWhenComplete(
    const std::string& download_guid,
    bool open_when_complete) {
  auto* download = download_notifier_.GetDownloadByGuid(download_guid);
  if (download)
    download->SetOpenWhenComplete(open_when_complete);
}

void DownloadControllerClientLacros::OnProfileAdded(Profile* profile) {
  download_notifier_.AddProfile(profile);
}

void DownloadControllerClientLacros::OnProfileManagerDestroying() {
  profile_manager_observation_.Reset();
}

void DownloadControllerClientLacros::OnManagerInitialized(
    content::DownloadManager* manager) {
  download::SimpleDownloadManager::DownloadVector downloads;
  manager->GetAllDownloads(&downloads);
  for (download::DownloadItem* download : downloads) {
    OnDownloadCreated(manager, download);
  }
}

void DownloadControllerClientLacros::OnManagerGoingDown(
    content::DownloadManager* manager) {
  download::SimpleDownloadManager::DownloadVector downloads;
  manager->GetAllDownloads(&downloads);
  for (download::DownloadItem* download : downloads) {
    OnDownloadDestroyed(manager, download);
  }
}

void DownloadControllerClientLacros::OnDownloadCreated(
    content::DownloadManager* manager,
    download::DownloadItem* item) {
  auto* service = chromeos::LacrosService::Get();
  if (!service->IsAvailable<crosapi::mojom::DownloadController>())
    return;

  service->GetRemote<crosapi::mojom::DownloadController>()->OnDownloadCreated(
      ConvertToMojoDownloadItem(item));
}

void DownloadControllerClientLacros::OnDownloadUpdated(
    content::DownloadManager* manager,
    download::DownloadItem* item) {
  auto* service = chromeos::LacrosService::Get();
  if (!service->IsAvailable<crosapi::mojom::DownloadController>())
    return;

  service->GetRemote<crosapi::mojom::DownloadController>()->OnDownloadUpdated(
      ConvertToMojoDownloadItem(item));
}

void DownloadControllerClientLacros::OnDownloadDestroyed(
    content::DownloadManager* manager,
    download::DownloadItem* item) {
  auto* service = chromeos::LacrosService::Get();
  if (!service->IsAvailable<crosapi::mojom::DownloadController>())
    return;

  service->GetRemote<crosapi::mojom::DownloadController>()->OnDownloadDestroyed(
      ConvertToMojoDownloadItem(item));
}