---
# System prepended metadata

title: KeyedService
tags: [Chromium-General, elkurin-daily-note]

---

# KeyedService and KeyedServiceFactory

[KeyedService](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service.h;l=24;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771) and [KeyedServiceBaseFactory](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service_base_factory.h;l=31;drc=447e4fe9632d6680991223b97b9c489f7edbf56f) are interfaces to support building a dependency tree of services corresponded to the same object such as [content::BrowserContext](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/browser_context.h;l=107;drc=9f831c2a0f5f38a330fd237eb0ac7fa4d2845053).

## Overview
When you would like to use keyed service design, inherit [KeyedService](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service.h;l=24;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771) to define the service class, and prepare KeyedServiceFactory for the instance
```cpp=
class ArcIntentHelperBridge : public KeyedService ... {
  ...;
  void Shutdown() override;
}

class ArcIntentHelperBridgeFactory
  : public internal::ArcBrowserContextKeyedServiceFactoryBase<
        ArcIntentHelperBridge,
        ArcIntentHelperBridgeFactory> {
  static ArcIntentHelperBridgeFactory* GetInstance() {...}          
}
```
KeyedService design is often used to handle the initialization/shutdown process clearer, and also provide methods to get a singelton.

KeyedService is mapped to some object like Profile and we can obtain the service using `profile` parameter from anywhere.

## KeyedService
[KeyedService](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/keyed_service.h;l=24;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771) interface supports two-phase destruction order.  

KeyedService are destroyed within two phases.  First is to frop references and second is to actually delete object. First is done by `Shutdown` and second is done by the destructor.
```cpp=
// First pass is shutdown.
virtual void Shutdown() {}

// Second pass is the actual deletion
virtual ~KeyedService() = default;
```
Note that `Shutdown` is not an actual destructor, it's like OnDestroying() observer.

`Shutdown` may not do anything if not required.  
In ArcIntentHelperBridge example, it calls OnArcIntentHelperBridgeShutdown observer which will remove its reference from the KeyedService.
```cpp=
void ArcAsh::OnArcIntentHelperBridgeShutdown(
  arc::ArcIntentHelperBridge* bridge) {
 if (bridge)
   bridge->RemoveObserver(this);
}
```

## KeyedServiceFactory
[BrowserContextKeyedServiceFactory](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/content/browser_context_keyed_service_factory.h;l=31;drc=371515598109bf869e1acbe5ea67813fc1a4cc3d) is a base class for KeyedServiceFactory which takes BrowserContext object to map a KeyedService.  
[GetServiceForBrowserContext](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/content/browser_context_keyed_service_factory.h;l=107;drc=371515598109bf869e1acbe5ea67813fc1a4cc3d) returns KeyedService paired with BrowserContext.

KeyedServiceFactory is responsible for creating/getting KeyedService instance, and also resolving dependency.  
The latter responsibility is in [DependencyManager](https://source.chromium.org/chromium/chromium/src/+/main:components/keyed_service/core/dependency_manager.h;drc=85d0a1363092979464bf9ecbdfe03dba39bc8532) stored in KeyedServiceFactory as `dependency_manager_`.

## Note
Gardening is very tough this week... zzz