chromium/chrome/browser/ui/ash/shelf/app_service/shelf_app_service_app_updater.cc

// Copyright 2019 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/ui/ash/shelf/app_service/shelf_app_service_app_updater.h"

#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/cpp/app_update.h"
#include "components/services/app_service/public/cpp/types_util.h"

ShelfAppServiceAppUpdater::ShelfAppServiceAppUpdater(
    Delegate* delegate,
    content::BrowserContext* browser_context)
    : ShelfAppUpdater(delegate, browser_context) {
  auto* cache = &apps::AppServiceProxyFactory::GetForProfile(
                     Profile::FromBrowserContext(browser_context))
                     ->AppRegistryCache();

  cache->ForEachApp([this](const apps::AppUpdate& update) {
    if (update.Readiness() == apps::Readiness::kReady)
      this->installed_apps_.insert(update.AppId());
  });
  app_registry_cache_observer_.Observe(cache);
}

ShelfAppServiceAppUpdater::~ShelfAppServiceAppUpdater() = default;

void ShelfAppServiceAppUpdater::OnAppUpdate(const apps::AppUpdate& update) {
  if (!update.ReadinessChanged() && !update.PausedChanged() &&
      !update.ShowInShelfChanged() && !update.ShortNameChanged() &&
      !update.PolicyIdsChanged()) {
    return;
  }

  const std::string& app_id = update.AppId();
  if (update.ReadinessChanged()) {
    std::set<std::string>::const_iterator it = installed_apps_.find(app_id);
    switch (update.Readiness()) {
      case apps::Readiness::kReady:
        if (it == installed_apps_.end()) {
          installed_apps_.insert(app_id);
        }
        delegate()->OnAppInstalled(browser_context(), app_id);
        return;
      case apps::Readiness::kUninstalledByUser:
      case apps::Readiness::kUninstalledByNonUser:
        if (it != installed_apps_.end()) {
          installed_apps_.erase(it);
          const bool by_migration =
              update.Readiness() == apps::Readiness::kUninstalledByNonUser;
          delegate()->OnAppUninstalledPrepared(browser_context(), app_id,
                                               by_migration);
          delegate()->OnAppUninstalled(browser_context(), app_id);
        }
        return;
      case apps::Readiness::kDisabledByPolicy:
      case apps::Readiness::kDisabledByLocalSettings:
        if (update.ShowInShelfChanged()) {
          OnShowInShelfChangedForAppDisabledByPolicy(
              app_id, update.ShowInShelf().value_or(false));
        } else {
          delegate()->OnAppUpdated(browser_context(), app_id,
                                   /*reload_icon=*/true);
        }
        return;
      default:
        delegate()->OnAppUpdated(browser_context(), app_id,
                                 /*reload_icon=*/true);
        return;
    }
  }

  if (update.PolicyIdsChanged())
    delegate()->OnAppInstalled(browser_context(), app_id);

  if (update.ShowInShelfChanged()) {
    if (apps_util::IsDisabled(update.Readiness())) {
      OnShowInShelfChangedForAppDisabledByPolicy(
          app_id, update.ShowInShelf().value_or(false));
    } else {
      delegate()->OnAppShowInShelfChanged(browser_context(), app_id,
                                          update.ShowInShelf().value_or(true));
    }
  }

  if (update.PausedChanged()) {
    delegate()->OnAppUpdated(browser_context(), app_id, /*reload_icon=*/true);
    return;
  }

  if (update.ShortNameChanged())
    delegate()->OnAppUpdated(browser_context(), app_id, /*reload_icon=*/false);
}

void ShelfAppServiceAppUpdater::OnAppRegistryCacheWillBeDestroyed(
    apps::AppRegistryCache* cache) {
  app_registry_cache_observer_.Reset();
}

void ShelfAppServiceAppUpdater::OnShowInShelfChangedForAppDisabledByPolicy(
    const std::string& app_id,
    bool show_in_shelf) {
  std::set<std::string>::const_iterator it = installed_apps_.find(app_id);
  if (show_in_shelf) {
    if (it == installed_apps_.end()) {
      installed_apps_.insert(app_id);
      delegate()->OnAppInstalled(browser_context(), app_id);
    }
  } else {
    if (it != installed_apps_.end()) {
      installed_apps_.erase(it);
      delegate()->OnAppUninstalledPrepared(browser_context(), app_id,
                                           /*by_migration=*/false);
    }
  }
}