#ChromeOS #Ash

Ash (Aura Shell) is a shell based on Aura. The Shell class seems to play a key role. Shell object is a singleton object, and several other objects called controllers are created and initialized through the init method. The following is the part that creates and initializes the controller for the background screen.

Ash::Shell::Init() {
   ...
  wallpaper_controller_ = std::make_unique<WallpaperControllerImpl>(local_state_);
   ...
}

In order to globally refer to the Shell object, which is a singleton object, the Shell class provides a static method, Get method. The WallpaperControllerImpl object registers itself as an observer for the Shell object. Also, register itself as an observer for WindowTreeHostManager object.

WallpaperControllerImpl::WallpaperControllerImpl(PrefService* local_state) {
   ...
   Shell::Get()->window_tree_host_manager()->AddObserver(this);
    Shell::Get()->AddShellObserver(this);
   ...
}

void Shell::AddShellObserver(ShellObserver* observer) {
   shell_observers_.AddObserver(observer);
}

After all, when the OnRootWindowAdded method of the Shell object is called ___ someday ___, a Widget object containing the wallpaper is created through the CreateWallpaperWidget method with the following call flow.

void Shell::OnRootWindowAdded(aura::Window* root_window);
void WallpaperControllerImpl::OnRootWindowAdded(...);
void WallpaperControllerImpl::InstallDesktopController(...);
views::Widget* CreateWallpaperWidget(...);

The Shell object and WallpaperController object are singleton objects to which the singleton pattern is applied. And the two objects have a relationship with the observer pattern, and in this relationship, it can be seen that the Shell object is observed and the WallpaperController object is observer.

The OnRootWindowAdded method of the WallpaperController object, which is an observer, is called as a means to receive notification that something has changed from the shell object to be observed. Judging from the name of the method, the change is “Which list is the RootWindow created? when appended to an array?”.

However, the strange thing is that the OnRootWindowAdded method, where the observer is notified of the change, is a method of the object of the same name. What you can infer without looking at the code here is,

  1. Shell class and WallpaperController class can inherit the same class. In fact, both classes are child classes of the ShellObserver class. Even, you can see through the comments that the object to be observed notifies the observer that the non-primary root window? has been created.
class ASH_EXPORT ShellObserver {
 public:
    ...
    // Invoked after a non-primary root window is created.
    virtual void OnRootWindowAdded(aura::Window* root_window) { ... }
  1. The Shell object can be the object of observation of the WallpaperController object and an observer of any other object. In fact, the Shell object is an observer of the RootWindowController object. Since the Shell object is a singleton object, it notifies the change directly without using an observer array. It is notified only when creating a RootWindow that is not of the PRIMARY type through the judgment statement.
void RootWindowController::Init(RootWindowType root_window_type) {
   ...  
   if (root_window_type == RootWindowType::PRIMARY) {
   ...
   } else {
      // Notify shell observers about new root window.
      shell->OnRootWindowAdded(root_window);
  }
  ...