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 GOOGLE_APIS_GCM_ENGINE_GCM_STORE_IMPL_H_
6 #define GOOGLE_APIS_GCM_ENGINE_GCM_STORE_IMPL_H_
7 
8 #include <stdint.h>
9 
10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h"
13 #include "google_apis/gcm/base/gcm_export.h"
14 #include "google_apis/gcm/engine/gcm_store.h"
15 
16 namespace base {
17 class FilePath;
18 class SequencedTaskRunner;
19 }  // namespace base
20 
21 namespace gcm {
22 
23 class Encryptor;
24 
25 // An implementation of GCM Store that uses LevelDB for persistence.
26 // It performs all blocking operations on the blocking task runner, and posts
27 // all callbacks to the thread on which the GCMStoreImpl is created.
28 class GCM_EXPORT GCMStoreImpl : public GCMStore {
29  public:
30   // |remove_account_mappings_with_email_key| indicates whether account mappings
31   // having email as account key should be removed while loading. This is
32   // required during the migration of account identifier from email to Gaia ID.
33   GCMStoreImpl(const base::FilePath& path,
34                bool remove_account_mappings_with_email_key,
35                scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
36                std::unique_ptr<Encryptor> encryptor);
37   ~GCMStoreImpl() override;
38 
39   // Load the directory and pass the initial state back to caller.
40   void Load(StoreOpenMode open_mode, LoadCallback callback) override;
41 
42   // Closes the GCM store.
43   void Close() override;
44 
45   // Clears the GCM store of all data and destroys any LevelDB files associated
46   // with this store.
47   // WARNING: this will permanently destroy any pending outgoing messages
48   // and require the device to re-create credentials and serial number mapping
49   // tables.
50   void Destroy(UpdateCallback callback) override;
51 
52   // Sets this device's messaging credentials.
53   void SetDeviceCredentials(uint64_t device_android_id,
54                             uint64_t device_security_token,
55                             UpdateCallback callback) override;
56 
57   // Registration info.
58   void AddRegistration(const std::string& serialized_key,
59                        const std::string& serialized_value,
60                        UpdateCallback callback) override;
61   void RemoveRegistration(const std::string& serialized_key,
62                           UpdateCallback callback) override;
63 
64   // Unacknowledged incoming message handling.
65   void AddIncomingMessage(const std::string& persistent_id,
66                           UpdateCallback callback) override;
67   void RemoveIncomingMessage(const std::string& persistent_id,
68                              UpdateCallback callback) override;
69   void RemoveIncomingMessages(const PersistentIdList& persistent_ids,
70                               UpdateCallback callback) override;
71 
72   // Unacknowledged outgoing messages handling.
73   bool AddOutgoingMessage(const std::string& persistent_id,
74                           const MCSMessage& message,
75                           UpdateCallback callback) override;
76   void OverwriteOutgoingMessage(const std::string& persistent_id,
77                                 const MCSMessage& message,
78                                 UpdateCallback callback) override;
79   void RemoveOutgoingMessage(const std::string& persistent_id,
80                              UpdateCallback callback) override;
81   void RemoveOutgoingMessages(const PersistentIdList& persistent_ids,
82                               UpdateCallback callback) override;
83 
84   // Sets last device's checkin information.
85   void SetLastCheckinInfo(const base::Time& time,
86                           const std::set<std::string>& accounts,
87                           UpdateCallback callback) override;
88 
89   // G-service settings handling.
90   void SetGServicesSettings(const std::map<std::string, std::string>& settings,
91                             const std::string& settings_digest,
92                             UpdateCallback callback) override;
93 
94   // Sets the account information related to device to account mapping.
95   void AddAccountMapping(const AccountMapping& account_mapping,
96                          UpdateCallback callback) override;
97   void RemoveAccountMapping(const CoreAccountId& account_id,
98                             UpdateCallback callback) override;
99 
100   // Sets last token fetch time.
101   void SetLastTokenFetchTime(const base::Time& time,
102                              UpdateCallback callback) override;
103 
104   // Sets the custom client heartbeat interval for the scope.
105   void AddHeartbeatInterval(const std::string& scope,
106                             int interval_ms,
107                             UpdateCallback callback) override;
108   void RemoveHeartbeatInterval(const std::string& scope,
109                                UpdateCallback callback) override;
110 
111   // Instance ID data.
112   void AddInstanceIDData(const std::string& app_id,
113                          const std::string& instance_id_data,
114                          UpdateCallback callback) override;
115   void RemoveInstanceIDData(const std::string& app_id,
116                             UpdateCallback callback) override;
117 
118   // Injects a value to database. Only to be used for testing.
119   void SetValueForTesting(const std::string& key,
120                           const std::string& value,
121                           UpdateCallback callback);
122 
123  private:
124   typedef std::map<std::string, int> AppIdToMessageCountMap;
125 
126   // Continuation to update the per-app message counts after a load.
127   void LoadContinuation(LoadCallback callback,
128                         std::unique_ptr<LoadResult> result);
129 
130   // Continuation to update the per-app message counts when adding messages.
131   // In particular, if a message fails to add, the message count is decremented.
132   void AddOutgoingMessageContinuation(UpdateCallback callback,
133                                       const std::string& app_id,
134                                       bool success);
135 
136   // Continuation to update the per-app message counts when removing messages.
137   // Note: if doing a read-then-write when removing messages proves expensive,
138   // an in-memory mapping of persisted message id to app could be maintained
139   // instead.
140   void RemoveOutgoingMessagesContinuation(
141       UpdateCallback callback,
142       bool success,
143       const std::map<std::string, int>& removed_message_counts);
144 
145   class Backend;
146 
147   // Map of App ids to their message counts.
148   AppIdToMessageCountMap app_message_counts_;
149 
150   scoped_refptr<Backend> backend_;
151   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
152 
153   base::WeakPtrFactory<GCMStoreImpl> weak_ptr_factory_{this};
154 
155   DISALLOW_COPY_AND_ASSIGN(GCMStoreImpl);
156 };
157 
158 }  // namespace gcm
159 
160 #endif  // GOOGLE_APIS_GCM_ENGINE_GCM_STORE_IMPL_H_
161