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 SYNC_ENGINE_DIRECTORY_COMMIT_CONTRIBUTION_H_
6#define SYNC_ENGINE_DIRECTORY_COMMIT_CONTRIBUTION_H_
7
8#include <vector>
9
10#include "base/gtest_prod_util.h"
11#include "base/memory/scoped_ptr.h"
12#include "sync/base/sync_export.h"
13#include "sync/engine/commit_contribution.h"
14#include "sync/internal_api/public/base/model_type.h"
15#include "sync/internal_api/public/util/syncer_error.h"
16#include "sync/protocol/sync.pb.h"
17#include "sync/sessions/directory_type_debug_info_emitter.h"
18#include "sync/sessions/status_controller.h"
19
20namespace syncer {
21
22namespace sessions {
23class StatusController;
24}  // namespace sessions
25
26namespace syncable {
27class Directory;
28}  // namespace syncable
29
30// This class represents a set of items belonging to a particular data type that
31// have been selected from the syncable Directory and prepared for commit.
32//
33// This class handles the bookkeeping related to the commit of these items,
34// including processing the commit response message and setting and unsetting
35// the SYNCING bits.
36class SYNC_EXPORT_PRIVATE DirectoryCommitContribution
37    : public CommitContribution {
38 public:
39  // This destructor will DCHECK if UnsetSyncingBits() has not been called yet.
40  virtual ~DirectoryCommitContribution();
41
42  // Build a CommitContribution from the IS_UNSYNCED items in |dir| with the
43  // given |type|.  The contribution will include at most |max_items| entries.
44  //
45  // This function may return NULL if this type has no items ready for and
46  // requiring commit.  This function may make model neutral changes to the
47  // directory.
48  static scoped_ptr<DirectoryCommitContribution> Build(
49      syncable::Directory* dir,
50      ModelType type,
51      size_t max_items,
52      DirectoryTypeDebugInfoEmitter* debug_info_emitter);
53
54  // Serialize this contribution's entries to the given commit request |msg|.
55  //
56  // This function is not const.  It will update some state in this contribution
57  // that will be used when processing the associated commit response.  This
58  // function should not be called more than once.
59  virtual void AddToCommitMessage(sync_pb::ClientToServerMessage* msg) OVERRIDE;
60
61  // Updates this contribution's contents in accordance with the provided
62  // |response|.
63  //
64  // This function may make model-neutral changes to the directory.  It is not
65  // valid to call this function unless AddToCommitMessage() was called earlier.
66  // This function should not be called more than once.
67  virtual SyncerError ProcessCommitResponse(
68      const sync_pb::ClientToServerResponse& response,
69      sessions::StatusController* status) OVERRIDE;
70
71  // Cleans up any temporary state associated with the commit.  Must be called
72  // before destruction.
73  virtual void CleanUp() OVERRIDE;
74
75  // Returns the number of entries included in this contribution.
76  virtual size_t GetNumEntries() const OVERRIDE;
77
78 private:
79  class DirectoryCommitContributionTest;
80  FRIEND_TEST_ALL_PREFIXES(DirectoryCommitContributionTest, GatherByTypes);
81  FRIEND_TEST_ALL_PREFIXES(DirectoryCommitContributionTest,
82                           GatherAndTruncate);
83
84  DirectoryCommitContribution(
85      const std::vector<int64>& metahandles,
86      const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities,
87      const sync_pb::DataTypeContext& context,
88      syncable::Directory* directory,
89      DirectoryTypeDebugInfoEmitter* debug_info_emitter);
90
91  void UnsetSyncingBits();
92
93  syncable::Directory* dir_;
94  const std::vector<int64> metahandles_;
95  const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity> entities_;
96  sync_pb::DataTypeContext context_;
97  size_t entries_start_index_;
98
99  // This flag is tracks whether or not the directory entries associated with
100  // this commit still have their SYNCING bits set.  These bits will be set when
101  // the CommitContribution is created with Build() and unset when CleanUp() is
102  // called.  This flag must be unset by the time our destructor is called.
103  bool syncing_bits_set_;
104
105  // A pointer to the commit counters of our parent CommitContributor.
106  DirectoryTypeDebugInfoEmitter* debug_info_emitter_;
107
108  DISALLOW_COPY_AND_ASSIGN(DirectoryCommitContribution);
109};
110
111}  // namespace syncer
112
113#endif  // SYNC_ENGINE_DIRECTORY_COMMIT_CONTRIBUTION_H_
114