|  | // 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 SetExtensionVisible(const std::string& extension_id, | 
|  | bool visible) 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; | 
|  | friend class ChromeAppSortingSetExtensionVisible; | 
|  |  | 
|  | // 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_ |