| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/apps/app_service/instance_registry_updater.h" |
| |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "components/services/app_service/public/cpp/instance_registry.h" |
| #include "ui/aura/window.h" |
| |
| namespace apps { |
| |
| namespace { |
| |
| static InstanceState GetState(bool visible, bool active) { |
| auto state = static_cast<InstanceState>(InstanceState::kStarted | |
| InstanceState::kRunning); |
| if (visible) { |
| state = static_cast<InstanceState>(state | InstanceState::kVisible); |
| } |
| if (active) { |
| // If the app is active, it should be started, running, and visible. |
| state = static_cast<InstanceState>(state | InstanceState::kVisible | |
| InstanceState::kActive); |
| } |
| return state; |
| } |
| |
| bool IsAshBrowserWindow(aura::Window* aura_window) { |
| for (Browser* browser : *BrowserList::GetInstance()) { |
| BrowserWindow* window = browser->window(); |
| if (window && window->GetNativeWindow() == aura_window) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| } // namespace |
| |
| InstanceRegistryUpdater::InstanceRegistryUpdater( |
| BrowserAppInstanceRegistry& browser_app_instance_registry, |
| InstanceRegistry& instance_registry) |
| : browser_app_instance_registry_(browser_app_instance_registry), |
| instance_registry_(instance_registry) { |
| if (aura::Env::HasInstance()) { |
| env_observer_.Observe(aura::Env::GetInstance()); |
| } |
| browser_app_instance_registry_observation_.Observe( |
| &*browser_app_instance_registry_); |
| } |
| |
| InstanceRegistryUpdater::~InstanceRegistryUpdater() = default; |
| |
| void InstanceRegistryUpdater::OnBrowserWindowAdded( |
| const BrowserWindowInstance& instance) { |
| OnBrowserWindowUpdated(instance); |
| } |
| |
| void InstanceRegistryUpdater::OnBrowserWindowUpdated( |
| const BrowserWindowInstance& instance) { |
| InstanceState state = |
| GetState(instance.window->IsVisible(), instance.is_active()); |
| OnInstance(instance.id, instance.GetAppId(), instance.window, state); |
| } |
| |
| void InstanceRegistryUpdater::OnBrowserWindowRemoved( |
| const BrowserWindowInstance& instance) { |
| OnInstance(instance.id, instance.GetAppId(), instance.window, |
| InstanceState::kDestroyed); |
| } |
| |
| void InstanceRegistryUpdater::OnBrowserAppAdded( |
| const BrowserAppInstance& instance) { |
| OnBrowserAppUpdated(instance); |
| } |
| |
| void InstanceRegistryUpdater::OnBrowserAppUpdated( |
| const BrowserAppInstance& instance) { |
| InstanceState state = |
| GetState(instance.window->IsVisible(), |
| instance.is_browser_active() && instance.is_web_contents_active); |
| OnInstance(instance.id, instance.app_id, instance.window, state); |
| } |
| |
| void InstanceRegistryUpdater::OnBrowserAppRemoved( |
| const BrowserAppInstance& instance) { |
| OnInstance(instance.id, instance.app_id, instance.window, |
| InstanceState::kDestroyed); |
| } |
| |
| void InstanceRegistryUpdater::OnWindowInitialized(aura::Window* window) { |
| window_observations_.AddObservation(window); |
| } |
| |
| void InstanceRegistryUpdater::OnWindowVisibilityChanged(aura::Window* window, |
| bool visible) { |
| if (!IsAshBrowserWindow(window)) { |
| return; |
| } |
| for (const BrowserAppInstance* instance : |
| browser_app_instance_registry_->SelectAppInstances( |
| [window](const BrowserAppInstance& instance) { |
| return instance.window == window; |
| })) { |
| OnBrowserAppUpdated(*instance); |
| } |
| for (const BrowserWindowInstance* instance : |
| browser_app_instance_registry_->SelectWindowInstances( |
| [window](const BrowserWindowInstance& instance) { |
| return instance.window == window; |
| })) { |
| OnBrowserWindowUpdated(*instance); |
| } |
| } |
| |
| void InstanceRegistryUpdater::OnWindowDestroying(aura::Window* window) { |
| window_observations_.RemoveObservation(window); |
| } |
| |
| void InstanceRegistryUpdater::OnInstance( |
| const base::UnguessableToken& instance_id, |
| const std::string& app_id, |
| aura::Window* window, |
| InstanceState state) { |
| auto instance = std::make_unique<apps::Instance>(app_id, instance_id, window); |
| instance->UpdateState(state, base::Time::Now()); |
| instance_registry_->OnInstance(std::move(instance)); |
| } |
| |
| } // namespace apps |