1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/sync/backup_rollback_controller.h"
6
7#include "base/command_line.h"
8#include "base/message_loop/message_loop.h"
9#include "base/metrics/field_trial.h"
10#include "chrome/browser/sync/supervised_user_signin_manager_wrapper.h"
11#include "chrome/common/chrome_switches.h"
12#include "components/sync_driver/sync_prefs.h"
13
14namespace browser_sync {
15
16#if defined(ENABLE_PRE_SYNC_BACKUP)
17// Number of rollback attempts to try before giving up.
18static const int kRollbackLimits = 3;
19
20// Finch experiment name and group.
21static char kSyncBackupFinchName[] = "SyncBackup";
22static char kSyncBackupFinchDisabled[] = "disabled";
23#endif
24
25BackupRollbackController::BackupRollbackController(
26    sync_driver::SyncPrefs* sync_prefs,
27    const SupervisedUserSigninManagerWrapper* signin,
28    base::Closure start_backup,
29    base::Closure start_rollback)
30    : sync_prefs_(sync_prefs),
31      signin_(signin),
32      start_backup_(start_backup),
33      start_rollback_(start_rollback) {
34}
35
36BackupRollbackController::~BackupRollbackController() {
37}
38
39bool BackupRollbackController::StartBackup() {
40  if (!IsBackupEnabled())
41    return false;
42
43  // Disable rollback to previous backup DB because it will be overwritten by
44  // new backup.
45  sync_prefs_->SetRemainingRollbackTries(0);
46  base::MessageLoop::current()->PostTask(FROM_HERE, start_backup_);
47  return true;
48}
49
50bool BackupRollbackController::StartRollback() {
51  if (!IsBackupEnabled())
52    return false;
53
54  // Don't roll back if disabled or user is signed in.
55  if (CommandLine::ForCurrentProcess()->HasSwitch(
56          switches::kSyncDisableRollback) ||
57      !signin_->GetEffectiveUsername().empty()) {
58    sync_prefs_->SetRemainingRollbackTries(0);
59    return false;
60  }
61
62  int rollback_tries = sync_prefs_->GetRemainingRollbackTries();
63  if (rollback_tries <= 0)
64    return false;   // No pending rollback.
65
66  sync_prefs_->SetRemainingRollbackTries(rollback_tries - 1);
67  base::MessageLoop::current()->PostTask(FROM_HERE, start_rollback_);
68  return true;
69}
70
71void BackupRollbackController::OnRollbackReceived() {
72#if defined(ENABLE_PRE_SYNC_BACKUP)
73  sync_prefs_->SetRemainingRollbackTries(kRollbackLimits);
74#endif
75}
76
77void BackupRollbackController::OnRollbackDone() {
78#if defined(ENABLE_PRE_SYNC_BACKUP)
79  sync_prefs_->SetRemainingRollbackTries(0);
80#endif
81}
82
83// static
84bool BackupRollbackController::IsBackupEnabled() {
85#if defined(ENABLE_PRE_SYNC_BACKUP)
86  const std::string group_name =
87      base::FieldTrialList::FindFullName(kSyncBackupFinchName);
88
89  if (CommandLine::ForCurrentProcess()->HasSwitch(
90          switches::kSyncDisableBackup) ||
91      group_name == kSyncBackupFinchDisabled)  {
92    return false;
93  }
94  return true;
95#else
96  return false;
97#endif
98}
99
100}  // namespace browser_sync
101