author Dave Townsend <>
Tue, 12 Feb 2019 20:14:33 +0000
changeset 458793 be5bd597747afe360b14fd53453f6a35f920bd09
parent 458772 fc8431c4497f63e93d95e212f8d408379b60f799
child 461491 be0aba20d1d170ceaf5333e3c25b1db23ec42c64
permissions -rw-r--r--
Bug 1518639: Hold the profile service as its concrete type. r=froydnj We cast the nsIToolkitProfileService to nsToolkitProfileService in a bunch of places, might as well just hold that instead. Differential Revision:

/* -*- 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 */

#ifndef nsToolkitProfileService_h
#define nsToolkitProfileService_h

#include "nsIToolkitProfileService.h"
#include "nsIToolkitProfile.h"
#include "nsIFactory.h"
#include "nsSimpleEnumerator.h"
#include "nsProfileLock.h"
#include "nsINIParser.h"

class nsToolkitProfile final : public nsIToolkitProfile {

  friend class nsToolkitProfileService;
  RefPtr<nsToolkitProfile> mNext;
  nsToolkitProfile* mPrev;

  ~nsToolkitProfile() = default;

  nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir,
                   nsIFile* aLocalDir, nsToolkitProfile* aPrev);

  nsresult RemoveInternal(bool aRemoveFiles, bool aInBackground);

  friend class nsToolkitProfileLock;

  nsCString mName;
  nsCOMPtr<nsIFile> mRootDir;
  nsCOMPtr<nsIFile> mLocalDir;
  nsIProfileLock* mLock;

class nsToolkitProfileLock final : public nsIProfileLock {

  nsresult Init(nsToolkitProfile* aProfile, nsIProfileUnlocker** aUnlocker);
  nsresult Init(nsIFile* aDirectory, nsIFile* aLocalDirectory,
                nsIProfileUnlocker** aUnlocker);

  nsToolkitProfileLock() = default;


  RefPtr<nsToolkitProfile> mProfile;
  nsCOMPtr<nsIFile> mDirectory;
  nsCOMPtr<nsIFile> mLocalDirectory;

  nsProfileLock mLock;

class nsToolkitProfileFactory final : public nsIFactory {
  ~nsToolkitProfileFactory() = default;


class nsToolkitProfileService final : public nsIToolkitProfileService {

  nsresult SelectStartupProfile(int* aArgc, char* aArgv[], bool aIsResetting,
                                nsIFile** aRootDir, nsIFile** aLocalDir,
                                nsIToolkitProfile** aProfile, bool* aDidCreate);
  nsresult CreateResetProfile(nsIToolkitProfile** aNewProfile);
  nsresult ApplyResetProfile(nsIToolkitProfile* aOldProfile);
  void CompleteStartup();

  friend class nsToolkitProfile;
  friend class nsToolkitProfileFactory;
  friend nsresult NS_NewToolkitProfileService(nsToolkitProfileService**);


  nsresult Init();

  nsresult CreateTimesInternal(nsIFile* profileDir);
  void GetProfileByDir(nsIFile* aRootDir, nsIFile* aLocalDir,
                       nsIToolkitProfile** aResult);

  nsresult GetProfileDescriptor(nsIToolkitProfile* aProfile,
                                nsACString& aDescriptor, bool* aIsRelative);
  bool IsProfileForCurrentInstall(nsIToolkitProfile* aProfile);
  void ClearProfileFromOtherInstalls(nsIToolkitProfile* aProfile);
  bool MaybeMakeDefaultDedicatedProfile(nsIToolkitProfile* aProfile);
  bool IsSnapEnvironment();

  // Returns the known install hashes from the installs database. Modifying the
  // installs database is safe while iterating the returned array.
  nsTArray<nsCString> GetKnownInstalls();

  // Tracks whether SelectStartupProfile has been called.
  bool mStartupProfileSelected;
  // The first profile in a linked list of profiles loaded from profiles.ini.
  RefPtr<nsToolkitProfile> mFirst;
  // The profile selected for use at startup, if it exists in profiles.ini.
  nsCOMPtr<nsIToolkitProfile> mCurrent;
  // The profile selected for this install in installs.ini.
  nsCOMPtr<nsIToolkitProfile> mDedicatedProfile;
  // The default profile used by non-dev-edition builds.
  nsCOMPtr<nsIToolkitProfile> mNormalDefault;
  // The profile used if mUseDevEditionProfile is true (the default on
  // dev-edition builds).
  nsCOMPtr<nsIToolkitProfile> mDevEditionDefault;
  // The directory that holds profiles.ini and profile directories.
  nsCOMPtr<nsIFile> mAppData;
  // The directory that holds the cache files for profiles.
  nsCOMPtr<nsIFile> mTempData;
  // The location of profiles.ini.
  nsCOMPtr<nsIFile> mListFile;
  // The location of installs.ini.
  nsCOMPtr<nsIFile> mInstallFile;
  // The data loaded from installs.ini.
  nsINIParser mInstallData;
  // The install hash for the currently running install.
  nsCString mInstallHash;
  // 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;
  // True if during startup no dedicated profile was already selected, an old
  // default profile existed but was rejected so a new profile was created.
  bool mCreatedAlternateProfile;
  nsString mStartupReason;
  bool mMaybeLockProfile;

  static nsToolkitProfileService* gService;

  class ProfileEnumerator final : public nsSimpleEnumerator {

    const nsID& DefaultInterface() override {
      return NS_GET_IID(nsIToolkitProfile);

    explicit ProfileEnumerator(nsToolkitProfile* first) { mCurrent = first; }

    RefPtr<nsToolkitProfile> mCurrent;