forked from mirrors/gecko-dev
		
	Memory is no longer just privite browsing data, now it is a cache. This means we have to store more in it, but also that reads don't need to hit disk. We also start using those new member variable databases here. Differential Revision: https://phabricator.services.mozilla.com/D165298
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | 
						|
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 | 
						|
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
#ifndef MOZILLA_IDENTITYCREDENTIALSTORAGESERVICE_H_
 | 
						|
#define MOZILLA_IDENTITYCREDENTIALSTORAGESERVICE_H_
 | 
						|
 | 
						|
#include "ErrorList.h"
 | 
						|
#include "mozilla/AlreadyAddRefed.h"
 | 
						|
#include "mozilla/dom/FlippedOnce.h"
 | 
						|
#include "mozilla/Monitor.h"
 | 
						|
#include "mozilla/OriginAttributes.h"
 | 
						|
#include "mozIStorageConnection.h"
 | 
						|
#include "mozIStorageFunction.h"
 | 
						|
#include "nsIAsyncShutdown.h"
 | 
						|
#include "nsIIdentityCredentialStorageService.h"
 | 
						|
#include "nsIObserver.h"
 | 
						|
#include "nsISupports.h"
 | 
						|
#include "nsThreadUtils.h"
 | 
						|
 | 
						|
namespace mozilla {
 | 
						|
 | 
						|
class IdentityCredentialStorageService final
 | 
						|
    : public nsIIdentityCredentialStorageService,
 | 
						|
      public nsIObserver,
 | 
						|
      public nsIAsyncShutdownBlocker {
 | 
						|
 public:
 | 
						|
  NS_DECL_THREADSAFE_ISUPPORTS
 | 
						|
  NS_DECL_NSIIDENTITYCREDENTIALSTORAGESERVICE
 | 
						|
  NS_DECL_NSIOBSERVER
 | 
						|
  NS_DECL_NSIASYNCSHUTDOWNBLOCKER
 | 
						|
 | 
						|
  // Returns the singleton instance. Used by the component manager
 | 
						|
  static already_AddRefed<IdentityCredentialStorageService> GetSingleton();
 | 
						|
 | 
						|
  // Singletons shouldn't have copy constructors or assignment operators
 | 
						|
  IdentityCredentialStorageService(const IdentityCredentialStorageService&) =
 | 
						|
      delete;
 | 
						|
  IdentityCredentialStorageService& operator=(
 | 
						|
      const IdentityCredentialStorageService&) = delete;
 | 
						|
 | 
						|
 private:
 | 
						|
  IdentityCredentialStorageService()
 | 
						|
      : mMonitor("mozilla::IdentityCredentialStorageService::mMonitor"),
 | 
						|
        mPendingWrites(0){};
 | 
						|
  ~IdentityCredentialStorageService() = default;
 | 
						|
 | 
						|
  // Spins up the service. This includes firing off async work in a worker
 | 
						|
  // thread. This should always be called before other use of the service to
 | 
						|
  // prevent deadlock.
 | 
						|
  nsresult Init();
 | 
						|
 | 
						|
  // Wait (non-blocking) until the service is fully initialized. We may be
 | 
						|
  // waiting for that async work started by Init().
 | 
						|
  nsresult WaitForInitialization();
 | 
						|
 | 
						|
  // Utility function to grab the correct barrier this service needs to shut
 | 
						|
  // down by
 | 
						|
  already_AddRefed<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() const;
 | 
						|
 | 
						|
  // Called to indicate to the async shutdown service that we are all wrapped
 | 
						|
  // up. This also spins down the worker thread, since it is called after all
 | 
						|
  // disk database connections are closed.
 | 
						|
  void Finalize();
 | 
						|
 | 
						|
  // Utility function to make sure a principal is an acceptable primary (RP)
 | 
						|
  // principal
 | 
						|
  static nsresult ValidatePrincipal(nsIPrincipal* aPrincipal);
 | 
						|
 | 
						|
  // Helper functions to initialize the database connections. Also makes sure
 | 
						|
  // the tables are present and have up to date schemas.
 | 
						|
  nsresult GetMemoryDatabaseConnection();
 | 
						|
  nsresult GetDiskDatabaseConnection();
 | 
						|
  static nsresult GetDatabaseConnectionInternal(
 | 
						|
      mozIStorageConnection** aDatabase, nsIFile* aFile);
 | 
						|
 | 
						|
  // Helper function for the Get*DatabaseConnection functions to ensure the
 | 
						|
  // tables are present and have up to date schemas.
 | 
						|
  static nsresult EnsureTable(mozIStorageConnection* aDatabase);
 | 
						|
 | 
						|
  // Grab all data from the disk database and insert it into the memory
 | 
						|
  // database/ This is used at start up
 | 
						|
  nsresult LoadMemoryTableFromDisk();
 | 
						|
 | 
						|
  // Used to (thread-safely) track how many operations have been launched to the
 | 
						|
  // worker thread so that we can wait for it to hit zero before close the disk
 | 
						|
  // database connection
 | 
						|
  void IncrementPendingWrites();
 | 
						|
  void DecrementPendingWrites();
 | 
						|
 | 
						|
  // Helper functions for database writes.
 | 
						|
  //   We have helper functions here for all operations we perform on the
 | 
						|
  //   databases that invlolve writes. These are split out and take a connection
 | 
						|
  //   as an argument because we have to write to both the memory database and
 | 
						|
  //   the disk database, where we only read from the memory database after
 | 
						|
  //   initialization. See nsIIdentityCredentialStorageService.idl for more info
 | 
						|
  //   on these functions' semantics
 | 
						|
 | 
						|
  // Upsert == Update or Insert! Uses some nice SQLite syntax to make this easy.
 | 
						|
  static nsresult UpsertData(mozIStorageConnection* aDatabaseConnection,
 | 
						|
                             nsIPrincipal* aRPPrincipal,
 | 
						|
                             nsIPrincipal* aIDPPrincipal,
 | 
						|
                             nsACString const& aCredentialID, bool aRegistered,
 | 
						|
                             bool aAllowLogout);
 | 
						|
 | 
						|
  static nsresult DeleteData(mozIStorageConnection* aDatabaseConnection,
 | 
						|
                             nsIPrincipal* aRPPrincipal,
 | 
						|
                             nsIPrincipal* aIDPPrincipal,
 | 
						|
                             nsACString const& aCredentialID);
 | 
						|
 | 
						|
  static nsresult ClearData(mozIStorageConnection* aDatabaseConnection);
 | 
						|
 | 
						|
  static nsresult DeleteDataFromOriginAttributesPattern(
 | 
						|
      mozIStorageConnection* aDatabaseConnection,
 | 
						|
      OriginAttributesPattern const& aOriginAttributesPattern);
 | 
						|
 | 
						|
  static nsresult DeleteDataFromTimeRange(
 | 
						|
      mozIStorageConnection* aDatabaseConnection, int64_t aStart, int64_t aEnd);
 | 
						|
 | 
						|
  static nsresult DeleteDataFromPrincipal(
 | 
						|
      mozIStorageConnection* aDatabaseConnection, nsIPrincipal* aPrincipal);
 | 
						|
 | 
						|
  static nsresult DeleteDataFromBaseDomain(
 | 
						|
      mozIStorageConnection* aDatabaseConnection,
 | 
						|
      nsACString const& aBaseDomain);
 | 
						|
 | 
						|
  // Database connections. Guaranteed to be non-null and working once
 | 
						|
  // initialized and not-yet finalized
 | 
						|
  RefPtr<mozIStorageConnection> mDiskDatabaseConnection;  // Worker thread only
 | 
						|
  RefPtr<mozIStorageConnection>
 | 
						|
      mMemoryDatabaseConnection;  // Main thread only after initialization,
 | 
						|
                                  // worker thread only before initialization.
 | 
						|
 | 
						|
  // Worker thread. This should be a valid thread after Init() returns and be
 | 
						|
  // destroyed when we finalize
 | 
						|
  nsCOMPtr<nsISerialEventTarget> mBackgroundThread;  // main thread only
 | 
						|
 | 
						|
  // The database file handle. We can only create this in the main thread and
 | 
						|
  // need it in the worker to perform blocking disk IO. So we put it on this,
 | 
						|
  // since we pass this to the worker anyway
 | 
						|
  nsCOMPtr<nsIFile> mDatabaseFile;  // initialized in the main thread, read-only
 | 
						|
                                    // in worker thread
 | 
						|
 | 
						|
  // Service state management. We protect these variables with a monitor. This
 | 
						|
  // monitor is also used to signal the completion of initialization and
 | 
						|
  // finalization performed in the worker thread.
 | 
						|
  Monitor mMonitor;
 | 
						|
  FlippedOnce<false> mInitialized MOZ_GUARDED_BY(mMonitor);
 | 
						|
  FlippedOnce<false> mErrored MOZ_GUARDED_BY(mMonitor);
 | 
						|
  FlippedOnce<false> mShuttingDown MOZ_GUARDED_BY(mMonitor);
 | 
						|
  FlippedOnce<false> mFinalized MOZ_GUARDED_BY(mMonitor);
 | 
						|
  uint32_t mPendingWrites MOZ_GUARDED_BY(mMonitor);
 | 
						|
};
 | 
						|
 | 
						|
class OriginAttrsPatternMatchOriginSQLFunction final
 | 
						|
    : public mozIStorageFunction {
 | 
						|
  NS_DECL_ISUPPORTS
 | 
						|
  NS_DECL_MOZISTORAGEFUNCTION
 | 
						|
 | 
						|
  explicit OriginAttrsPatternMatchOriginSQLFunction(
 | 
						|
      OriginAttributesPattern const& aPattern)
 | 
						|
      : mPattern(aPattern) {}
 | 
						|
  OriginAttrsPatternMatchOriginSQLFunction() = delete;
 | 
						|
 | 
						|
 private:
 | 
						|
  ~OriginAttrsPatternMatchOriginSQLFunction() = default;
 | 
						|
 | 
						|
  OriginAttributesPattern mPattern;
 | 
						|
};
 | 
						|
 | 
						|
class PrivateBrowsingOriginSQLFunction final : public mozIStorageFunction {
 | 
						|
  NS_DECL_ISUPPORTS
 | 
						|
  NS_DECL_MOZISTORAGEFUNCTION
 | 
						|
 | 
						|
  PrivateBrowsingOriginSQLFunction() = default;
 | 
						|
 | 
						|
 private:
 | 
						|
  ~PrivateBrowsingOriginSQLFunction() = default;
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace mozilla
 | 
						|
 | 
						|
#endif /* MOZILLA_IDENTITYCREDENTIALSTORAGESERVICE_H_ */
 |