The Semi-Single-Profile Proposal

Author: Benjamin Smedberg
Date: 25-Feb-2004

I have been floating the idea of a semi-single-profile setup for the new-toolkit apps, but I never wrote a complete proposal. This is my first cut at a serious proposal for discussion.

The Problem:

The problem was originally discussed in a long series of emails about how the new-app extension manager would register XPCOM components which were part of extensions installed in the profile. There was talk of having a "tiered" compreg, but I argue that to be a major re-architecturing for little benefit. We could also register profile components at startup and un-register them at shutdown: this doesn't work well because the components may miss important startup notifications.

Requirements:

  1. Continue to support a multi-profile mechanism. On Firefox, this is mainly for developers, and can be "hidden" behind command-line parameters. For Thunderbird, we need profile-selection UI similar to what currently exists;
  2. Compreg should be cached in the profile;
  3. Don't rewrite more than necessary;
  4. If possible, remove the profile code's dependency on libreg.

Core Concept:

Move profile-selection before XPCOM is initialized.

Timeline:

Since this may seem a bit abstract and I don't have a better way to describe it, I'm going to present an timeline of the startup sequence, with sidenotes about design decisions. For the moment, I'm presenting a solution with full profile UI: firefox can simplify as appropriate:

  1. Start the app (firefox);
  2. Check for a commandline flag -profile <path>. If found, it sets up the profile; dirserviceprovider to point to <path> and skips to the "launch" step below. To support "run-from-CD" installations, the <path> may be CWD-relative;
  3. Check for a commandline flag -P <profilename>. If found, look in a text file ~/.phoenix/profiles.list. This file has the very simple format:
    #relative path is relative to ~/.phoenix
    default=./default/<slt>
    devel=/opt/devel-phoenix-profile
    startup-default=devel
    If the profile name exists, set it up with the profile dirserviceprovider and skip to the "launch" step below. If it doesn't exist, skip to "launch profile manager" below;
  4. If there is a "startup-default" line in profiles.list, use that profile and skip to the "launch" step below;
  5. Launch Profile Manager: start XPCOM without a profile, using the compreg in /app/components/compreg.dat  The profile-manager UI will provide an interface with the method "nsIFile selectProfile()" which runs synchronously and selects a profile. Then we shut down XPCOM. During this step all the ordinary functionality of the profile manager is available, including creating new profiles, deleting profiles (and profile migration?);
  6. If we don't have a profile selected now (e.g. selectProfile() returned null, because the user selected "cancel" on the profile manager), we quit. Otherwise, we set up the profile dirserviceprovider appropriately for the selected profile;
  7. Launch: We launch XPCOM (perhaps again). This time, however, the compreg is in this location: <profile-path>/<buildid>/compreg.dat.  We go through the ordinary startup procedures (launch app chrome windows + ensure1window);
  8. Shutdown: when the last window is closed, shut down XPCOM as if we were going to quit;
  9. Check a global variable gSwitchProfile, if true, we skip back to "Launch Profile Manager".

Design Considerations:

I am not sure the impact this will have on profile migration strategy. I "think" we'll be fine, because migration should happen in the profile manager, but I'm not sure that's how it actually works.

This system should continue to work with salted profiles. Other people can decide whether we actually want to salt profiles.

We need to split and make sensible the profile dirserviceprovider. It contains gecko keys and app keys all mixed together. We need to document which directory service keys an embedding app needs to provide in order for gecko to work correctly in various configurations, and minimize this as much as possible by providing a defaulting mechanism.

Removing the profile dependency on libreg may imply other things I haven't thought of... ccarlen? does profile/ keep other information in registry.dat?

The start-xpcom-several times strategy is *supposed* to work, but hasn't really been tested. There is probably static data scattered around the tree that might need to be cleaned up more rigorously than today.