chromium/chrome/browser/download/download_ui_controller.cc

// Copyright 2013 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/download/download_ui_controller.h"

#include <memory>
#include <utility>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/download/bubble/download_bubble_utils.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/download/download_stats.h"
#include "chrome/common/pref_names.h"
#include "components/download/public/common/download_item.h"
#include "components/security_state/content/security_state_tab_helper.h"
#include "components/security_state/core/security_state.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/strings/string_util.h"
#include "chrome/browser/download/android/download_controller.h"
#include "chrome/browser/download/android/download_controller_base.h"
#include "components/pdf/common/constants.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/common/content_features.h"
#else
#include "chrome/browser/download/bubble/download_bubble_prefs.h"
#include "chrome/browser/download/bubble/download_bubble_ui_controller.h"
#include "chrome/browser/download/bubble/download_bubble_update_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/download/notification/download_notification_manager.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/startup/browser_params_proxy.h"
#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)

namespace {

// DownloadShelfUIControllerDelegate{Android,} is used when a
// DownloadUIController is
// constructed without specifying an explicit Delegate.
#if BUILDFLAG(IS_ANDROID)

class AndroidUIControllerDelegate : public DownloadUIController::Delegate {
 public:
  AndroidUIControllerDelegate() {}
  ~AndroidUIControllerDelegate() override {}

 private:
  // DownloadUIController::Delegate
  void OnNewDownloadReady(download::DownloadItem* item) override;
};

void AndroidUIControllerDelegate::OnNewDownloadReady(
    download::DownloadItem* item) {
  DownloadControllerBase::Get()->OnDownloadStarted(item);
}

#else  // BUILDFLAG(IS_ANDROID)

void InitializeDownloadBubbleUpdateService(Profile* profile,
                                           content::DownloadManager* manager) {}

class DownloadShelfUIControllerDelegate
    : public DownloadUIController::Delegate {};

void DownloadShelfUIControllerDelegate::OnNewDownloadReady(
    download::DownloadItem* item) {}

class DownloadBubbleUIControllerDelegate
    : public DownloadUIController::Delegate {};

void DownloadBubbleUIControllerDelegate::OnNewDownloadReady(
    download::DownloadItem* item) {}

void DownloadBubbleUIControllerDelegate::OnButtonClicked() {}

#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_CHROMEOS)

// A composite `DownloadUIController::Delegate` for use exclusively on ChromeOS.
// TODO(http://b/279791981): Remove after enabling the new downloads integration
// with System UI surfaces and deprecating `DownloadNotificationManager`.
class CrOSUIControllerDelegate : public DownloadUIController::Delegate {
 public:
  explicit CrOSUIControllerDelegate(content::DownloadManager* manager) {
    // Conditionally add the `DownloadBubbleUIControllerDelegate`.
    auto* profile = Profile::FromBrowserContext(manager->GetBrowserContext());
    if (download::IsDownloadBubbleEnabled()) {
      delegates_.emplace_back(
          std::make_unique<DownloadBubbleUIControllerDelegate>(profile));
      InitializeDownloadBubbleUpdateService(profile, manager);
    }

    // Generally the `DownloadNotificationManager` should always be added as it
    // provides System UI notifications on ChromeOS.
    bool add_download_notification_manager = true;

    // In Lacros, the `DownloadNotificationManager` should be added if and only
    // if the new downloads integration with System UI surfaces is disabled.
    // This ensures that exactly one System UI notification provider exists.
#if BUILDFLAG(IS_CHROMEOS_LACROS)
    if (auto* proxy = chromeos::BrowserParamsProxy::Get();
        proxy && proxy->IsSysUiDownloadsIntegrationV2Enabled()) {
      add_download_notification_manager = false;
    }
#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)

    if (add_download_notification_manager) {
      delegates_.emplace_back(
          std::make_unique<DownloadNotificationManager>(profile));
    }
  }

  CrOSUIControllerDelegate(const CrOSUIControllerDelegate&) = delete;
  CrOSUIControllerDelegate& operator=(const CrOSUIControllerDelegate&) = delete;
  ~CrOSUIControllerDelegate() override = default;

 private:
  // DownloadUIController::Delegate:
  void OnNewDownloadReady(download::DownloadItem* item) override {
    for (auto& delegate : delegates_) {
      delegate->OnNewDownloadReady(item);
    }
  }

  void OnButtonClicked() override {
    for (auto& delegate : delegates_) {
      delegate->OnButtonClicked();
    }
  }

  // The collection of delegates contained by this composite.
  std::vector<std::unique_ptr<DownloadUIController::Delegate>> delegates_;
};

#endif  // BUILDFLAG(IS_CHROMEOS)

} // namespace

DownloadUIController::Delegate::~Delegate() {}

void DownloadUIController::Delegate::OnButtonClicked() {}

DownloadUIController::DownloadUIController(content::DownloadManager* manager,
                                           std::unique_ptr<Delegate> delegate)
    :{}

DownloadUIController::~DownloadUIController() = default;

void DownloadUIController::OnButtonClicked() {}

void DownloadUIController::OnDownloadCreated(content::DownloadManager* manager,
                                             download::DownloadItem* item) {}

void DownloadUIController::OnDownloadUpdated(content::DownloadManager* manager,
                                             download::DownloadItem* item) {}