1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/nullable_string16.h"
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/common/content_export.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/session_storage_namespace.h"
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "url/gurl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace content {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass DOMStorageArea;
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class DOMStorageContextImpl;
23bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass DOMStorageTaskRunner;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionStorageDatabase;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Container for the set of per-origin Areas.
27bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// See class comments for DOMStorageContextImpl for a larger overview.
28bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass CONTENT_EXPORT DOMStorageNamespace
29bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    : public base::RefCountedThreadSafe<DOMStorageNamespace> {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Option for PurgeMemory.
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum PurgeOption {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Purge unopened areas only.
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PURGE_UNOPENED,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Purge aggressively, i.e. discard cache even for areas that have
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // non-zero open count.
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PURGE_AGGRESSIVE,
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructor for a LocalStorage namespace with id of 0
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and an optional backing directory on disk.
43bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageNamespace(const base::FilePath& directory,  // may be empty
44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                      DOMStorageTaskRunner* task_runner);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructor for a SessionStorage namespace with a non-zero id and an
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // optional backing on disk via |session_storage_database| (may be NULL).
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageNamespace(int64 namespace_id,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& persistent_namespace_id,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SessionStorageDatabase* session_storage_database,
51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                      DOMStorageTaskRunner* task_runner);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 namespace_id() const { return namespace_id_; }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& persistent_namespace_id() const {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return persistent_namespace_id_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the storage area for the given origin,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creating instance if needed. Each call to open
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // must be balanced with a call to CloseStorageArea.
61bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageArea* OpenStorageArea(const GURL& origin);
62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void CloseStorageArea(DOMStorageArea* area);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the area for |origin| if it's open, otherwise NULL.
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageArea* GetOpenStorageArea(const GURL& origin);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a clone of |this| namespace including
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shallow copies of all contained areas.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be called for session storage namespaces.
70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageNamespace* Clone(int64 clone_namespace_id,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& clone_persistent_namespace_id);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates an alias of |this| namespace.
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Should only be called for session storage namespaces.
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* CreateAlias(int64 alias_namespace_id);
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteLocalStorageOrigin(const GURL& origin);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteSessionStorageOrigin(const GURL& origin);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void PurgeMemory(PurgeOption purge);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Shutdown();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned int CountInMemoryAreas() const;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void AddTransactionLogProcessId(int process_id);
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void RemoveTransactionLogProcessId(int process_id);
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SessionStorageNamespace::MergeResult Merge(
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool actually_merge,
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int process_id,
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DOMStorageNamespace* other,
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DOMStorageContextImpl* context);
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* alias_master_namespace() {
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return alias_master_namespace_.get();
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int num_aliases() const { return num_aliases_; }
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ready_for_deletion_pending_aliases() const {
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return ready_for_deletion_pending_aliases_; }
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_ready_for_deletion_pending_aliases(bool value) {
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ready_for_deletion_pending_aliases_ = value;
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool must_persist_at_shutdown() const { return must_persist_at_shutdown_; }
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_must_persist_at_shutdown(bool value) {
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    must_persist_at_shutdown_ = value;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  enum LogType {
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRANSACTION_READ,
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRANSACTION_WRITE,
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRANSACTION_REMOVE,
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TRANSACTION_CLEAR
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  struct CONTENT_EXPORT TransactionRecord {
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LogType transaction_type;
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GURL origin;
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GURL page_url;
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::string16 key;
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::NullableString16 value;
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TransactionRecord();
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ~TransactionRecord();
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void AddTransaction(int process_id, const TransactionRecord& transaction);
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool IsLoggingRenderer(int process_id);
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Decrements the count of aliases owned by the master, and returns true
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // if the new count is 0.
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool DecrementMasterAliasCount();
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
129bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class base::RefCountedThreadSafe<DOMStorageNamespace>;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Struct to hold references to our contained areas and
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to keep track of how many tabs have a given area open.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct AreaHolder {
134bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<DOMStorageArea> area_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int open_count_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AreaHolder();
137bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    AreaHolder(DOMStorageArea* area, int count);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~AreaHolder();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, AreaHolder> AreaMap;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  struct TransactionData {
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool max_log_size_exceeded;
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::vector<TransactionRecord> log;
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TransactionData();
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ~TransactionData();
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
149bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ~DOMStorageNamespace();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a pointer to the area holder in our map or NULL.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AreaHolder* GetAreaHolder(const GURL& origin);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Switches the current alias DOM storage namespace to a new alias master.
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SwitchToNewAliasMaster(DOMStorageNamespace* new_master,
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              DOMStorageContextImpl* context);
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 namespace_id_;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string persistent_namespace_id_;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath directory_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AreaMap areas_;
162bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageTaskRunner> task_runner_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SessionStorageDatabase> session_storage_database_;
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::map<int, TransactionData*> transactions_;
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int num_aliases_;
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<DOMStorageNamespace> alias_master_namespace_;
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* old_master_for_close_area_;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Indicates whether we have already decremented |num_aliases_| for this
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // namespace in its alias master. We may only decrement it once, and around
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // deletion, this instance will stick around a bit longer until its refcount
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // drops to 0. Therefore, we want to make sure we don't decrement the master's
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // alias count a second time.
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool master_alias_count_decremented_;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This indicates, for an alias master, that the master itself is ready
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // for deletion, but there are aliases outstanding that we have to wait for
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // before we can start cleaning up the master.
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ready_for_deletion_pending_aliases_;
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool must_persist_at_shutdown_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace content
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif  // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
185