blob: b943357789ad1bff6017672000a95678ccf1fc88 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
#define CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
#include <map>
#include <set>
#include <string>
#include "base/basictypes.h"
#include "extensions/browser/app_sorting.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/extension.h"
#include "sync/api/string_ordinal.h"
class ExtensionSyncService;
class PrefService;
namespace extensions {
class ExtensionScopedPrefs;
class ChromeAppSorting : public AppSorting {
public:
ChromeAppSorting();
virtual ~ChromeAppSorting();
// AppSorting implementation:
virtual void SetExtensionScopedPrefs(ExtensionScopedPrefs* prefs) OVERRIDE;
virtual void SetExtensionSyncService(
ExtensionSyncService* extension_sync_service) OVERRIDE;
virtual void Initialize(
const extensions::ExtensionIdList& extension_ids) OVERRIDE;
virtual void FixNTPOrdinalCollisions() OVERRIDE;
virtual void EnsureValidOrdinals(
const std::string& extension_id,
const syncer::StringOrdinal& suggested_page) OVERRIDE;
virtual void OnExtensionMoved(
const std::string& moved_extension_id,
const std::string& predecessor_extension_id,
const std::string& successor_extension_id) OVERRIDE;
virtual syncer::StringOrdinal GetAppLaunchOrdinal(
const std::string& extension_id) const OVERRIDE;
virtual void SetAppLaunchOrdinal(
const std::string& extension_id,
const syncer::StringOrdinal& new_app_launch_ordinal) OVERRIDE;
virtual syncer::StringOrdinal CreateFirstAppLaunchOrdinal(
const syncer::StringOrdinal& page_ordinal) const OVERRIDE;
virtual syncer::StringOrdinal CreateNextAppLaunchOrdinal(
const syncer::StringOrdinal& page_ordinal) const OVERRIDE;
virtual syncer::StringOrdinal CreateFirstAppPageOrdinal() const OVERRIDE;
virtual syncer::StringOrdinal GetNaturalAppPageOrdinal() const OVERRIDE;
virtual syncer::StringOrdinal GetPageOrdinal(
const std::string& extension_id) const OVERRIDE;
virtual void SetPageOrdinal(
const std::string& extension_id,
const syncer::StringOrdinal& new_page_ordinal) OVERRIDE;
virtual void ClearOrdinals(const std::string& extension_id) OVERRIDE;
virtual int PageStringOrdinalAsInteger(
const syncer::StringOrdinal& page_ordinal) const OVERRIDE;
virtual syncer::StringOrdinal PageIntegerAsStringOrdinal(
size_t page_index) OVERRIDE;
virtual void MarkExtensionAsHidden(const std::string& extension_id) OVERRIDE;
private:
// The StringOrdinal is the app launch ordinal and the string is the extension
// id.
typedef std::multimap<
syncer::StringOrdinal, std::string,
syncer::StringOrdinal::LessThanFn> AppLaunchOrdinalMap;
// The StringOrdinal is the page ordinal and the AppLaunchOrdinalMap is the
// contents of that page.
typedef std::map<
syncer::StringOrdinal, AppLaunchOrdinalMap,
syncer::StringOrdinal::LessThanFn> PageOrdinalMap;
// Unit tests.
friend class ChromeAppSortingDefaultOrdinalsBase;
friend class ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage;
friend class ChromeAppSortingInitializeWithNoApps;
friend class ChromeAppSortingPageOrdinalMapping;
// An enum used by GetMinOrMaxAppLaunchOrdinalsOnPage to specify which
// value should be returned.
enum AppLaunchOrdinalReturn {MIN_ORDINAL, MAX_ORDINAL};
// Maps an app id to its ordinals.
struct AppOrdinals {
AppOrdinals();
~AppOrdinals();
syncer::StringOrdinal page_ordinal;
syncer::StringOrdinal app_launch_ordinal;
};
typedef std::map<std::string, AppOrdinals> AppOrdinalsMap;
// This function returns the lowest ordinal on |page_ordinal| if
// |return_value| == AppLaunchOrdinalReturn::MIN_ORDINAL, otherwise it returns
// the largest ordinal on |page_ordinal|. If there are no apps on the page
// then an invalid StringOrdinal is returned. It is an error to call this
// function with an invalid |page_ordinal|.
syncer::StringOrdinal GetMinOrMaxAppLaunchOrdinalsOnPage(
const syncer::StringOrdinal& page_ordinal,
AppLaunchOrdinalReturn return_type) const;
// Initialize the |page_ordinal_map_| with the page ordinals used by the
// given extensions.
void InitializePageOrdinalMap(
const extensions::ExtensionIdList& extension_ids);
// Migrates the app launcher and page index values.
void MigrateAppIndex(
const extensions::ExtensionIdList& extension_ids);
// Called to add a new mapping value for |extension_id| with a page ordinal
// of |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. This
// works with valid and invalid StringOrdinals.
void AddOrdinalMapping(const std::string& extension_id,
const syncer::StringOrdinal& page_ordinal,
const syncer::StringOrdinal& app_launch_ordinal);
// Ensures |ntp_ordinal_map_| is of |minimum_size| number of entries.
void CreateOrdinalsIfNecessary(size_t minimum_size);
// Removes the mapping for |extension_id| with a page ordinal of
// |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. If there
// is not matching map, nothing happens. This works with valid and invalid
// StringOrdinals.
void RemoveOrdinalMapping(const std::string& extension_id,
const syncer::StringOrdinal& page_ordinal,
const syncer::StringOrdinal& app_launch_ordinal);
// Syncs the extension if needed. It is an error to call this if the
// extension is not an application.
void SyncIfNeeded(const std::string& extension_id);
// Creates the default ordinals.
void CreateDefaultOrdinals();
// Gets the default ordinals for |extension_id|. Returns false if no default
// ordinals for |extension_id| is defined. Otherwise, returns true and
// ordinals is updated with corresponding ordinals.
bool GetDefaultOrdinals(const std::string& extension_id,
syncer::StringOrdinal* page_ordinal,
syncer::StringOrdinal* app_launch_ordinal);
// Returns |app_launch_ordinal| if it has no collision in the page specified
// by |page_ordinal|. Otherwise, returns an ordinal after |app_launch_ordinal|
// that has no conflict.
syncer::StringOrdinal ResolveCollision(
const syncer::StringOrdinal& page_ordinal,
const syncer::StringOrdinal& app_launch_ordinal) const;
// Returns the number of items in |m| visible on the new tab page.
size_t CountItemsVisibleOnNtp(const AppLaunchOrdinalMap& m) const;
ExtensionScopedPrefs* extension_scoped_prefs_; // Weak, owns this instance.
ExtensionSyncService* extension_sync_service_; // Weak.
// A map of all the StringOrdinal page ordinals mapping to the collections of
// app launch ordinals that exist on that page. This is used for mapping
// StringOrdinals to their Integer equivalent as well as quick lookup of the
// any collision of on the NTP (icons with the same page and same app launch
// ordinals). The possiblity of collisions means that a multimap must be used
// (although the collisions must all be resolved once all the syncing is
// done).
PageOrdinalMap ntp_ordinal_map_;
// Defines the default ordinals.
AppOrdinalsMap default_ordinals_;
// Used to construct the default ordinals once when needed instead of on
// construction when the app order may not have been determined.
bool default_ordinals_created_;
// The set of extensions that don't appear in the new tab page.
std::set<std::string> ntp_hidden_extensions_;
DISALLOW_COPY_AND_ASSIGN(ChromeAppSorting);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_