#ifndef CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
#define CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
#include <stddef.h>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_install_manager_observer.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registrar_observer.h"
#include "components/sync/model/string_ordinal.h"
#include "components/webapps/common/web_app_id.h"
#include "extensions/browser/app_sorting.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension_id.h"
namespace web_app {
class WebApp;
class WebAppSyncBridge;
}
namespace extensions {
class ChromeAppSorting : public AppSorting,
public ExtensionRegistryObserver,
public web_app::WebAppRegistrarObserver,
public web_app::WebAppInstallManagerObserver {
public:
explicit ChromeAppSorting(content::BrowserContext* browser_context);
ChromeAppSorting(const ChromeAppSorting&) = delete;
ChromeAppSorting& operator=(const ChromeAppSorting&) = delete;
~ChromeAppSorting() override;
void InitializePageOrdinalMapFromWebApps() override;
void FixNTPOrdinalCollisions() override;
void EnsureValidOrdinals(
const ExtensionId& extension_id,
const syncer::StringOrdinal& suggested_page) override;
bool GetDefaultOrdinals(const ExtensionId& extension_id,
syncer::StringOrdinal* page_ordinal,
syncer::StringOrdinal* app_launch_ordinal) override;
void OnExtensionMoved(const ExtensionId& moved_extension_id,
const ExtensionId& predecessor_extension_id,
const ExtensionId& successor_extension_id) override;
syncer::StringOrdinal GetAppLaunchOrdinal(
const ExtensionId& extension_id) const override;
void SetAppLaunchOrdinal(
const ExtensionId& extension_id,
const syncer::StringOrdinal& new_app_launch_ordinal) override;
syncer::StringOrdinal CreateFirstAppLaunchOrdinal(
const syncer::StringOrdinal& page_ordinal) const override;
syncer::StringOrdinal CreateNextAppLaunchOrdinal(
const syncer::StringOrdinal& page_ordinal) const override;
syncer::StringOrdinal CreateFirstAppPageOrdinal() const override;
syncer::StringOrdinal GetNaturalAppPageOrdinal() const override;
syncer::StringOrdinal GetPageOrdinal(
const ExtensionId& extension_id) const override;
void SetPageOrdinal(const ExtensionId& extension_id,
const syncer::StringOrdinal& new_page_ordinal) override;
void ClearOrdinals(const ExtensionId& extension_id) override;
int PageStringOrdinalAsInteger(
const syncer::StringOrdinal& page_ordinal) const override;
syncer::StringOrdinal PageIntegerAsStringOrdinal(size_t page_index) override;
void SetExtensionVisible(const ExtensionId& extension_id,
bool visible) override;
void OnWebAppInstalled(const webapps::AppId& app_id) override;
void OnWebAppInstallManagerDestroyed() override;
void OnWebAppsWillBeUpdatedFromSync(
const std::vector<const web_app::WebApp*>& updated_apps_state) override;
void OnAppRegistrarDestroyed() override;
private:
typedef std::multimap<syncer::StringOrdinal,
ExtensionId,
syncer::StringOrdinal::LessThanFn>
AppLaunchOrdinalMap;
typedef std::map<
syncer::StringOrdinal, AppLaunchOrdinalMap,
syncer::StringOrdinal::LessThanFn> PageOrdinalMap;
friend class ChromeAppSortingDefaultOrdinalsBase;
friend class ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage;
friend class ChromeAppSortingInitialize;
friend class ChromeAppSortingInitializeWithNoApps;
friend class ChromeAppSortingPageOrdinalMapping;
friend class ChromeAppSortingSetExtensionVisible;
enum AppLaunchOrdinalReturn {MIN_ORDINAL, MAX_ORDINAL};
struct AppOrdinals {
AppOrdinals();
AppOrdinals(const AppOrdinals& other);
~AppOrdinals();
syncer::StringOrdinal page_ordinal;
syncer::StringOrdinal app_launch_ordinal;
};
using AppOrdinalsMap = std::map<ExtensionId, AppOrdinals>;
syncer::StringOrdinal GetMinOrMaxAppLaunchOrdinalsOnPage(
const syncer::StringOrdinal& page_ordinal,
AppLaunchOrdinalReturn return_type) const;
void InitializePageOrdinalMap(
const std::vector<ExtensionId>& extension_or_app_ids);
void MigrateAppIndex(const ExtensionIdList& extension_ids);
void AddOrdinalMapping(const ExtensionId& extension_id,
const syncer::StringOrdinal& page_ordinal,
const syncer::StringOrdinal& app_launch_ordinal);
void CreateOrdinalsIfNecessary(size_t minimum_size);
void RemoveOrdinalMapping(const ExtensionId& extension_id,
const syncer::StringOrdinal& page_ordinal,
const syncer::StringOrdinal& app_launch_ordinal);
void SyncIfNeeded(const ExtensionId& extension_id);
void CreateDefaultOrdinals();
syncer::StringOrdinal ResolveCollision(
const syncer::StringOrdinal& page_ordinal,
const syncer::StringOrdinal& app_launch_ordinal) const;
size_t CountItemsVisibleOnNtp(const AppLaunchOrdinalMap& m) const;
void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) override;
const raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_ =
nullptr;
raw_ptr<const web_app::WebAppRegistrar, AcrossTasksDanglingUntriaged>
web_app_registrar_ = nullptr;
raw_ptr<web_app::WebAppSyncBridge, AcrossTasksDanglingUntriaged>
web_app_sync_bridge_ = nullptr;
base::ScopedObservation<web_app::WebAppRegistrar,
web_app::WebAppRegistrarObserver>
app_registrar_observation_{this};
base::ScopedObservation<web_app::WebAppInstallManager,
web_app::WebAppInstallManagerObserver>
install_manager_observation_{this};
PageOrdinalMap ntp_ordinal_map_;
AppOrdinalsMap default_ordinals_;
bool default_ordinals_created_;
std::set<ExtensionId> ntp_hidden_extensions_;
base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
registry_observation_{this};
base::WeakPtrFactory<ChromeAppSorting> weak_factory_{this};
};
}
#endif