summaryrefslogtreecommitdiffstats
path: root/content/browser/dom_storage/dom_storage_namespace.h
blob: 5d18882834d9569b85c9e40794d58a142388d43a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright 2013 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 CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_

#include <map>
#include <vector>

#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/strings/nullable_string16.h"
#include "content/common/content_export.h"
#include "content/public/browser/session_storage_namespace.h"
#include "url/gurl.h"

namespace content {

class DOMStorageArea;
class DOMStorageContextImpl;
class DOMStorageTaskRunner;
class SessionStorageDatabase;

// Container for the set of per-origin Areas.
// See class comments for DOMStorageContextImpl for a larger overview.
class CONTENT_EXPORT DOMStorageNamespace
    : public base::RefCountedThreadSafe<DOMStorageNamespace> {
 public:
  // Option for PurgeMemory.
  enum PurgeOption {
    // Purge unopened areas only.
    PURGE_UNOPENED,

    // Purge aggressively, i.e. discard cache even for areas that have
    // non-zero open count.
    PURGE_AGGRESSIVE,
  };

  // Constructor for a LocalStorage namespace with id of 0
  // and an optional backing directory on disk.
  DOMStorageNamespace(const base::FilePath& directory,  // may be empty
                      DOMStorageTaskRunner* task_runner);

  // Constructor for a SessionStorage namespace with a non-zero id and an
  // optional backing on disk via |session_storage_database| (may be NULL).
  DOMStorageNamespace(int64 namespace_id,
                      const std::string& persistent_namespace_id,
                      SessionStorageDatabase* session_storage_database,
                      DOMStorageTaskRunner* task_runner);

  int64 namespace_id() const { return namespace_id_; }
  const std::string& persistent_namespace_id() const {
    return persistent_namespace_id_;
  }

  // Returns the storage area for the given origin,
  // creating instance if needed. Each call to open
  // must be balanced with a call to CloseStorageArea.
  DOMStorageArea* OpenStorageArea(const GURL& origin);
  void CloseStorageArea(DOMStorageArea* area);

  // Returns the area for |origin| if it's open, otherwise NULL.
  DOMStorageArea* GetOpenStorageArea(const GURL& origin);

  // Creates a clone of |this| namespace including
  // shallow copies of all contained areas.
  // Should only be called for session storage namespaces.
  DOMStorageNamespace* Clone(int64 clone_namespace_id,
                             const std::string& clone_persistent_namespace_id);

  // Creates an alias of |this| namespace.
  // Should only be called for session storage namespaces.
  DOMStorageNamespace* CreateAlias(int64 alias_namespace_id);

  void DeleteLocalStorageOrigin(const GURL& origin);
  void DeleteSessionStorageOrigin(const GURL& origin);
  void PurgeMemory(PurgeOption purge);
  void Shutdown();

  unsigned int CountInMemoryAreas() const;

  void AddTransactionLogProcessId(int process_id);
  void RemoveTransactionLogProcessId(int process_id);
  SessionStorageNamespace::MergeResult Merge(
      bool actually_merge,
      int process_id,
      DOMStorageNamespace* other,
      DOMStorageContextImpl* context);
  DOMStorageNamespace* alias_master_namespace() {
    return alias_master_namespace_.get();
  }
  int num_aliases() const { return num_aliases_; }
  bool ready_for_deletion_pending_aliases() const {
    return ready_for_deletion_pending_aliases_; }
  void set_ready_for_deletion_pending_aliases(bool value) {
    ready_for_deletion_pending_aliases_ = value;
  }
  bool must_persist_at_shutdown() const { return must_persist_at_shutdown_; }
  void set_must_persist_at_shutdown(bool value) {
    must_persist_at_shutdown_ = value;
  }

  enum LogType {
    TRANSACTION_READ,
    TRANSACTION_WRITE,
    TRANSACTION_REMOVE,
    TRANSACTION_CLEAR
  };

  struct CONTENT_EXPORT TransactionRecord {
    LogType transaction_type;
    GURL origin;
    GURL page_url;
    base::string16 key;
    base::NullableString16 value;
    TransactionRecord();
    ~TransactionRecord();
  };

  void AddTransaction(int process_id, const TransactionRecord& transaction);
  bool IsLoggingRenderer(int process_id);
  // Decrements the count of aliases owned by the master, and returns true
  // if the new count is 0.
  bool DecrementMasterAliasCount();

 private:
  friend class base::RefCountedThreadSafe<DOMStorageNamespace>;

  // Struct to hold references to our contained areas and
  // to keep track of how many tabs have a given area open.
  struct AreaHolder {
    scoped_refptr<DOMStorageArea> area_;
    int open_count_;
    AreaHolder();
    AreaHolder(DOMStorageArea* area, int count);
    ~AreaHolder();
  };
  typedef std::map<GURL, AreaHolder> AreaMap;

  struct TransactionData {
    bool max_log_size_exceeded;
    std::vector<TransactionRecord> log;
    TransactionData();
    ~TransactionData();
  };

  ~DOMStorageNamespace();

  // Returns a pointer to the area holder in our map or NULL.
  AreaHolder* GetAreaHolder(const GURL& origin);

  // Switches the current alias DOM storage namespace to a new alias master.
  void SwitchToNewAliasMaster(DOMStorageNamespace* new_master,
                              DOMStorageContextImpl* context);

  int64 namespace_id_;
  std::string persistent_namespace_id_;
  base::FilePath directory_;
  AreaMap areas_;
  scoped_refptr<DOMStorageTaskRunner> task_runner_;
  scoped_refptr<SessionStorageDatabase> session_storage_database_;
  std::map<int, TransactionData*> transactions_;
  int num_aliases_;
  scoped_refptr<DOMStorageNamespace> alias_master_namespace_;
  DOMStorageNamespace* old_master_for_close_area_;
  // Indicates whether we have already decremented |num_aliases_| for this
  // namespace in its alias master. We may only decrement it once, and around
  // deletion, this instance will stick around a bit longer until its refcount
  // drops to 0. Therefore, we want to make sure we don't decrement the master's
  // alias count a second time.
  bool master_alias_count_decremented_;
  // This indicates, for an alias master, that the master itself is ready
  // for deletion, but there are aliases outstanding that we have to wait for
  // before we can start cleaning up the master.
  bool ready_for_deletion_pending_aliases_;
  bool must_persist_at_shutdown_;
};

}  // namespace content


#endif  // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_