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 EXTENSIONS_BROWSER_API_STORAGE_STORAGE_API_H_
6#define EXTENSIONS_BROWSER_API_STORAGE_STORAGE_API_H_
7
8#include "base/compiler_specific.h"
9#include "base/memory/ref_counted.h"
10#include "extensions/browser/api/storage/settings_namespace.h"
11#include "extensions/browser/api/storage/settings_observer.h"
12#include "extensions/browser/extension_function.h"
13#include "extensions/browser/value_store/value_store.h"
14
15namespace extensions {
16
17// Superclass of all settings functions.
18class SettingsFunction : public UIThreadExtensionFunction {
19 protected:
20  SettingsFunction();
21  virtual ~SettingsFunction();
22
23  // ExtensionFunction:
24  virtual bool ShouldSkipQuotaLimiting() const OVERRIDE;
25  virtual ResponseAction Run() OVERRIDE;
26
27  // Extension settings function implementations should do their work here.
28  // The StorageFrontend makes sure this is posted to the appropriate thread.
29  virtual ResponseValue RunWithStorage(ValueStore* storage) = 0;
30
31  // Handles the |result| of a read function.
32  // - If the result succeeded, this will set |result_| and return.
33  // - If |result| failed with a ValueStore::CORRUPTION error, this will call
34  //   RestoreStorageAndRetry(), and return that result.
35  // - If the |result| failed with a different error, this will set |error_|
36  //   and return.
37  ResponseValue UseReadResult(ValueStore::ReadResult result,
38                              ValueStore* storage);
39
40  // Handles the |result| of a write function.
41  // - If the result succeeded, this will set |result_| and return.
42  // - If |result| failed with a ValueStore::CORRUPTION error, this will call
43  //   RestoreStorageAndRetry(), and return that result.
44  // - If the |result| failed with a different error, this will set |error_|
45  //   and return.
46  // This will also send out a change notification, if appropriate.
47  ResponseValue UseWriteResult(ValueStore::WriteResult result,
48                               ValueStore* storage);
49
50 private:
51  // Called via PostTask from Run. Calls RunWithStorage and then
52  // SendResponse with its success value.
53  void AsyncRunWithStorage(ValueStore* storage);
54
55  // Called if we encounter a ValueStore error. If the error is due to
56  // corruption, tries to restore the ValueStore and re-run the API function.
57  // If the storage cannot be restored or was due to some other error, then sets
58  // error and returns. This also sets the |tried_restoring_storage_| flag to
59  // ensure we don't enter a loop.
60  ResponseValue HandleError(const ValueStore::Error& error,
61                            ValueStore* storage);
62
63  // The settings namespace the call was for.  For example, SYNC if the API
64  // call was chrome.settings.experimental.sync..., LOCAL if .local, etc.
65  settings_namespace::Namespace settings_namespace_;
66
67  // A flag indicating whether or not we have tried to restore storage. We
68  // should only ever try once (per API call) in order to avoid entering a loop.
69  bool tried_restoring_storage_;
70
71  // Observers, cached so that it's only grabbed from the UI thread.
72  scoped_refptr<SettingsObserverList> observers_;
73};
74
75class StorageStorageAreaGetFunction : public SettingsFunction {
76 public:
77  DECLARE_EXTENSION_FUNCTION("storage.get", STORAGE_GET)
78
79 protected:
80  virtual ~StorageStorageAreaGetFunction() {}
81
82  // SettingsFunction:
83  virtual ResponseValue RunWithStorage(ValueStore* storage) OVERRIDE;
84};
85
86class StorageStorageAreaSetFunction : public SettingsFunction {
87 public:
88  DECLARE_EXTENSION_FUNCTION("storage.set", STORAGE_SET)
89
90 protected:
91  virtual ~StorageStorageAreaSetFunction() {}
92
93  // SettingsFunction:
94  virtual ResponseValue RunWithStorage(ValueStore* storage) OVERRIDE;
95
96  // ExtensionFunction:
97  virtual void GetQuotaLimitHeuristics(
98      QuotaLimitHeuristics* heuristics) const OVERRIDE;
99};
100
101class StorageStorageAreaRemoveFunction : public SettingsFunction {
102 public:
103  DECLARE_EXTENSION_FUNCTION("storage.remove", STORAGE_REMOVE)
104
105 protected:
106  virtual ~StorageStorageAreaRemoveFunction() {}
107
108  // SettingsFunction:
109  virtual ResponseValue RunWithStorage(ValueStore* storage) OVERRIDE;
110
111  // ExtensionFunction:
112  virtual void GetQuotaLimitHeuristics(
113      QuotaLimitHeuristics* heuristics) const OVERRIDE;
114};
115
116class StorageStorageAreaClearFunction : public SettingsFunction {
117 public:
118  DECLARE_EXTENSION_FUNCTION("storage.clear", STORAGE_CLEAR)
119
120 protected:
121  virtual ~StorageStorageAreaClearFunction() {}
122
123  // SettingsFunction:
124  virtual ResponseValue RunWithStorage(ValueStore* storage) OVERRIDE;
125
126  // ExtensionFunction:
127  virtual void GetQuotaLimitHeuristics(
128      QuotaLimitHeuristics* heuristics) const OVERRIDE;
129};
130
131class StorageStorageAreaGetBytesInUseFunction : public SettingsFunction {
132 public:
133  DECLARE_EXTENSION_FUNCTION("storage.getBytesInUse", STORAGE_GETBYTESINUSE)
134
135 protected:
136  virtual ~StorageStorageAreaGetBytesInUseFunction() {}
137
138  // SettingsFunction:
139  virtual ResponseValue RunWithStorage(ValueStore* storage) OVERRIDE;
140};
141
142}  // namespace extensions
143
144#endif  // EXTENSIONS_BROWSER_API_STORAGE_STORAGE_API_H_
145