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#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_SYNCABLE_SERVICE_H__
6#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_SYNCABLE_SERVICE_H__
7
8#if !defined(PASSWORD_MANAGER_ENABLE_SYNC)
9#error "Only build this file when sync is enabled in Password Manager."
10#endif
11
12#include <string>
13#include <vector>
14
15#include "base/memory/scoped_ptr.h"
16#include "base/threading/non_thread_safe.h"
17#include "components/password_manager/core/browser/password_store_change.h"
18#include "sync/api/sync_change.h"
19#include "sync/api/sync_data.h"
20#include "sync/api/sync_error.h"
21#include "sync/api/syncable_service.h"
22#include "sync/protocol/password_specifics.pb.h"
23#include "sync/protocol/sync.pb.h"
24
25namespace autofill {
26struct PasswordForm;
27}
28
29namespace syncer {
30class SyncErrorFactory;
31}
32
33namespace password_manager {
34
35class PasswordStoreSync;
36
37// The implementation of the SyncableService API for passwords.
38class PasswordSyncableService : public syncer::SyncableService,
39                                public base::NonThreadSafe {
40 public:
41  // Since the constructed |PasswordSyncableService| is typically owned by the
42  // |password_store|, the constructor doesn't take ownership of the
43  // |password_store|.
44  explicit PasswordSyncableService(PasswordStoreSync* password_store);
45  virtual ~PasswordSyncableService();
46
47  // syncer::SyncableService:
48  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
49      syncer::ModelType type,
50      const syncer::SyncDataList& initial_sync_data,
51      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
52      scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
53  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
54  virtual syncer::SyncDataList GetAllSyncData(
55      syncer::ModelType type) const OVERRIDE;
56  virtual syncer::SyncError ProcessSyncChanges(
57      const tracked_objects::Location& from_here,
58      const syncer::SyncChangeList& change_list) OVERRIDE;
59
60  // Notifies the Sync engine of changes to the password database.
61  void ActOnPasswordStoreChanges(const PasswordStoreChangeList& changes);
62
63  // Provides a StartSyncFlare to the SyncableService. See
64  // chrome/browser/sync/glue/sync_start_util.h for more.
65  void InjectStartSyncFlare(
66      const syncer::SyncableService::StartSyncFlare& flare);
67
68 private:
69  typedef std::vector<autofill::PasswordForm*> PasswordForms;
70  // Map from password sync tag to password form.
71  typedef std::map<std::string, autofill::PasswordForm*> PasswordEntryMap;
72
73  // The type of PasswordStoreSync::AddLoginImpl,
74  // PasswordStoreSync::UpdateLoginImpl and PasswordStoreSync::RemoveLoginImpl.
75  typedef PasswordStoreChangeList(PasswordStoreSync::*DatabaseOperation)(
76      const autofill::PasswordForm& form);
77
78  struct SyncEntries;
79
80  // Retrieves the entries from password db and fills both |password_entries|
81  // and |passwords_entry_map|. |passwords_entry_map| can be NULL.
82  bool ReadFromPasswordStore(
83      ScopedVector<autofill::PasswordForm>* password_entries,
84      PasswordEntryMap* passwords_entry_map) const;
85
86  // Uses the |PasswordStore| APIs to change entries.
87  void WriteToPasswordStore(const SyncEntries& entries);
88
89  // Examines |data|, an entry in sync db, and updates |sync_entries| or
90  // |updated_db_entries| accordingly. An element is removed from
91  // |unmatched_data_from_password_db| if its tag is identical to |data|'s.
92  void CreateOrUpdateEntry(
93      const syncer::SyncData& data,
94      PasswordEntryMap* unmatched_data_from_password_db,
95      SyncEntries* sync_entries,
96      syncer::SyncChangeList* updated_db_entries);
97
98  // Calls |operation| for each element in |entries| and appends the changes to
99  // |all_changes|.
100  void WriteEntriesToDatabase(
101      DatabaseOperation operation,
102      const PasswordForms& entries,
103      PasswordStoreChangeList* all_changes);
104
105  // The factory that creates sync errors. |SyncError| has rich data
106  // suitable for debugging.
107  scoped_ptr<syncer::SyncErrorFactory> sync_error_factory_;
108
109  // |sync_processor_| will mirror the |PasswordStore| changes in the sync db.
110  scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
111
112  // The password store that adds/updates/deletes password entries. Not owned.
113  PasswordStoreSync* const password_store_;
114
115  // A signal activated by this class to start sync as soon as possible.
116  syncer::SyncableService::StartSyncFlare flare_;
117
118  // True if processing sync changes is in progress.
119  bool is_processing_sync_changes_;
120
121  DISALLOW_COPY_AND_ASSIGN(PasswordSyncableService);
122};
123
124}  // namespace password_manager
125
126#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_SYNCABLE_SERVICE_H__
127