blob: 92b1be541d89bc1da02039f6904104d65f7fa0b0 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/crostini/crostini_upgrade_available_notification.h"
#include "ash/public/cpp/notification_utils.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/ash/crostini/crostini_manager.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
#include "chrome/grit/generated_resources.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
namespace crostini {
const char kNotifierCrostiniUpgradeAvailable[] = "crostini.upgrade_available";
class CrostiniUpgradeAvailableNotificationDelegate
: public message_center::NotificationDelegate {
public:
explicit CrostiniUpgradeAvailableNotificationDelegate(
Profile* profile,
base::WeakPtr<CrostiniUpgradeAvailableNotification> notification,
base::OnceClosure closure)
: profile_(profile),
notification_(notification),
closure_(std::move(closure)) {
CrostiniManager::GetForProfile(profile_)->UpgradePromptShown(
ContainerId::GetDefault());
}
void Click(const absl::optional<int>& button_index,
const absl::optional<std::u16string>& reply) override {
disposition_ =
CrostiniUpgradeAvailableNotificationClosed::kNotificationBody;
if (button_index && button_index.value() == 0) {
disposition_ = CrostiniUpgradeAvailableNotificationClosed::kUpgradeButton;
HandleButtonClick();
return;
}
HandleBodyClick();
}
void HandleButtonClick() {
chromeos::CrostiniUpgraderDialog::Show(profile_, base::DoNothing());
if (notification_) {
notification_->UpgradeDialogShown();
}
Close(false);
}
void HandleBodyClick() {
chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
profile_, chromeos::settings::mojom::kCrostiniDetailsSubpagePath);
Close(false);
}
void Close(bool by_user) override {
if (by_user) {
disposition_ = CrostiniUpgradeAvailableNotificationClosed::kByUser;
}
// Run the callback now. The notification might hang around after the
// closure has been run, so we need to guard it.
if (closure_) {
std::move(closure_).Run();
}
base::UmaHistogramEnumeration("Crostini.UpgradeAvailable", disposition_);
}
private:
~CrostiniUpgradeAvailableNotificationDelegate() override = default;
CrostiniUpgradeAvailableNotificationClosed disposition_ =
CrostiniUpgradeAvailableNotificationClosed::kUnknown;
Profile* profile_; // Not owned.
base::WeakPtr<CrostiniUpgradeAvailableNotification> notification_;
base::OnceClosure closure_;
base::WeakPtrFactory<CrostiniUpgradeAvailableNotificationDelegate>
weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(CrostiniUpgradeAvailableNotificationDelegate);
};
std::unique_ptr<CrostiniUpgradeAvailableNotification>
CrostiniUpgradeAvailableNotification::Show(Profile* profile,
base::OnceClosure closure) {
return std::make_unique<CrostiniUpgradeAvailableNotification>(
profile, std::move(closure));
}
CrostiniUpgradeAvailableNotification::CrostiniUpgradeAvailableNotification(
Profile* profile,
base::OnceClosure closure)
: profile_(profile) {
message_center::RichNotificationData rich_notification_data;
rich_notification_data.small_image = gfx::Image(gfx::CreateVectorIcon(
vector_icons::kFileDownloadIcon, 64, gfx::kGoogleBlue800));
rich_notification_data.accent_color = ash::kSystemNotificationColorNormal;
rich_notification_data.buttons.emplace_back(
message_center::ButtonInfo(l10n_util::GetStringUTF16(
IDS_CROSTINI_UPGRADE_AVAILABLE_NOTIFICATION_UPGRADE)));
notification_ = std::make_unique<message_center::Notification>(
message_center::NOTIFICATION_TYPE_MULTIPLE,
kNotifierCrostiniUpgradeAvailable,
l10n_util::GetStringUTF16(
IDS_CROSTINI_UPGRADE_AVAILABLE_NOTIFICATION_TITLE),
l10n_util::GetStringUTF16(
IDS_CROSTINI_UPGRADE_AVAILABLE_NOTIFICATION_BODY),
gfx::Image(), std::u16string(), GURL(),
message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
kNotifierCrostiniUpgradeAvailable),
rich_notification_data,
base::MakeRefCounted<CrostiniUpgradeAvailableNotificationDelegate>(
profile_, weak_ptr_factory_.GetWeakPtr(), std::move(closure)));
notification_->SetSystemPriority();
ForceRedisplay();
}
CrostiniUpgradeAvailableNotification::~CrostiniUpgradeAvailableNotification() =
default;
void CrostiniUpgradeAvailableNotification::UpgradeDialogShown() {
notification_->set_buttons({});
notification_->set_never_timeout(false);
notification_->set_pinned(false);
ForceRedisplay();
}
void CrostiniUpgradeAvailableNotification::ForceRedisplay() {
NotificationDisplayService::GetForProfile(profile_)->Display(
NotificationHandler::Type::TRANSIENT, *notification_,
/*metadata=*/nullptr);
}
} // namespace crostini