Home | History | Annotate | Download | only in dom_storage
      1 // Copyright 2013 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 CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
      6 #define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
      7 
      8 #include <map>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/files/file_path.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/strings/nullable_string16.h"
     15 #include "content/common/content_export.h"
     16 #include "content/public/browser/session_storage_namespace.h"
     17 #include "url/gurl.h"
     18 
     19 namespace content {
     20 
     21 class DOMStorageArea;
     22 class DOMStorageContextImpl;
     23 class DOMStorageTaskRunner;
     24 class SessionStorageDatabase;
     25 
     26 // Container for the set of per-origin Areas.
     27 // See class comments for DOMStorageContextImpl for a larger overview.
     28 class CONTENT_EXPORT DOMStorageNamespace
     29     : public base::RefCountedThreadSafe<DOMStorageNamespace> {
     30  public:
     31   // Option for PurgeMemory.
     32   enum PurgeOption {
     33     // Purge unopened areas only.
     34     PURGE_UNOPENED,
     35 
     36     // Purge aggressively, i.e. discard cache even for areas that have
     37     // non-zero open count.
     38     PURGE_AGGRESSIVE,
     39   };
     40 
     41   // Constructor for a LocalStorage namespace with id of 0
     42   // and an optional backing directory on disk.
     43   DOMStorageNamespace(const base::FilePath& directory,  // may be empty
     44                       DOMStorageTaskRunner* task_runner);
     45 
     46   // Constructor for a SessionStorage namespace with a non-zero id and an
     47   // optional backing on disk via |session_storage_database| (may be NULL).
     48   DOMStorageNamespace(int64 namespace_id,
     49                       const std::string& persistent_namespace_id,
     50                       SessionStorageDatabase* session_storage_database,
     51                       DOMStorageTaskRunner* task_runner);
     52 
     53   int64 namespace_id() const { return namespace_id_; }
     54   const std::string& persistent_namespace_id() const {
     55     return persistent_namespace_id_;
     56   }
     57 
     58   // Returns the storage area for the given origin,
     59   // creating instance if needed. Each call to open
     60   // must be balanced with a call to CloseStorageArea.
     61   DOMStorageArea* OpenStorageArea(const GURL& origin);
     62   void CloseStorageArea(DOMStorageArea* area);
     63 
     64   // Returns the area for |origin| if it's open, otherwise NULL.
     65   DOMStorageArea* GetOpenStorageArea(const GURL& origin);
     66 
     67   // Creates a clone of |this| namespace including
     68   // shallow copies of all contained areas.
     69   // Should only be called for session storage namespaces.
     70   DOMStorageNamespace* Clone(int64 clone_namespace_id,
     71                              const std::string& clone_persistent_namespace_id);
     72 
     73   // Creates an alias of |this| namespace.
     74   // Should only be called for session storage namespaces.
     75   DOMStorageNamespace* CreateAlias(int64 alias_namespace_id);
     76 
     77   void DeleteLocalStorageOrigin(const GURL& origin);
     78   void DeleteSessionStorageOrigin(const GURL& origin);
     79   void PurgeMemory(PurgeOption purge);
     80   void Shutdown();
     81 
     82   unsigned int CountInMemoryAreas() const;
     83 
     84   void AddTransactionLogProcessId(int process_id);
     85   void RemoveTransactionLogProcessId(int process_id);
     86   SessionStorageNamespace::MergeResult Merge(
     87       bool actually_merge,
     88       int process_id,
     89       DOMStorageNamespace* other,
     90       DOMStorageContextImpl* context);
     91   DOMStorageNamespace* alias_master_namespace() {
     92     return alias_master_namespace_.get();
     93   }
     94   int num_aliases() const { return num_aliases_; }
     95   bool ready_for_deletion_pending_aliases() const {
     96     return ready_for_deletion_pending_aliases_; }
     97   void set_ready_for_deletion_pending_aliases(bool value) {
     98     ready_for_deletion_pending_aliases_ = value;
     99   }
    100   bool must_persist_at_shutdown() const { return must_persist_at_shutdown_; }
    101   void set_must_persist_at_shutdown(bool value) {
    102     must_persist_at_shutdown_ = value;
    103   }
    104 
    105   enum LogType {
    106     TRANSACTION_READ,
    107     TRANSACTION_WRITE,
    108     TRANSACTION_REMOVE,
    109     TRANSACTION_CLEAR
    110   };
    111 
    112   struct CONTENT_EXPORT TransactionRecord {
    113     LogType transaction_type;
    114     GURL origin;
    115     GURL page_url;
    116     base::string16 key;
    117     base::NullableString16 value;
    118     TransactionRecord();
    119     ~TransactionRecord();
    120   };
    121 
    122   void AddTransaction(int process_id, const TransactionRecord& transaction);
    123   bool IsLoggingRenderer(int process_id);
    124   // Decrements the count of aliases owned by the master, and returns true
    125   // if the new count is 0.
    126   bool DecrementMasterAliasCount();
    127 
    128  private:
    129   friend class base::RefCountedThreadSafe<DOMStorageNamespace>;
    130 
    131   // Struct to hold references to our contained areas and
    132   // to keep track of how many tabs have a given area open.
    133   struct AreaHolder {
    134     scoped_refptr<DOMStorageArea> area_;
    135     int open_count_;
    136     AreaHolder();
    137     AreaHolder(DOMStorageArea* area, int count);
    138     ~AreaHolder();
    139   };
    140   typedef std::map<GURL, AreaHolder> AreaMap;
    141 
    142   struct TransactionData {
    143     bool max_log_size_exceeded;
    144     std::vector<TransactionRecord> log;
    145     TransactionData();
    146     ~TransactionData();
    147   };
    148 
    149   ~DOMStorageNamespace();
    150 
    151   // Returns a pointer to the area holder in our map or NULL.
    152   AreaHolder* GetAreaHolder(const GURL& origin);
    153 
    154   // Switches the current alias DOM storage namespace to a new alias master.
    155   void SwitchToNewAliasMaster(DOMStorageNamespace* new_master,
    156                               DOMStorageContextImpl* context);
    157 
    158   int64 namespace_id_;
    159   std::string persistent_namespace_id_;
    160   base::FilePath directory_;
    161   AreaMap areas_;
    162   scoped_refptr<DOMStorageTaskRunner> task_runner_;
    163   scoped_refptr<SessionStorageDatabase> session_storage_database_;
    164   std::map<int, TransactionData*> transactions_;
    165   int num_aliases_;
    166   scoped_refptr<DOMStorageNamespace> alias_master_namespace_;
    167   DOMStorageNamespace* old_master_for_close_area_;
    168   // Indicates whether we have already decremented |num_aliases_| for this
    169   // namespace in its alias master. We may only decrement it once, and around
    170   // deletion, this instance will stick around a bit longer until its refcount
    171   // drops to 0. Therefore, we want to make sure we don't decrement the master's
    172   // alias count a second time.
    173   bool master_alias_count_decremented_;
    174   // This indicates, for an alias master, that the master itself is ready
    175   // for deletion, but there are aliases outstanding that we have to wait for
    176   // before we can start cleaning up the master.
    177   bool ready_for_deletion_pending_aliases_;
    178   bool must_persist_at_shutdown_;
    179 };
    180 
    181 }  // namespace content
    182 
    183 
    184 #endif  // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_NAMESPACE_H_
    185