blob: af9b404beedc1ca2a57cd90a10e870dd7a0f0548 [file] [log] [blame]
// Copyright 2024 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/ash/extended_updates/extended_updates_notification.h"
#include <optional>
#include <vector>
#include "ash/constants/ash_pref_names.h"
#include "ash/constants/notifier_catalogs.h"
#include "ash/public/cpp/new_window_delegate.h"
#include "ash/public/cpp/system_notification_builder.h"
#include "ash/system/extended_updates/extended_updates_metrics.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ash/extended_updates/extended_updates_controller.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_handler.h"
#include "chrome/browser/ui/webui/ash/extended_updates/extended_updates_dialog.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/chromeos/devicetype_utils.h"
#include "ui/message_center/public/cpp/notification.h"
#include "url/gurl.h"
namespace ash {
namespace {
using IndexedButton = ExtendedUpdatesNotification::IndexedButton;
// Adds the |button| to the notification via |data|,
// where |title_id| is the string resource id for the button title.
void AddButton(message_center::RichNotificationData& data,
IndexedButton button,
int title_id) {
DCHECK_EQ(data.buttons.size(), static_cast<size_t>(button));
data.buttons.emplace_back(l10n_util::GetStringUTF16(title_id));
}
} // namespace
ExtendedUpdatesNotification::ExtendedUpdatesNotification(Profile* profile)
: profile_(profile->GetWeakPtr()) {}
ExtendedUpdatesNotification::~ExtendedUpdatesNotification() = default;
void ExtendedUpdatesNotification::Show(Profile* profile) {
Show(base::MakeRefCounted<ExtendedUpdatesNotification>(profile));
}
void ExtendedUpdatesNotification::Show(
scoped_refptr<ExtendedUpdatesNotification> delegate) {
if (!delegate || !delegate->profile()) {
return;
}
Profile* profile = delegate->profile();
delegate->SubscribeToDeviceSettingsChanges();
message_center::RichNotificationData data;
// Keep same order as |IndexedButton| enum.
AddButton(data, IndexedButton::kSetUp,
IDS_EXTENDED_UPDATES_NOTIFICATION_SETUP_BUTTON);
AddButton(data, IndexedButton::kLearnMore,
IDS_EXTENDED_UPDATES_NOTIFICATION_LEARN_MORE_BUTTON);
SystemNotificationBuilder builder;
builder.SetId(std::string(kNotificationId))
.SetCatalogName(NotificationCatalogName::kExtendedUpdatesAvailable)
.SetTitleId(IDS_EXTENDED_UPDATES_NOTIFICATION_TITLE)
.SetMessageId(IDS_EXTENDED_UPDATES_NOTIFICATION_MESSAGE)
.SetOptionalFields(data)
.SetDelegate(std::move(delegate));
NotificationDisplayServiceFactory::GetForProfile(profile)->Display(
kNotificationType, builder.Build(/*keep_timestamp=*/false),
/*metadata=*/nullptr);
RecordExtendedUpdatesEntryPointEvent(
ExtendedUpdatesEntryPointEvent::kNoArcNotificationShown);
}
bool ExtendedUpdatesNotification::IsNotificationDismissed(Profile* profile) {
return profile->GetPrefs()->GetBoolean(
prefs::kExtendedUpdatesNotificationDismissed);
}
void ExtendedUpdatesNotification::Close(bool by_user) {
if (by_user && profile_) {
profile_->GetPrefs()->SetBoolean(
prefs::kExtendedUpdatesNotificationDismissed, true);
}
}
void ExtendedUpdatesNotification::Click(
const std::optional<int>& button_index,
const std::optional<std::u16string>& reply) {
if (!button_index) {
return;
}
switch (IndexedButton{*button_index}) {
case IndexedButton::kSetUp:
RecordExtendedUpdatesEntryPointEvent(
ExtendedUpdatesEntryPointEvent::kNoArcNotificationClicked);
ShowExtendedUpdatesDialog();
break;
case IndexedButton::kLearnMore:
OpenLearnMoreUrl();
break;
}
if (profile_) {
NotificationDisplayServiceFactory::GetForProfile(profile_.get())
->Close(kNotificationType, std::string(kNotificationId));
}
}
void ExtendedUpdatesNotification::ShowExtendedUpdatesDialog() {
extended_updates::ExtendedUpdatesDialog::Show();
}
void ExtendedUpdatesNotification::OpenLearnMoreUrl() {
NewWindowDelegate::GetInstance()->OpenUrl(
GURL(chrome::kDeviceExtendedUpdatesLearnMoreURL),
NewWindowDelegate::OpenUrlFrom::kUserInteraction,
NewWindowDelegate::Disposition::kNewForegroundTab);
}
void ExtendedUpdatesNotification::SubscribeToDeviceSettingsChanges() {
settings_change_subscription_ =
ExtendedUpdatesController::SubscribeToDeviceSettingsChanges(
base::BindRepeating(
&ExtendedUpdatesNotification::OnDeviceSettingsChanged,
weak_factory_.GetWeakPtr()));
}
void ExtendedUpdatesNotification::OnDeviceSettingsChanged() {
if (profile_ && ExtendedUpdatesController::Get()->IsOptedIn()) {
NotificationDisplayServiceFactory::GetForProfile(profile_.get())
->Close(kNotificationType, std::string(kNotificationId));
}
}
} // namespace ash