Index: rlz/lib/rlz_value_store.h |
=================================================================== |
--- rlz/lib/rlz_value_store.h (revision 0) |
+++ rlz/lib/rlz_value_store.h (revision 0) |
@@ -0,0 +1,116 @@ |
+// Copyright (c) 2012 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. |
+ |
+#ifndef RLZ_VALUE_STORE_H_ |
+#define RLZ_VALUE_STORE_H_ |
+ |
+#include "base/basictypes.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "rlz/lib/rlz_enums.h" |
+ |
+#if defined(OS_WIN) |
+#include "rlz/win/lib/lib_mutex.h" |
+#endif |
+ |
+#if defined(OS_MACOSX) |
+#include "base/mac/scoped_nsautorelease_pool.h" |
+#endif |
+ |
+ |
+#include <string> |
+#include <vector> |
+ |
+class FilePath; |
+ |
+namespace rlz_lib { |
+ |
+// Abstracts away rlz's key value store. On windows, this usually writes to |
+// the registry. On mac, it writes to an NSDefaults object. |
+class RlzValueStore { |
+ public: |
+ virtual ~RlzValueStore() {} |
+ |
+ enum AccessType { kReadAccess, kWriteAccess }; |
+ virtual bool HasAccess(AccessType type) = 0; |
+ |
+ // Ping times. |
+ virtual bool WritePingTime(Product product, int64 time) = 0; |
+ virtual bool ReadPingTime(Product product, int64* time) = 0; |
+ virtual bool ClearPingTime(Product product) = 0; |
+ |
+ // Access point RLZs. |
+ virtual bool WriteAccessPointRlz(AccessPoint access_point, |
+ const char* new_rlz) = 0; |
+ virtual bool ReadAccessPointRlz(AccessPoint access_point, |
+ char* rlz, // At most kMaxRlzLength + 1 bytes |
+ size_t rlz_size) = 0; |
+ virtual bool ClearAccessPointRlz(AccessPoint access_point) = 0; |
+ |
+ // Product events. |
+ // Stores |event_rlz| for product |product| as product event. |
+ virtual bool AddProductEvent(Product product, const char* event_rlz) = 0; |
+ // Appends all events for |product| to |events|, in arbirtrary order. |
+ virtual bool ReadProductEvents(Product product, |
+ std::vector<std::string>* events) = 0; |
+ // Removes the stored event |event_rlz| for |product| if it exists. |
+ virtual bool ClearProductEvent(Product product, const char* event_rlz) = 0; |
+ // Removes all stored product events for |product|. |
+ virtual bool ClearAllProductEvents(Product product) = 0; |
+ |
+ // Stateful events. |
+ // Stores |event_rlz| for product |product| as stateful event. |
+ virtual bool AddStatefulEvent(Product product, const char* event_rlz) = 0; |
+ // Checks if |event_rlz| has been stored as stateful event for |product|. |
+ virtual bool IsStatefulEvent(Product product, const char* event_rlz) = 0; |
+ // Removes all stored stateful events for |product|. |
+ virtual bool ClearAllStatefulEvents(Product product) = 0; |
+ |
+ // Tells the value store to clean up unimportant internal data structures, for |
+ // example empty registry folders, that might remain after clearing other |
+ // data. Best-effort. |
+ virtual void CollectGarbage() = 0; |
+}; |
+ |
+// All methods of RlzValueStore must stays consistent even when accessed from |
+// multiple threads in multiple processes. To enforce this through the type |
+// system, the only way to access the RlzValueStore is through a |
+// ScopedRlzValueStoreLock, which is a cross-process lock. It is active while |
+// it is in scope. If the class fails to acquire a lock, its GetStore() method |
+// returns NULL. If the lock fails to be acquired, it must not be taken |
+// recursively. That is, all user code should look like this: |
+// ScopedRlzValueStoreLock lock; |
+// RlzValueStore* store = lock.GetStore(); |
+// if (!store) |
+// return some_error_code; |
+// ... |
+class ScopedRlzValueStoreLock { |
+ public: |
+ ScopedRlzValueStoreLock(); |
+ ~ScopedRlzValueStoreLock(); |
+ |
+ // Returns a RlzValueStore protected by a cross-process lock, or NULL if the |
+ // lock can't be obtained. The lifetime of the returned object is limited to |
+ // the lifetime of this ScopedRlzValueStoreLock object. |
+ RlzValueStore* GetStore(); |
+ |
+ private: |
+ scoped_ptr<RlzValueStore> store_; |
+#if defined(OS_WIN) |
+ LibMutex lock_; |
+#else |
+ base::mac::ScopedNSAutoreleasePool autorelease_pool_; |
+#endif |
+}; |
+ |
+#if defined(OS_MACOSX) |
+namespace testing { |
+// Prefix |directory| to the path where the RLZ data file lives, for tests. |
+void SetRlzStoreDirectory(const FilePath& directory); |
+} // namespace testing |
+#endif // defined(OS_MACOSX) |
+ |
+ |
+} // namespace rlz_lib |
+ |
+#endif // RLZ_VALUE_STORE_H_ |