chromium/chrome/browser/extensions/desktop_android/desktop_android_extension_system.cc

// Copyright 2024 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/extensions/desktop_android/desktop_android_extension_system.h"

#include <memory>
#include <string>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/value_store/value_store_factory_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/app_runtime/app_runtime_api.h"
#include "extensions/browser/extension_prefs_factory.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_factory.h"
#include "extensions/browser/extension_system_provider.h"
#include "extensions/browser/null_app_sorting.h"
#include "extensions/browser/quota_service.h"
#include "extensions/browser/service_worker_manager.h"
#include "extensions/browser/user_script_manager.h"
#include "extensions/common/constants.h"
#include "extensions/common/file_util.h"

using content::BrowserContext;
namespace extensions {

namespace {

// A factory implementation to construct and return the
// DesktopAndroidExtensionSystem.
class DesktopAndroidExtensionSystemFactory : public ExtensionSystemProvider {
 public:
  DesktopAndroidExtensionSystemFactory()
      : ExtensionSystemProvider(
            "DesktopAndroidExtensionSystem",
            BrowserContextDependencyManager::GetInstance()) {
    DependsOn(ExtensionPrefsFactory::GetInstance());
    DependsOn(ExtensionRegistryFactory::GetInstance());
  }
  DesktopAndroidExtensionSystemFactory(
      const DesktopAndroidExtensionSystemFactory&) = delete;
  DesktopAndroidExtensionSystemFactory& operator=(
      const DesktopAndroidExtensionSystemFactory&) = delete;
  ~DesktopAndroidExtensionSystemFactory() override = default;

  // ExtensionSystemProvider implementation:
  ExtensionSystem* GetForBrowserContext(
      content::BrowserContext* context) override {
    return static_cast<DesktopAndroidExtensionSystem*>(
        GetInstance()->GetServiceForBrowserContext(context, true));
  }

  static DesktopAndroidExtensionSystemFactory* GetInstance() {
    static base::NoDestructor<DesktopAndroidExtensionSystemFactory> g_instance;
    return g_instance.get();
  }

 private:
  // BrowserContextKeyedServiceFactory implementation:
  std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
      content::BrowserContext* context) const override {
    return std::make_unique<DesktopAndroidExtensionSystem>(context);
  }
  content::BrowserContext* GetBrowserContextToUse(
      content::BrowserContext* context) const override {
    // Use a separate instance for incognito.
    return context;
  }
  bool ServiceIsCreatedWithBrowserContext() const override { return true; }
};

// A minimal stub implementation of the ExtensionRegistrar::Delegate.
class DesktopAndroidExtensionRegistrarDelegate
    : public ExtensionRegistrar::Delegate {
 public:
  explicit DesktopAndroidExtensionRegistrarDelegate(
      content::BrowserContext* browser_context)
      : browser_context_(browser_context) {
    DCHECK(browser_context_);
  }
  ~DesktopAndroidExtensionRegistrarDelegate() override = default;

  // ExtensionRegistrar::Delegate:
  void PreAddExtension(const Extension* extension,
                       const Extension* old_extension) override {}
  void PostActivateExtension(
      scoped_refptr<const Extension> extension) override {}
  void PostDeactivateExtension(
      scoped_refptr<const Extension> extension) override {}
  void LoadExtensionForReload(
      const ExtensionId& extension_id,
      const base::FilePath& path,
      ExtensionRegistrar::LoadErrorBehavior load_error_behavior) override {
    NOTIMPLEMENTED();
  }
  bool CanEnableExtension(const Extension* extension) override { return true; }
  bool CanDisableExtension(const Extension* extension) override { return true; }
  bool ShouldBlockExtension(const Extension* extension) override {
    return false;
  }

 private:
  raw_ptr<content::BrowserContext> browser_context_;  // Not owned.
};

}  // namespace

DesktopAndroidExtensionSystem::DesktopAndroidExtensionSystem(
    BrowserContext* browser_context)
    : browser_context_(browser_context),
      store_factory_(base::MakeRefCounted<value_store::ValueStoreFactoryImpl>(
          browser_context->GetPath())) {}

DesktopAndroidExtensionSystem::~DesktopAndroidExtensionSystem() = default;

// static
ExtensionSystemProvider* DesktopAndroidExtensionSystem::GetFactory() {
  return DesktopAndroidExtensionSystemFactory::GetInstance();
}

void DesktopAndroidExtensionSystem::Shutdown() {}

void DesktopAndroidExtensionSystem::AddExtension(
    scoped_refptr<const Extension> extension) {
  registrar_->AddExtension(std::move(extension));
}

void DesktopAndroidExtensionSystem::InitForRegularProfile(
    bool extensions_enabled) {
  registrar_delegate_ =
      std::make_unique<DesktopAndroidExtensionRegistrarDelegate>(
          browser_context_);
  registrar_ = std::make_unique<ExtensionRegistrar>(browser_context_,
                                                    registrar_delegate_.get());

  service_worker_manager_ =
      std::make_unique<ServiceWorkerManager>(browser_context_);
  quota_service_ = std::make_unique<QuotaService>();
  user_script_manager_ = std::make_unique<UserScriptManager>(browser_context_);

  ready_.Signal();
}

ExtensionService* DesktopAndroidExtensionSystem::extension_service() {
  return nullptr;
}

ManagementPolicy* DesktopAndroidExtensionSystem::management_policy() {
  return nullptr;
}

ServiceWorkerManager* DesktopAndroidExtensionSystem::service_worker_manager() {
  return service_worker_manager_.get();
}

UserScriptManager* DesktopAndroidExtensionSystem::user_script_manager() {
  return user_script_manager_.get();
}

StateStore* DesktopAndroidExtensionSystem::state_store() {
  return nullptr;
}

StateStore* DesktopAndroidExtensionSystem::rules_store() {
  return nullptr;
}

StateStore* DesktopAndroidExtensionSystem::dynamic_user_scripts_store() {
  return nullptr;
}

scoped_refptr<value_store::ValueStoreFactory>
DesktopAndroidExtensionSystem::store_factory() {
  return store_factory_;
}

QuotaService* DesktopAndroidExtensionSystem::quota_service() {
  return quota_service_.get();
}

AppSorting* DesktopAndroidExtensionSystem::app_sorting() {
  return nullptr;
}

const base::OneShotEvent& DesktopAndroidExtensionSystem::ready() const {
  return ready_;
}

bool DesktopAndroidExtensionSystem::is_ready() const {
  return ready_.is_signaled();
}

ContentVerifier* DesktopAndroidExtensionSystem::content_verifier() {
  return nullptr;
}

std::unique_ptr<ExtensionSet>
DesktopAndroidExtensionSystem::GetDependentExtensions(
    const Extension* extension) {
  return std::make_unique<ExtensionSet>();
}

void DesktopAndroidExtensionSystem::InstallUpdate(
    const std::string& extension_id,
    const std::string& public_key,
    const base::FilePath& temp_dir,
    bool install_immediately,
    InstallUpdateCallback install_update_callback) {
  NOTREACHED();
}

void DesktopAndroidExtensionSystem::PerformActionBasedOnOmahaAttributes(
    const std::string& extension_id,
    const base::Value::Dict& attributes) {
  NOTREACHED();
}

bool DesktopAndroidExtensionSystem::FinishDelayedInstallationIfReady(
    const std::string& extension_id,
    bool install_immediately) {
  NOTREACHED();
}

}  // namespace extensions