chromium/chrome/browser/extensions/external_pref_loader.cc

// Copyright 2012 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/external_pref_loader.h"

#include <set>
#include <utility>

#include "base/containers/contains.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/json/json_file_value_serializer.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/scoped_observation.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/value_iterators.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/apps/user_type_filter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_file_task_runner.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/constants/ash_switches.h"
#include "chrome/browser/prefs/pref_service_syncable_util.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/service/sync_service_observer.h"
#include "components/sync/service/sync_user_settings.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/sync_preferences/pref_service_syncable_observer.h"
#endif

BrowserThread;

namespace {

constexpr base::FilePath::CharType kExternalExtensionJson[] =);

// Extension installations are skipped here as excluding these in the overlay
// is a bit complicated.
// TODO(crbug.com/40658053) This is a temporary measure and should be replaced.
bool SkipInstallForChromeOSTablet(const base::FilePath& file_path) {}

std::set<base::FilePath> GetPrefsCandidateFilesFromFolder(
    const base::FilePath& external_extension_search_path) {}

}  // namespace

namespace extensions {

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Helper class to wait for priority pref sync to be ready.
class ExternalPrefLoader::PrioritySyncReadyWaiter
    : public sync_preferences::PrefServiceSyncableObserver,
      public syncer::SyncServiceObserver {
 public:
  explicit PrioritySyncReadyWaiter(Profile* profile) : profile_(profile) {
    DCHECK(profile_);
  }

  PrioritySyncReadyWaiter(const PrioritySyncReadyWaiter&) = delete;
  PrioritySyncReadyWaiter& operator=(const PrioritySyncReadyWaiter&) = delete;

  ~PrioritySyncReadyWaiter() override = default;

  void Start(base::OnceClosure done_closure) {
    if (IsPrioritySyncing()) {
      std::move(done_closure).Run();
      // Note: |this| is deleted here.
      return;
    }
    DCHECK(!done_closure_);
    done_closure_ = std::move(done_closure);
    MaybeObserveSyncStart();
  }

 private:
  void MaybeObserveSyncStart() {
    syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
    if (!service || !service->IsSyncFeatureEnabled()) {
      Finish();
      // Note: |this| is deleted.
      return;
    }
    AddObservers();
  }

  // sync_preferences::PrefServiceSyncableObserver:
  void OnIsSyncingChanged() override {
    DCHECK(profile_);
    if (!IsPrioritySyncing())
      return;

    Finish();
    // Note: |this| is deleted here.
  }

  // syncer::SyncServiceObserver
  void OnStateChanged(syncer::SyncService* sync) override {
    if (!sync->IsSyncFeatureEnabled()) {
      Finish();
    }
  }

  void OnSyncShutdown(syncer::SyncService* sync) override {
    DCHECK(sync_service_observation_.IsObservingSource(sync));
    sync_service_observation_.Reset();
  }

  bool IsPrioritySyncing() {
    sync_preferences::PrefServiceSyncable* prefs =
        PrefServiceSyncableFromProfile(profile_);
    return prefs->AreOsPriorityPrefsSyncing();
  }

  void AddObservers() {
    sync_preferences::PrefServiceSyncable* prefs =
        PrefServiceSyncableFromProfile(profile_);
    DCHECK(prefs);
    syncable_pref_observation_.Observe(prefs);

    syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
    sync_service_observation_.Observe(service);
  }

  void Finish() { std::move(done_closure_).Run(); }

  raw_ptr<Profile, LeakedDanglingUntriaged> profile_;

  base::OnceClosure done_closure_;

  // Used for registering observer for sync_preferences::PrefServiceSyncable.
  base::ScopedObservation<sync_preferences::PrefServiceSyncable,
                          sync_preferences::PrefServiceSyncableObserver>
      syncable_pref_observation_{this};
  base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
      sync_service_observation_{this};
};
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

ExternalPrefLoader::ExternalPrefLoader(int base_path_id,
                                       int options,
                                       Profile* profile)
    :{}

ExternalPrefLoader::~ExternalPrefLoader() {}

const base::FilePath ExternalPrefLoader::GetBaseCrxFilePath() {}

void ExternalPrefLoader::StartLoading() {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
void ExternalPrefLoader::OnPrioritySyncReady(
    ExternalPrefLoader::PrioritySyncReadyWaiter* waiter) {
  // Delete |waiter| from |pending_waiter_list_|.
  pending_waiter_list_.erase(
      base::ranges::find(pending_waiter_list_, waiter,
                         &std::unique_ptr<PrioritySyncReadyWaiter>::get));
  // Continue loading.
  GetExtensionFileTaskRunner()->PostTask(
      FROM_HERE, base::BindOnce(&ExternalPrefLoader::LoadOnFileThread, this));
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

// static.
base::Value::Dict ExternalPrefLoader::ExtractExtensionPrefs(
    base::ValueDeserializer* deserializer,
    const base::FilePath& path) {}

void ExternalPrefLoader::LoadOnFileThread() {}

void ExternalPrefLoader::ReadExternalExtensionPrefFile(
    base::Value::Dict& prefs) {}

void ExternalPrefLoader::ReadStandaloneExtensionPrefFiles(
    base::Value::Dict& prefs) {}

}  // namespace extensions