dom/quota/QuotaManager.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef mozilla_dom_quota_quotamanager_h__
     8 #define mozilla_dom_quota_quotamanager_h__
    10 #include "QuotaCommon.h"
    12 #include "nsIObserver.h"
    13 #include "nsIQuotaManager.h"
    15 #include "mozilla/dom/Nullable.h"
    16 #include "mozilla/Mutex.h"
    18 #include "nsClassHashtable.h"
    19 #include "nsRefPtrHashtable.h"
    21 #include "ArrayCluster.h"
    22 #include "Client.h"
    23 #include "PersistenceType.h"
    24 #include "StoragePrivilege.h"
    26 #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
    28 class nsIOfflineStorage;
    29 class nsIPrincipal;
    30 class nsIThread;
    31 class nsITimer;
    32 class nsIURI;
    33 class nsPIDOMWindow;
    34 class nsIRunnable;
    36 BEGIN_QUOTA_NAMESPACE
    38 class AcquireListener;
    39 class AsyncUsageRunnable;
    40 class CheckQuotaHelper;
    41 class CollectOriginsHelper;
    42 class FinalizeOriginEvictionRunnable;
    43 class GroupInfo;
    44 class GroupInfoPair;
    45 class OriginClearRunnable;
    46 class OriginInfo;
    47 class OriginOrPatternString;
    48 class QuotaObject;
    49 class ResetOrClearRunnable;
    50 struct SynchronizedOp;
    52 class QuotaManager MOZ_FINAL : public nsIQuotaManager,
    53                                public nsIObserver
    54 {
    55   friend class AsyncUsageRunnable;
    56   friend class CollectOriginsHelper;
    57   friend class FinalizeOriginEvictionRunnable;
    58   friend class GroupInfo;
    59   friend class OriginClearRunnable;
    60   friend class OriginInfo;
    61   friend class QuotaObject;
    62   friend class ResetOrClearRunnable;
    64   enum MozBrowserPatternFlag
    65   {
    66     MozBrowser = 0,
    67     NotMozBrowser,
    68     IgnoreMozBrowser
    69   };
    71   typedef void
    72   (*WaitingOnStoragesCallback)(nsTArray<nsCOMPtr<nsIOfflineStorage> >&, void*);
    74 public:
    75   NS_DECL_ISUPPORTS
    76   NS_DECL_NSIQUOTAMANAGER
    77   NS_DECL_NSIOBSERVER
    79   // Returns a non-owning reference.
    80   static QuotaManager*
    81   GetOrCreate();
    83   // Returns a non-owning reference.
    84   static QuotaManager*
    85   Get();
    87   // Returns an owning reference! No one should call this but the factory.
    88   static QuotaManager*
    89   FactoryCreate();
    91   // Returns true if we've begun the shutdown process.
    92   static bool IsShuttingDown();
    94   void
    95   InitQuotaForOrigin(PersistenceType aPersistenceType,
    96                      const nsACString& aGroup,
    97                      const nsACString& aOrigin,
    98                      uint64_t aLimitBytes,
    99                      uint64_t aUsageBytes,
   100                      int64_t aAccessTime);
   102   void
   103   DecreaseUsageForOrigin(PersistenceType aPersistenceType,
   104                          const nsACString& aGroup,
   105                          const nsACString& aOrigin,
   106                          int64_t aSize);
   108   void
   109   UpdateOriginAccessTime(PersistenceType aPersistenceType,
   110                          const nsACString& aGroup,
   111                          const nsACString& aOrigin);
   113   void
   114   RemoveQuota();
   116   void
   117   RemoveQuotaForPersistenceType(PersistenceType);
   119   void
   120   RemoveQuotaForOrigin(PersistenceType aPersistenceType,
   121                        const nsACString& aGroup,
   122                        const nsACString& aOrigin)
   123   {
   124     MutexAutoLock lock(mQuotaMutex);
   125     LockedRemoveQuotaForOrigin(aPersistenceType, aGroup, aOrigin);
   126   }
   128   void
   129   RemoveQuotaForPattern(PersistenceType aPersistenceType,
   130                         const nsACString& aPattern);
   132   already_AddRefed<QuotaObject>
   133   GetQuotaObject(PersistenceType aPersistenceType,
   134                  const nsACString& aGroup,
   135                  const nsACString& aOrigin,
   136                  nsIFile* aFile);
   138   already_AddRefed<QuotaObject>
   139   GetQuotaObject(PersistenceType aPersistenceType,
   140                  const nsACString& aGroup,
   141                  const nsACString& aOrigin,
   142                  const nsAString& aPath);
   144   // Set the Window that the current thread is doing operations for.
   145   // The caller is responsible for ensuring that aWindow is held alive.
   146   static void
   147   SetCurrentWindow(nsPIDOMWindow* aWindow)
   148   {
   149     QuotaManager* quotaManager = Get();
   150     NS_ASSERTION(quotaManager, "Must have a manager here!");
   152     quotaManager->SetCurrentWindowInternal(aWindow);
   153   }
   155   static void
   156   CancelPromptsForWindow(nsPIDOMWindow* aWindow)
   157   {
   158     NS_ASSERTION(aWindow, "Passed null window!");
   160     QuotaManager* quotaManager = Get();
   161     NS_ASSERTION(quotaManager, "Must have a manager here!");
   163     quotaManager->CancelPromptsForWindowInternal(aWindow);
   164   }
   166   // Called when a storage is created.
   167   bool
   168   RegisterStorage(nsIOfflineStorage* aStorage);
   170   // Called when a storage is being unlinked or destroyed.
   171   void
   172   UnregisterStorage(nsIOfflineStorage* aStorage);
   174   // Called when a storage has been closed.
   175   void
   176   OnStorageClosed(nsIOfflineStorage* aStorage);
   178   // Called when a window is being purged from the bfcache or the user leaves
   179   // a page which isn't going into the bfcache. Forces any live storage
   180   // objects to close themselves and aborts any running transactions.
   181   void
   182   AbortCloseStoragesForWindow(nsPIDOMWindow* aWindow);
   184   // Used to check if there are running transactions in a given window.
   185   bool
   186   HasOpenTransactions(nsPIDOMWindow* aWindow);
   188   // Waits for storages to be cleared and for version change transactions to
   189   // complete before dispatching the given runnable.
   190   nsresult
   191   WaitForOpenAllowed(const OriginOrPatternString& aOriginOrPattern,
   192                      Nullable<PersistenceType> aPersistenceType,
   193                      const nsACString& aId, nsIRunnable* aRunnable);
   195   // Acquire exclusive access to the storage given (waits for all others to
   196   // close).  If storages need to close first, the callback will be invoked
   197   // with an array of said storages.
   198   nsresult
   199   AcquireExclusiveAccess(nsIOfflineStorage* aStorage,
   200                          const nsACString& aOrigin,
   201                          Nullable<PersistenceType> aPersistenceType,
   202                          AcquireListener* aListener,
   203                          WaitingOnStoragesCallback aCallback,
   204                          void* aClosure)
   205   {
   206     NS_ASSERTION(aStorage, "Need a storage here!");
   207     return AcquireExclusiveAccess(aOrigin, aPersistenceType, aStorage,
   208                                   aListener, aCallback, aClosure);
   209   }
   211   nsresult
   212   AcquireExclusiveAccess(const nsACString& aOrigin,
   213                          Nullable<PersistenceType> aPersistenceType,
   214                          AcquireListener* aListener,
   215                          WaitingOnStoragesCallback aCallback,
   216                          void* aClosure)
   217   {
   218     return AcquireExclusiveAccess(aOrigin, aPersistenceType, nullptr,
   219                                   aListener, aCallback, aClosure);
   220   }
   222   void
   223   AllowNextSynchronizedOp(const OriginOrPatternString& aOriginOrPattern,
   224                           Nullable<PersistenceType> aPersistenceType,
   225                           const nsACString& aId);
   227   bool
   228   IsClearOriginPending(const nsACString& aPattern,
   229                        Nullable<PersistenceType> aPersistenceType)
   230   {
   231     return !!FindSynchronizedOp(aPattern, aPersistenceType, EmptyCString());
   232   }
   234   nsresult
   235   GetDirectoryForOrigin(PersistenceType aPersistenceType,
   236                         const nsACString& aASCIIOrigin,
   237                         nsIFile** aDirectory) const;
   239   nsresult
   240   EnsureOriginIsInitialized(PersistenceType aPersistenceType,
   241                             const nsACString& aGroup,
   242                             const nsACString& aOrigin,
   243                             bool aTrackQuota,
   244                             nsIFile** aDirectory);
   246   void
   247   OriginClearCompleted(PersistenceType aPersistenceType,
   248                        const OriginOrPatternString& aOriginOrPattern);
   250   void
   251   ResetOrClearCompleted();
   253   void
   254   AssertCurrentThreadOwnsQuotaMutex()
   255   {
   256     mQuotaMutex.AssertCurrentThreadOwns();
   257   }
   259   nsIThread*
   260   IOThread()
   261   {
   262     NS_ASSERTION(mIOThread, "This should never be null!");
   263     return mIOThread;
   264   }
   266   already_AddRefed<Client>
   267   GetClient(Client::Type aClientType);
   269   const nsString&
   270   GetStoragePath(PersistenceType aPersistenceType) const
   271   {
   272     if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
   273       return mPersistentStoragePath;
   274     }
   276     NS_ASSERTION(aPersistenceType == PERSISTENCE_TYPE_TEMPORARY, "Huh?");
   278     return mTemporaryStoragePath;
   279   }
   281   uint64_t
   282   GetGroupLimit() const;
   284   static uint32_t
   285   GetStorageQuotaMB();
   287   static void
   288   GetStorageId(PersistenceType aPersistenceType,
   289                const nsACString& aOrigin,
   290                Client::Type aClientType,
   291                const nsAString& aName,
   292                nsACString& aDatabaseId);
   294   static nsresult
   295   GetInfoFromURI(nsIURI* aURI,
   296                  uint32_t aAppId,
   297                  bool aInMozBrowser,
   298                  nsACString* aGroup,
   299                  nsACString* aASCIIOrigin,
   300                  StoragePrivilege* aPrivilege,
   301                  PersistenceType* aDefaultPersistenceType);
   303   static nsresult
   304   GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
   305                        nsACString* aGroup,
   306                        nsACString* aASCIIOrigin,
   307                        StoragePrivilege* aPrivilege,
   308                        PersistenceType* aDefaultPersistenceType);
   310   static nsresult
   311   GetInfoFromWindow(nsPIDOMWindow* aWindow,
   312                     nsACString* aGroup,
   313                     nsACString* aASCIIOrigin,
   314                     StoragePrivilege* aPrivilege,
   315                     PersistenceType* aDefaultPersistenceType);
   317   static void
   318   GetInfoForChrome(nsACString* aGroup,
   319                    nsACString* aASCIIOrigin,
   320                    StoragePrivilege* aPrivilege,
   321                    PersistenceType* aDefaultPersistenceType);
   323   static void
   324   GetOriginPatternString(uint32_t aAppId, bool aBrowserOnly,
   325                          const nsACString& aOrigin, nsAutoCString& _retval)
   326   {
   327     return GetOriginPatternString(aAppId,
   328                                   aBrowserOnly ? MozBrowser : NotMozBrowser,
   329                                   aOrigin, _retval);
   330   }
   332   static void
   333   GetOriginPatternStringMaybeIgnoreBrowser(uint32_t aAppId, bool aBrowserOnly,
   334                                            nsAutoCString& _retval)
   335   {
   336     return GetOriginPatternString(aAppId,
   337                                   aBrowserOnly ? MozBrowser : IgnoreMozBrowser,
   338                                   EmptyCString(), _retval);
   339   }
   341 private:
   342   QuotaManager();
   344   virtual ~QuotaManager();
   346   nsresult
   347   Init();
   349   void
   350   SetCurrentWindowInternal(nsPIDOMWindow* aWindow);
   352   void
   353   CancelPromptsForWindowInternal(nsPIDOMWindow* aWindow);
   355   // Determine if the quota is lifted for the Window the current thread is
   356   // using.
   357   bool
   358   LockedQuotaIsLifted();
   360   uint64_t
   361   LockedCollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
   362                                   nsTArray<OriginInfo*>& aOriginInfos);
   364   void
   365   LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
   366                              const nsACString& aGroup,
   367                              const nsACString& aOrigin);
   369   nsresult
   370   AcquireExclusiveAccess(const nsACString& aOrigin,
   371                          Nullable<PersistenceType> aPersistenceType,
   372                          nsIOfflineStorage* aStorage,
   373                          AcquireListener* aListener,
   374                          WaitingOnStoragesCallback aCallback,
   375                          void* aClosure);
   377   void
   378   AddSynchronizedOp(const OriginOrPatternString& aOriginOrPattern,
   379                     Nullable<PersistenceType> aPersistenceType);
   381   nsresult
   382   RunSynchronizedOp(nsIOfflineStorage* aStorage,
   383                     SynchronizedOp* aOp);
   385   SynchronizedOp*
   386   FindSynchronizedOp(const nsACString& aPattern,
   387                      Nullable<PersistenceType> aPersistenceType,
   388                      const nsACString& aId);
   390   nsresult
   391   MaybeUpgradeIndexedDBDirectory();
   393   nsresult
   394   InitializeOrigin(PersistenceType aPersistenceType,
   395                    const nsACString& aGroup,
   396                    const nsACString& aOrigin,
   397                    bool aTrackQuota,
   398                    int64_t aAccessTime,
   399                    nsIFile* aDirectory);
   401   nsresult
   402   ClearStoragesForApp(uint32_t aAppId, bool aBrowserOnly);
   404   void
   405   CheckTemporaryStorageLimits();
   407   // Collect inactive and the least recently used origins.
   408   uint64_t
   409   CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
   410                             nsTArray<OriginInfo*>& aOriginInfos);
   412   void
   413   DeleteTemporaryFilesForOrigin(const nsACString& aOrigin);
   415   void
   416   FinalizeOriginEviction(nsTArray<nsCString>& aOrigins);
   418   void
   419   SaveOriginAccessTime(const nsACString& aOrigin, int64_t aTimestamp);
   421   void
   422   ReleaseIOThreadObjects()
   423   {
   424     AssertIsOnIOThread();
   426     for (uint32_t index = 0; index < Client::TYPE_MAX; index++) {
   427       mClients[index]->ReleaseIOThreadObjects();
   428     }
   429   }
   431   static void
   432   GetOriginPatternString(uint32_t aAppId,
   433                          MozBrowserPatternFlag aBrowserFlag,
   434                          const nsACString& aOrigin,
   435                          nsAutoCString& _retval);
   437   static PLDHashOperator
   438   RemoveQuotaForPersistenceTypeCallback(const nsACString& aKey,
   439                                         nsAutoPtr<GroupInfoPair>& aValue,
   440                                         void* aUserArg);
   442   static PLDHashOperator
   443   RemoveQuotaCallback(const nsACString& aKey,
   444                       nsAutoPtr<GroupInfoPair>& aValue,
   445                       void* aUserArg);
   447   static PLDHashOperator
   448   RemoveQuotaForPatternCallback(const nsACString& aKey,
   449                                 nsAutoPtr<GroupInfoPair>& aValue,
   450                                 void* aUserArg);
   452   static PLDHashOperator
   453   GetOriginsExceedingGroupLimit(const nsACString& aKey,
   454                                 GroupInfoPair* aValue,
   455                                 void* aUserArg);
   457   static PLDHashOperator
   458   GetAllTemporaryStorageOrigins(const nsACString& aKey,
   459                                 GroupInfoPair* aValue,
   460                                 void* aUserArg);
   462   static PLDHashOperator
   463   AddTemporaryStorageOrigins(const nsACString& aKey,
   464                              ArrayCluster<nsIOfflineStorage*>* aValue,
   465                              void* aUserArg);
   467   static PLDHashOperator
   468   GetInactiveTemporaryStorageOrigins(const nsACString& aKey,
   469                                      GroupInfoPair* aValue,
   470                                      void* aUserArg);
   472   // TLS storage index for the current thread's window.
   473   unsigned int mCurrentWindowIndex;
   475   mozilla::Mutex mQuotaMutex;
   477   nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
   479   // A map of Windows to the corresponding quota helper.
   480   nsRefPtrHashtable<nsPtrHashKey<nsPIDOMWindow>,
   481                     CheckQuotaHelper> mCheckQuotaHelpers;
   483   // Maintains a list of live storages per origin.
   484   nsClassHashtable<nsCStringHashKey,
   485                    ArrayCluster<nsIOfflineStorage*> > mLiveStorages;
   487   // Maintains a list of synchronized operatons that are in progress or queued.
   488   nsAutoTArray<nsAutoPtr<SynchronizedOp>, 5> mSynchronizedOps;
   490   // Thread on which IO is performed.
   491   nsCOMPtr<nsIThread> mIOThread;
   493   // A timer that gets activated at shutdown to ensure we close all storages.
   494   nsCOMPtr<nsITimer> mShutdownTimer;
   496   // A list of all successfully initialized origins. This list isn't protected
   497   // by any mutex but it is only ever touched on the IO thread.
   498   nsTArray<nsCString> mInitializedOrigins;
   500   nsAutoTArray<nsRefPtr<Client>, Client::TYPE_MAX> mClients;
   502   nsString mIndexedDBPath;
   503   nsString mPersistentStoragePath;
   504   nsString mTemporaryStoragePath;
   506   uint64_t mTemporaryStorageLimit;
   507   uint64_t mTemporaryStorageUsage;
   508   bool mTemporaryStorageInitialized;
   510   bool mStorageAreaInitialized;
   511 };
   513 class AutoEnterWindow
   514 {
   515 public:
   516   AutoEnterWindow(nsPIDOMWindow* aWindow)
   517   {
   518     QuotaManager::SetCurrentWindow(aWindow);
   519   }
   521   ~AutoEnterWindow()
   522   {
   523     QuotaManager::SetCurrentWindow(nullptr);
   524   }
   525 };
   527 END_QUOTA_NAMESPACE
   529 #endif /* mozilla_dom_quota_quotamanager_h__ */

mercurial