blob: 04c01e38731b8980992ebd8b16e95148808d2609 [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/chromeos/full_restore/full_restore_service.h"
#include "ash/public/cpp/notification_utils.h"
#include "base/strings/string_util.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/chromeos/full_restore/app_launch_handler.h"
#include "chrome/browser/chromeos/full_restore/full_restore_data_handler.h"
#include "chrome/browser/chromeos/full_restore/full_restore_prefs.h"
#include "chrome/browser/chromeos/full_restore/full_restore_service_factory.h"
#include "chrome/browser/chromeos/full_restore/new_user_restore_pref_handler.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/constants/chromeos_features.h"
#include "components/account_id/account_id.h"
#include "components/full_restore/full_restore_info.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/public/cpp/notification.h"
namespace chromeos {
namespace full_restore {
const char kRestoreForCrashNotificationId[] = "restore_for_crash_notification";
const char kRestoreNotificationId[] = "restore_notification";
const char kSetRestorePrefNotificationId[] = "set_restore_pref_notification";
// If the user selected the 'Restore' button from the restore notification
// dialog for more than |kMaxConsecutiveRestoreSelectionCount| times, show the
// set restore pref notification.
const int kMaxConsecutiveRestoreSelectionCount = 3;
FullRestoreService::FullRestoreService(Profile* profile)
: profile_(profile),
app_launch_handler_(std::make_unique<AppLaunchHandler>(profile_)),
restore_data_handler_(
std::make_unique<FullRestoreDataHandler>(profile_)) {
// If the system crashed before reboot, show the restore notification.
if (profile->GetLastSessionExitType() == Profile::EXIT_CRASHED) {
ShowRestoreNotification(kRestoreForCrashNotificationId);
return;
}
PrefService* prefs = profile->GetPrefs();
DCHECK(prefs);
// If it is the first time to run Chrome OS, we don't have restore data, so we
// don't need to consider restoration.
if (user_manager::UserManager::Get()->IsCurrentUserNew()) {
new_user_pref_handler_ =
std::make_unique<NewUserRestorePrefHandler>(profile_);
return;
}
// If it is the first time to migrate to the full restore release, we don't
// have other restore data, so we don't need to consider restoration.
if (!HasRestorePref(prefs)) {
SetDefaultRestorePrefIfNecessary(prefs);
return;
}
RestoreOption restore_pref = static_cast<RestoreOption>(
prefs->GetInteger(kRestoreAppsAndPagesPrefName));
switch (restore_pref) {
case RestoreOption::kAlways:
Restore();
break;
case RestoreOption::kAskEveryTime:
ShowRestoreNotification(kRestoreNotificationId);
break;
case RestoreOption::kDoNotRestore:
return;
}
}
FullRestoreService::~FullRestoreService() = default;
void FullRestoreService::Shutdown() {
is_shut_down_ = true;
}
void FullRestoreService::ShowRestoreNotification(const std::string& id) {
message_center::RichNotificationData notification_data;
message_center::ButtonInfo restore_button(l10n_util::GetStringUTF16(
base::ToUpperASCII(id == kSetRestorePrefNotificationId
? IDS_SET_RESTORE_NOTIFICATION_BUTTON
: IDS_RESTORE_NOTIFICATION_RESTORE_BUTTON)));
notification_data.buttons.push_back(restore_button);
message_center::ButtonInfo cancel_button(l10n_util::GetStringUTF16(
base::ToUpperASCII(IDS_RESTORE_NOTIFICATION_CANCEL_BUTTON)));
notification_data.buttons.push_back(cancel_button);
int title_id = id == kSetRestorePrefNotificationId
? IDS_SET_RESTORE_NOTIFICATION_TITLE
: IDS_RESTORE_NOTIFICATION_TITLE;
int message_id;
if (id == kRestoreForCrashNotificationId)
message_id = IDS_RESTORE_FOR_CRASH_NOTIFICATION_MESSAGE;
else if (id == kRestoreNotificationId)
message_id = IDS_RESTORE_NOTIFICATION_MESSAGE;
else
message_id = IDS_SET_RESTORE_NOTIFICATION_MESSAGE;
std::unique_ptr<message_center::Notification> notification =
ash::CreateSystemNotification(
message_center::NOTIFICATION_TYPE_SIMPLE, id,
l10n_util::GetStringUTF16(title_id),
l10n_util::GetStringUTF16(message_id),
l10n_util::GetStringUTF16(IDS_RESTORE_NOTIFICATION_DISPLAY_SOURCE),
GURL(),
message_center::NotifierId(
message_center::NotifierType::SYSTEM_COMPONENT, id),
notification_data,
base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
base::BindRepeating(
&FullRestoreService::HandleRestoreNotificationClicked,
weak_ptr_factory_.GetWeakPtr(), id)),
kFullRestoreNotificationIcon,
message_center::SystemNotificationWarningLevel::NORMAL);
notification->set_priority(message_center::SYSTEM_PRIORITY);
auto* notification_display_service =
NotificationDisplayService::GetForProfile(profile_);
DCHECK(notification_display_service);
notification_display_service->Display(NotificationHandler::Type::TRANSIENT,
*notification,
/*metadata=*/nullptr);
}
void FullRestoreService::HandleRestoreNotificationClicked(
const std::string& id,
base::Optional<int> button_index) {
if (!is_shut_down_) {
NotificationDisplayService::GetForProfile(profile_)->Close(
NotificationHandler::Type::TRANSIENT, id);
}
if (!button_index.has_value() ||
button_index.value() !=
static_cast<int>(RestoreNotificationButtonIndex::kRestore)) {
return;
}
if (id == kSetRestorePrefNotificationId) {
// Show the 'On Startup' OS setting page.
chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
profile_, chromeos::settings::mojom::kOnStartupSectionPath);
return;
}
int count = GetRestoreSelectedCountPref(profile_->GetPrefs());
if (count < kMaxConsecutiveRestoreSelectionCount)
SetRestoreSelectedCountPref(profile_->GetPrefs(), ++count);
// If the user selects the 'restore' button for more than 3 times, show the
// set restore pref notification.
if (count >= kMaxConsecutiveRestoreSelectionCount)
ShowRestoreNotification(kSetRestorePrefNotificationId);
Restore();
}
void FullRestoreService::Restore() {
const user_manager::User* user =
chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
if (user) {
::full_restore::FullRestoreInfo::GetInstance()->SetRestoreFlag(
user->GetAccountId(), true);
}
app_launch_handler_->SetShouldRestore();
}
} // namespace full_restore
} // namespace chromeos