chrome/browser/profiles/README.md
If a KeyedService owns objects that depend on the lifetime of its Profile then it
needs to ensure that these objects are destroyed before the Profile is
destroyed (e.g. content::WebContents need to be be destroyed before their
Profile is destroyed). This can be done by overriding
KeyedService::Shutdown - this method will be called before the Profile object
is destroyed.
Typically, closing the last Browser window associated with a Profile will
start tearing down the Profile. This is undesirable if there are
content::WebContents associated with that Profile in standalone (i.e.
non-Browser) windows that shouldn't go away without an explicit user action to
close such a window. In such cases, Profile destruction can be postponed by
holding ScopedProfileKeepAlive.
ScopedProfileKeepAlive is a strong reference to a Profile object.
It is very similar to ScopedKeepAlive, which is for the browser process.
If an object is not a KeyedService, but still needs to react to destruction of
a specific KeyedService, then it can do so using
BrowserContextKeyedServiceShutdownNotifierFactory.
For example, extensions::ExtensionURLLoaderFactory is owned by its remote mojo
client (i.e. it is not a KeyedService) but it still wants to avoid processing
further chrome-extension:// resource requests after Profile destruction.
This is done by
registering
ExtensionURLLoaderFactory::OnBrowserContextDestroyed to be called
when extension-related keyed services get
destroyed.
If you really need to directly listen for Profile destruction you can use
ProfileObserver::OnProfileWillBeDestroyed, but in general if you need this,
it's a bad sign, as it means that you're using a feature that is not properly
encapsulated in a keyed service.