| // Copyright 2023 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/ui/web_applications/web_app_relaunch_notification.h" |
| |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/no_destructor.h" |
| #include "base/notreached.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/task/single_thread_task_runner.h" |
| #include "base/timer/timer.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/notifications/notification_display_service.h" |
| #include "chrome/browser/notifications/notification_handler.h" |
| #include "chrome/browser/notifications/system_notification_helper.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser_navigator.h" |
| #include "chrome/browser/ui/browser_navigator_params.h" |
| #include "chrome/browser/web_applications/web_app_ui_manager.h" |
| #include "chrome/browser/web_applications/web_app_utils.h" |
| #include "chrome/common/webui_url_constants.h" |
| #include "chromeos/strings/grit/chromeos_strings.h" |
| #include "components/webapps/common/web_app_id.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| #include "ash/constants/notifier_catalogs.h" |
| #endif |
| |
| namespace web_app { |
| |
| namespace { |
| |
| constexpr char kWebAppRelaunchId[] = "web_app_relaunch"; |
| constexpr char kWebAppRelaunchNotifierIdPrefix[] = "web_app_relaunch_notifier"; |
| |
| std::string CreateNotificationId(const webapps::AppId& placeholder_app_id) { |
| return base::StrCat( |
| {kWebAppRelaunchNotifierIdPrefix, ":", placeholder_app_id}); |
| } |
| |
| message_center::Notification CreateNotification( |
| const webapps::AppId& placeholder_app_id, |
| const webapps::AppId& final_app_id, |
| const std::u16string& final_app_name) { |
| #if (BUILDFLAG(IS_CHROMEOS_ASH)) |
| message_center::NotifierId notifier_id = message_center::NotifierId( |
| message_center::NotifierType::SYSTEM_COMPONENT, kWebAppRelaunchId, |
| ash::NotificationCatalogName::kWebAppSettings); |
| #else |
| message_center::NotifierId notifier_id = message_center::NotifierId( |
| message_center::NotifierType::SYSTEM_COMPONENT, kWebAppRelaunchId); |
| #endif // (BUILDFLAG(IS_CHROMEOS_ASH)) |
| |
| message_center::Notification notification( |
| message_center::NOTIFICATION_TYPE_SIMPLE, |
| CreateNotificationId(placeholder_app_id), |
| l10n_util::GetStringFUTF16(IDS_WEB_APP_RELAUNCH_NOTIFICATION_TITLE, |
| final_app_name), |
| l10n_util::GetStringUTF16(IDS_WEB_APP_RELAUNCH_NOTIFICATION_MESSAGE), |
| ui::ImageModel(), |
| /* display_source= */ std::u16string(), |
| /* origin_url */ GURL(), std::move(notifier_id), |
| message_center::RichNotificationData(), |
| base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( |
| message_center::HandleNotificationClickDelegate::ButtonClickCallback( |
| base::DoNothing()))); |
| notification.SetSystemPriority(); |
| return notification; |
| } |
| |
| } // namespace |
| |
| void NotifyAppRelaunchState(const webapps::AppId& placeholder_app_id, |
| const webapps::AppId& final_app_id, |
| const std::u16string& final_app_name, |
| base::WeakPtr<Profile> profile, |
| AppRelaunchState relaunch_state) { |
| if (!profile) { |
| return; |
| } |
| |
| switch (relaunch_state) { |
| case web_app::AppRelaunchState::kAppClosingForRelaunch: |
| NotificationDisplayService::GetForProfile(profile.get()) |
| ->Display(NotificationHandler::Type::TRANSIENT, |
| std::move(CreateNotification(placeholder_app_id, |
| final_app_id, final_app_name)), |
| /*metadata=*/nullptr); |
| break; |
| case web_app::AppRelaunchState::kAppAboutToRelaunch: |
| // TODO(b/311711416): Implement progress bar. |
| break; |
| case web_app::AppRelaunchState::kAppRelaunched: |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner; |
| if (GetTaskRunnerForTesting()) { // IN-TEST |
| task_runner = GetTaskRunnerForTesting(); // IN-TEST |
| } else { |
| task_runner = base::SingleThreadTaskRunner::GetCurrentDefault(); |
| } |
| task_runner->PostDelayedTask( |
| FROM_HERE, |
| base::BindOnce( |
| [](webapps::AppId app_id, base::WeakPtr<Profile> profile) { |
| if (!profile) { |
| return; |
| } |
| |
| // The `NotificationDisplayService::Close` function can be |
| // called even if |
| // the notification is not shown anymore. |
| NotificationDisplayService::GetForProfile(profile.get()) |
| ->Close(NotificationHandler::Type::TRANSIENT, |
| CreateNotificationId(app_id)); |
| }, |
| placeholder_app_id, std::move(profile)), |
| base::Seconds(kSecondsToShowNotificationPostAppRelaunch)); |
| break; |
| } |
| } |
| |
| scoped_refptr<base::SingleThreadTaskRunner>& GetTaskRunnerForTesting() { |
| static base::NoDestructor<scoped_refptr<base::SingleThreadTaskRunner>> |
| task_runner_for_testing; |
| return *task_runner_for_testing; |
| } |
| |
| } // namespace web_app |