Home | History | Annotate | Download | only in dom_storage
      1 // Copyright (c) 2012 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_CONTEXT_IMPL_H_
      6 #define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <vector>
     11 
     12 #include "base/atomic_sequence_num.h"
     13 #include "base/basictypes.h"
     14 #include "base/files/file_path.h"
     15 #include "base/gtest_prod_util.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/observer_list.h"
     18 #include "base/time/time.h"
     19 #include "content/common/content_export.h"
     20 #include "url/gurl.h"
     21 
     22 namespace base {
     23 class FilePath;
     24 class NullableString16;
     25 class Time;
     26 }
     27 
     28 namespace quota {
     29 class SpecialStoragePolicy;
     30 }
     31 
     32 namespace content {
     33 
     34 class DOMStorageArea;
     35 class DOMStorageNamespace;
     36 class DOMStorageSession;
     37 class DOMStorageTaskRunner;
     38 class SessionStorageDatabase;
     39 struct LocalStorageUsageInfo;
     40 struct SessionStorageUsageInfo;
     41 
     42 // The Context is the root of an object containment hierachy for
     43 // Namespaces and Areas related to the owning profile.
     44 // One instance is allocated in the main process for each profile,
     45 // instance methods should be called serially in the background as
     46 // determined by the task_runner. Specifcally not on chrome's non-blocking
     47 // IO thread since these methods can result in blocking file io.
     48 //
     49 // In general terms, the DOMStorage object relationships are...
     50 //   Contexts (per-profile) own Namespaces which own Areas which share Maps.
     51 //   Hosts(per-renderer) refer to Namespaces and Areas open in its renderer.
     52 //   Sessions (per-tab) cause the creation and deletion of session Namespaces.
     53 //
     54 // Session Namespaces are cloned by initially making a shallow copy of
     55 // all contained Areas, the shallow copies refer to the same refcounted Map,
     56 // and does a deep copy-on-write if needed.
     57 //
     58 // Classes intended to be used by an embedder are DOMStorageContextImpl,
     59 // DOMStorageHost, and DOMStorageSession. The other classes are for
     60 // internal consumption.
     61 class CONTENT_EXPORT DOMStorageContextImpl
     62     : public base::RefCountedThreadSafe<DOMStorageContextImpl> {
     63  public:
     64   // An interface for observing Local and Session Storage events on the
     65   // background thread.
     66   class EventObserver {
     67    public:
     68     // |old_value| may be null on initial insert.
     69     virtual void OnDOMStorageItemSet(
     70         const DOMStorageArea* area,
     71         const base::string16& key,
     72         const base::string16& new_value,
     73         const base::NullableString16& old_value,
     74         const GURL& page_url) = 0;
     75     virtual void OnDOMStorageItemRemoved(
     76         const DOMStorageArea* area,
     77         const base::string16& key,
     78         const base::string16& old_value,
     79         const GURL& page_url) = 0;
     80     virtual void OnDOMStorageAreaCleared(
     81         const DOMStorageArea* area,
     82         const GURL& page_url) = 0;
     83 
     84    protected:
     85     virtual ~EventObserver() {}
     86   };
     87 
     88   // |localstorage_directory| and |sessionstorage_directory| may be empty
     89   // for incognito browser contexts.
     90   DOMStorageContextImpl(
     91       const base::FilePath& localstorage_directory,
     92       const base::FilePath& sessionstorage_directory,
     93       quota::SpecialStoragePolicy* special_storage_policy,
     94       DOMStorageTaskRunner* task_runner);
     95 
     96   // Returns the directory path for localStorage, or an empty directory, if
     97   // there is no backing on disk.
     98   const base::FilePath& localstorage_directory() {
     99     return localstorage_directory_;
    100   }
    101 
    102   // Returns the directory path for sessionStorage, or an empty directory, if
    103   // there is no backing on disk.
    104   const base::FilePath& sessionstorage_directory() {
    105     return sessionstorage_directory_;
    106   }
    107 
    108   DOMStorageTaskRunner* task_runner() const { return task_runner_.get(); }
    109   DOMStorageNamespace* GetStorageNamespace(int64 namespace_id);
    110 
    111   void GetLocalStorageUsage(std::vector<LocalStorageUsageInfo>* infos,
    112                             bool include_file_info);
    113   void GetSessionStorageUsage(std::vector<SessionStorageUsageInfo>* infos);
    114   void DeleteLocalStorage(const GURL& origin);
    115   void DeleteSessionStorage(const SessionStorageUsageInfo& usage_info);
    116   void PurgeMemory();
    117 
    118   // Used by content settings to alter the behavior around
    119   // what data to keep and what data to discard at shutdown.
    120   // The policy is not so straight forward to describe, see
    121   // the implementation for details.
    122   void SetForceKeepSessionState() {
    123     force_keep_session_state_ = true;
    124   }
    125 
    126   // Called when the owning BrowserContext is ending.
    127   // Schedules the commit of any unsaved changes and will delete
    128   // and keep data on disk per the content settings and special storage
    129   // policies. Contained areas and namespaces will stop functioning after
    130   // this method has been called.
    131   void Shutdown();
    132 
    133   // Methods to add, remove, and notify EventObservers.
    134   void AddEventObserver(EventObserver* observer);
    135   void RemoveEventObserver(EventObserver* observer);
    136   void NotifyItemSet(
    137       const DOMStorageArea* area,
    138       const base::string16& key,
    139       const base::string16& new_value,
    140       const base::NullableString16& old_value,
    141       const GURL& page_url);
    142   void NotifyItemRemoved(
    143       const DOMStorageArea* area,
    144       const base::string16& key,
    145       const base::string16& old_value,
    146       const GURL& page_url);
    147   void NotifyAreaCleared(
    148       const DOMStorageArea* area,
    149       const GURL& page_url);
    150 
    151   // May be called on any thread.
    152   int64 AllocateSessionId() {
    153     return session_id_sequence_.GetNext();
    154   }
    155 
    156   std::string AllocatePersistentSessionId();
    157 
    158   // Must be called on the background thread.
    159   void CreateSessionNamespace(int64 namespace_id,
    160                               const std::string& persistent_namespace_id);
    161   void DeleteSessionNamespace(int64 namespace_id, bool should_persist_data);
    162   void CloneSessionNamespace(int64 existing_id, int64 new_id,
    163                              const std::string& new_persistent_id);
    164 
    165   // Starts backing sessionStorage on disk. This function must be called right
    166   // after DOMStorageContextImpl is created, before it's used.
    167   void SetSaveSessionStorageOnDisk();
    168 
    169   // Deletes all namespaces which don't have an associated DOMStorageNamespace
    170   // alive. This function is used for deleting possible leftover data after an
    171   // unclean exit.
    172   void StartScavengingUnusedSessionStorage();
    173 
    174  private:
    175   friend class DOMStorageContextImplTest;
    176   FRIEND_TEST_ALL_PREFIXES(DOMStorageContextImplTest, Basics);
    177   friend class base::RefCountedThreadSafe<DOMStorageContextImpl>;
    178   typedef std::map<int64, scoped_refptr<DOMStorageNamespace> >
    179       StorageNamespaceMap;
    180 
    181   ~DOMStorageContextImpl();
    182 
    183   void ClearSessionOnlyOrigins();
    184 
    185   // For scavenging unused sessionStorages.
    186   void FindUnusedNamespaces();
    187   void FindUnusedNamespacesInCommitSequence(
    188       const std::set<std::string>& namespace_ids_in_use,
    189       const std::set<std::string>& protected_persistent_session_ids);
    190   void DeleteNextUnusedNamespace();
    191   void DeleteNextUnusedNamespaceInCommitSequence();
    192 
    193   // Collection of namespaces keyed by id.
    194   StorageNamespaceMap namespaces_;
    195 
    196   // Where localstorage data is stored, maybe empty for the incognito use case.
    197   base::FilePath localstorage_directory_;
    198 
    199   // Where sessionstorage data is stored, maybe empty for the incognito use
    200   // case. Always empty until the file-backed session storage feature is
    201   // implemented.
    202   base::FilePath sessionstorage_directory_;
    203 
    204   // Used to schedule sequenced background tasks.
    205   scoped_refptr<DOMStorageTaskRunner> task_runner_;
    206 
    207   // List of objects observing local storage events.
    208   ObserverList<EventObserver> event_observers_;
    209 
    210   // We use a 32 bit identifier for per tab storage sessions.
    211   // At a tab per second, this range is large enough for 68 years.
    212   base::AtomicSequenceNumber session_id_sequence_;
    213 
    214   bool is_shutdown_;
    215   bool force_keep_session_state_;
    216   scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
    217   scoped_refptr<SessionStorageDatabase> session_storage_database_;
    218 
    219   // For cleaning up unused namespaces gradually.
    220   bool scavenging_started_;
    221   std::vector<std::string> deletable_persistent_namespace_ids_;
    222 
    223   // Persistent namespace IDs to protect from gradual deletion (they will
    224   // be needed for session restore).
    225   std::set<std::string> protected_persistent_session_ids_;
    226 
    227   // Mapping between persistent namespace IDs and namespace IDs for
    228   // sessionStorage.
    229   std::map<std::string, int64> persistent_namespace_id_to_namespace_id_;
    230 };
    231 
    232 }  // namespace content
    233 
    234 #endif  // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_CONTEXT_IMPL_H_
    235