| // 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> |
| |
| namespace base { |
| 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_; |
| #elif defined(OS_MACOSX) |
| base::mac::ScopedNSAutoreleasePool autorelease_pool_; |
| #endif |
| }; |
| |
| #if defined(OS_POSIX) |
| namespace testing { |
| // Prefix |directory| to the path where the RLZ data file lives, for tests. |
| void SetRlzStoreDirectory(const base::FilePath& directory); |
| |
| // Returns the path of the file used as data store. |
| std::string RlzStoreFilenameStr(); |
| } // namespace testing |
| #endif // defined(OS_POSIX) |
| |
| } // namespace rlz_lib |
| |
| #endif // RLZ_VALUE_STORE_H_ |