/* -*- 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 nsToolkitProfileService_h #define nsToolkitProfileService_h #include "mozilla/Components.h" #include "mozilla/LinkedList.h" #include "nsIToolkitProfileService.h" #include "nsIToolkitProfile.h" #include "nsIFactory.h" #include "nsSimpleEnumerator.h" #include "nsProfileLock.h" #include "nsINIParser.h" #include "mozilla/MozPromise.h" #include "nsProxyRelease.h" class nsStartupLock; struct GroupProfileData { nsCString mPath; nsCString mStoreID; bool mShowSelector; }; struct IniData { nsCString mProfiles; nsCString mInstalls; }; class nsToolkitProfile final : public nsIToolkitProfile, public mozilla::LinkedListElement> { public: NS_DECL_ISUPPORTS NS_DECL_NSITOOLKITPROFILE friend class nsToolkitProfileService; private: ~nsToolkitProfile() = default; nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir, nsIFile* aLocalDir, bool aFromDB, const nsACString& aStoreID, bool aShowProfileSelector); nsresult RemoveInternal(bool aRemoveFiles, bool aInBackground); friend class nsToolkitProfileLock; nsCString mName; nsCOMPtr mRootDir; nsCOMPtr mLocalDir; nsCString mStoreID; bool mShowProfileSelector; nsIProfileLock* mLock; uint32_t mIndex; nsCString mSection; }; class nsToolkitProfileLock final : public nsIProfileLock { public: NS_DECL_ISUPPORTS NS_DECL_NSIPROFILELOCK nsresult Init(nsToolkitProfile* aProfile, nsIProfileUnlocker** aUnlocker); nsresult Init(nsIFile* aDirectory, nsIFile* aLocalDirectory, nsIProfileUnlocker** aUnlocker); nsToolkitProfileLock() = default; private: ~nsToolkitProfileLock(); RefPtr mProfile; nsCOMPtr mDirectory; nsCOMPtr mLocalDirectory; nsProfileLock mLock; }; class nsToolkitProfileService final : public nsIToolkitProfileService { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSITOOLKITPROFILESERVICE nsresult SelectStartupProfile(int* aArgc, char* aArgv[], bool aIsResetting, nsIFile** aRootDir, nsIFile** aLocalDir, nsIToolkitProfile** aProfile, bool* aDidCreate, bool* aWasDefaultSelection); nsresult CreateResetProfile(nsIToolkitProfile** aNewProfile); nsresult ApplyResetProfile(nsIToolkitProfile* aOldProfile); void CompleteStartup(); using AsyncFlushPromise = mozilla::MozPromise; private: friend class nsToolkitProfile; friend already_AddRefed NS_GetToolkitProfileService(); nsToolkitProfileService(); ~nsToolkitProfileService(); nsresult Init(); nsresult CreateTimesInternal(nsIFile* profileDir); void GetProfileByDir(nsIFile* aRootDir, nsIFile* aLocalDir, nsToolkitProfile** aResult); already_AddRefed GetProfileByStoreID( const nsACString& aStoreID); nsresult GetProfileDescriptor(nsIFile* aRootDir, nsACString& aDescriptor, bool* aIsRelative); nsresult GetProfileDescriptor(nsToolkitProfile* aProfile, nsACString& aDescriptor, bool* aIsRelative); bool IsProfileForCurrentInstall(nsToolkitProfile* aProfile); void ClearProfileFromOtherInstalls(nsToolkitProfile* aProfile); nsresult MaybeMakeDefaultDedicatedProfile(nsToolkitProfile* aProfile, bool* aResult); bool IsSnapEnvironment(); bool UseLegacyProfiles(); nsresult CreateDefaultProfile(nsToolkitProfile** aResult); nsresult CreateUniqueProfile(nsIFile* aRootDir, const nsACString& aNamePrefix, nsToolkitProfile** aResult); nsresult CreateProfile(nsIFile* aRootDir, const nsACString& aName, nsToolkitProfile** aResult); already_AddRefed GetProfileByName(const nsACString& aName); void SetNormalDefault(nsToolkitProfile* aProfile); already_AddRefed GetDefaultProfile(); nsresult GetLocalDirFromRootDir(nsIFile* aRootDir, nsIFile** aResult); void FlushProfileData( const nsMainThreadPtrHandle& aStartupLock, const GroupProfileData* aProfileInfo); void BuildIniData(nsCString& aProfilesIniData, nsCString& aInstallsIniData); nsresult FlushData(const nsCString& aProfilesIniData, const nsCString& aInstallsIniData); // Returns the known install hashes from the installs database. Modifying the // installs database is safe while iterating the returned array. nsTArray GetKnownInstalls(); // Tracks whether SelectStartupProfile has been called. bool mStartupProfileSelected; // The profiles loaded from profiles.ini. mozilla::LinkedList> mProfiles; // The profile selected for use at startup, if it exists in profiles.ini. RefPtr mCurrent; // The managed profile that acts as a pointer to a profile group. RefPtr mGroupProfile; // The profile selected for this install in installs.ini. RefPtr mDedicatedProfile; // The default profile used by non-dev-edition builds. RefPtr mNormalDefault; // The profile used if mUseDevEditionProfile is true (the default on // dev-edition builds). RefPtr mDevEditionDefault; // The directory that holds profiles.ini and profile directories. nsCOMPtr mAppData; // The directory that holds the cache files for profiles. nsCOMPtr mTempData; // The location of profiles.ini. nsCOMPtr mProfileDBFile; // The location of installs.ini. nsCOMPtr mInstallDBFile; // The data loaded from profiles.ini. nsINIParser mProfileDB; // The section in the profiles db for the current install. nsCString mInstallSection; // A legacy install section which may have been generated against an // installation directory with an incorrect case (see bug 1555319). It is only // really held here so that it can be overridden by tests. nsCString mLegacyInstallSection; // Whether to start with the selected profile by default. bool mStartWithLast; // True if during startup it appeared that this is the first run. bool mIsFirstRun; // True if the default profile is the separate dev-edition-profile. bool mUseDevEditionProfile; // True if this install should use a dedicated default profile. const bool mUseDedicatedProfile; nsCString mStartupReason; // Records the version of the profiles.ini file as it was when it was loaded // during startup. nsCString mStartupFileVersion; bool mMaybeLockProfile; // Holds the current application update channel. This is only really held // so it can be overriden in tests. nsCString mUpdateChannel; // Keep track of some attributes of the databases so we can tell if another // process has changed them. bool mProfileDBExists; int64_t mProfileDBFileSize; PRTime mProfileDBModifiedTime; // A background task queue for the async flushing operations. nsCOMPtr mAsyncQueue; nsISerialEventTarget* AsyncQueue(); static nsToolkitProfileService* gService; class ProfileEnumerator final : public nsSimpleEnumerator { public: NS_DECL_NSISIMPLEENUMERATOR const nsID& DefaultInterface() override { return NS_GET_IID(nsIToolkitProfile); } explicit ProfileEnumerator(nsToolkitProfile* first) { mCurrent = first; } private: RefPtr mCurrent; }; }; already_AddRefed NS_GetToolkitProfileService(); #endif