1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SORTING_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_SORTING_H_
12 #include "base/basictypes.h"
13 #include "chrome/browser/extensions/extension_prefs.h"
14 #include "chrome/common/extensions/extension.h"
15 #include "sync/api/string_ordinal.h"
17 class ExtensionScopedPrefs
;
18 class ExtensionServiceInterface
;
21 class ExtensionSorting
{
23 explicit ExtensionSorting(ExtensionScopedPrefs
* extension_scoped_prefs
);
26 // Set up the ExtensionService to inform of changes that require syncing.
27 void SetExtensionService(ExtensionServiceInterface
* extension_service
);
29 // Properly initialize ExtensionSorting internal values that require
32 const extensions::ExtensionIdList
& extension_ids
);
34 // Resolves any conflicts the might be created as a result of syncing that
35 // results in two icons having the same page and app launch ordinal. After
36 // this is called it is guaranteed that there are no collisions of NTP icons.
37 void FixNTPOrdinalCollisions();
39 // This ensures that the extension has valid ordinals, and if it doesn't then
40 // properly initialize them. |suggested_page| will be used if it is valid and
41 // the extension has no valid user-set page ordinal.
42 void EnsureValidOrdinals(const std::string
& extension_id
,
43 const syncer::StringOrdinal
& suggested_page
);
45 // Updates the app launcher value for the moved extension so that it is now
46 // located after the given predecessor and before the successor.
47 // Empty strings are used to indicate no successor or predecessor.
48 void OnExtensionMoved(const std::string
& moved_extension_id
,
49 const std::string
& predecessor_extension_id
,
50 const std::string
& successor_extension_id
);
52 // Get the application launch ordinal for an app with |extension_id|. This
53 // determines the order in which the app appears on the page it's on in the
54 // New Tab Page (Note that you can compare app launch ordinals only if the
55 // apps are on the same page). A string value close to |a*| generally
56 // indicates top left. If the extension has no launch ordinal, an invalid
57 // StringOrdinal is returned.
58 syncer::StringOrdinal
GetAppLaunchOrdinal(
59 const std::string
& extension_id
) const;
61 // Sets a specific launch ordinal for an app with |extension_id|.
62 void SetAppLaunchOrdinal(const std::string
& extension_id
,
63 const syncer::StringOrdinal
& new_app_launch_ordinal
);
65 // Returns a StringOrdinal that is lower than any app launch ordinal for the
67 syncer::StringOrdinal
CreateFirstAppLaunchOrdinal(
68 const syncer::StringOrdinal
& page_ordinal
) const;
70 // Returns a StringOrdinal that is higher than any app launch ordinal for the
72 syncer::StringOrdinal
CreateNextAppLaunchOrdinal(
73 const syncer::StringOrdinal
& page_ordinal
) const;
75 // Returns a StringOrdinal that is lower than any existing page ordinal.
76 syncer::StringOrdinal
CreateFirstAppPageOrdinal() const;
78 // Gets the page a new app should install to, which is the earliest non-full
79 // page. The returned ordinal may correspond to a page that doesn't yet exist
80 // if all pages are full.
81 syncer::StringOrdinal
GetNaturalAppPageOrdinal() const;
83 // Get the page ordinal for an app with |extension_id|. This determines
84 // which page an app will appear on in page-based NTPs. If the app has no
85 // page specified, an invalid StringOrdinal is returned.
86 syncer::StringOrdinal
GetPageOrdinal(const std::string
& extension_id
) const;
88 // Sets a specific page ordinal for an app with |extension_id|.
89 void SetPageOrdinal(const std::string
& extension_id
,
90 const syncer::StringOrdinal
& new_page_ordinal
);
92 // Removes the ordinal values for an app.
93 void ClearOrdinals(const std::string
& extension_id
);
95 // Convert the page StringOrdinal value to its integer equivalent. This takes
96 // O(# of apps) worst-case.
97 int PageStringOrdinalAsInteger(
98 const syncer::StringOrdinal
& page_ordinal
) const;
100 // Converts the page index integer to its StringOrdinal equivalent. This takes
101 // O(# of apps) worst-case.
102 syncer::StringOrdinal
PageIntegerAsStringOrdinal(size_t page_index
);
104 // Hidden extensions don't appear in the new tab page.
105 void MarkExtensionAsHidden(const std::string
& extension_id
);
108 // The StringOrdinal is the app launch ordinal and the string is the extension
110 typedef std::multimap
<
111 syncer::StringOrdinal
, std::string
,
112 syncer::StringOrdinal::LessThanFn
> AppLaunchOrdinalMap
;
113 // The StringOrdinal is the page ordinal and the AppLaunchOrdinalMap is the
114 // contents of that page.
116 syncer::StringOrdinal
, AppLaunchOrdinalMap
,
117 syncer::StringOrdinal::LessThanFn
> PageOrdinalMap
;
120 friend class ExtensionSortingDefaultOrdinalsBase
;
121 friend class ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage
;
122 friend class ExtensionSortingInitializeWithNoApps
;
123 friend class ExtensionSortingPageOrdinalMapping
;
125 // An enum used by GetMinOrMaxAppLaunchOrdinalsOnPage to specify which
126 // value should be returned.
127 enum AppLaunchOrdinalReturn
{MIN_ORDINAL
, MAX_ORDINAL
};
129 // Maps an app id to its ordinals.
134 syncer::StringOrdinal page_ordinal
;
135 syncer::StringOrdinal app_launch_ordinal
;
137 typedef std::map
<std::string
, AppOrdinals
> AppOrdinalsMap
;
139 // This function returns the lowest ordinal on |page_ordinal| if
140 // |return_value| == AppLaunchOrdinalReturn::MIN_ORDINAL, otherwise it returns
141 // the largest ordinal on |page_ordinal|. If there are no apps on the page
142 // then an invalid StringOrdinal is returned. It is an error to call this
143 // function with an invalid |page_ordinal|.
144 syncer::StringOrdinal
GetMinOrMaxAppLaunchOrdinalsOnPage(
145 const syncer::StringOrdinal
& page_ordinal
,
146 AppLaunchOrdinalReturn return_type
) const;
148 // Initialize the |page_ordinal_map_| with the page ordinals used by the
150 void InitializePageOrdinalMap(
151 const extensions::ExtensionIdList
& extension_ids
);
153 // Migrates the app launcher and page index values.
154 void MigrateAppIndex(
155 const extensions::ExtensionIdList
& extension_ids
);
157 // Called to add a new mapping value for |extension_id| with a page ordinal
158 // of |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. This
159 // works with valid and invalid StringOrdinals.
160 void AddOrdinalMapping(const std::string
& extension_id
,
161 const syncer::StringOrdinal
& page_ordinal
,
162 const syncer::StringOrdinal
& app_launch_ordinal
);
164 // Ensures |ntp_ordinal_map_| is of |minimum_size| number of entries.
165 void CreateOrdinalsIfNecessary(size_t minimum_size
);
167 // Removes the mapping for |extension_id| with a page ordinal of
168 // |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. If there
169 // is not matching map, nothing happens. This works with valid and invalid
171 void RemoveOrdinalMapping(const std::string
& extension_id
,
172 const syncer::StringOrdinal
& page_ordinal
,
173 const syncer::StringOrdinal
& app_launch_ordinal
);
175 // Syncs the extension if needed. It is an error to call this if the
176 // extension is not an application.
177 void SyncIfNeeded(const std::string
& extension_id
);
179 // Creates the default ordinals.
180 void CreateDefaultOrdinals();
182 // Gets the default ordinals for |extension_id|. Returns false if no default
183 // ordinals for |extension_id| is defined. Otherwise, returns true and
184 // ordinals is updated with corresponding ordinals.
185 bool GetDefaultOrdinals(const std::string
& extension_id
,
186 syncer::StringOrdinal
* page_ordinal
,
187 syncer::StringOrdinal
* app_launch_ordinal
);
189 // Returns |app_launch_ordinal| if it has no collision in the page specified
190 // by |page_ordinal|. Otherwise, returns an ordinal after |app_launch_ordinal|
191 // that has no conflict.
192 syncer::StringOrdinal
ResolveCollision(
193 const syncer::StringOrdinal
& page_ordinal
,
194 const syncer::StringOrdinal
& app_launch_ordinal
) const;
196 // Returns the number of items in |m| visible on the new tab page.
197 size_t CountItemsVisibleOnNtp(const AppLaunchOrdinalMap
& m
) const;
199 ExtensionScopedPrefs
* extension_scoped_prefs_
; // Weak, owns this instance.
200 ExtensionServiceInterface
* extension_service_
; // Weak.
202 // A map of all the StringOrdinal page ordinals mapping to the collections of
203 // app launch ordinals that exist on that page. This is used for mapping
204 // StringOrdinals to their Integer equivalent as well as quick lookup of the
205 // any collision of on the NTP (icons with the same page and same app launch
206 // ordinals). The possiblity of collisions means that a multimap must be used
207 // (although the collisions must all be resolved once all the syncing is
209 PageOrdinalMap ntp_ordinal_map_
;
211 // Defines the default ordinals.
212 AppOrdinalsMap default_ordinals_
;
214 // Used to construct the default ordinals once when needed instead of on
215 // construction when the app order may not have been determined.
216 bool default_ordinals_created_
;
218 // The set of extensions that don't appear in the new tab page.
219 std::set
<std::string
> ntp_hidden_extensions_
;
221 DISALLOW_COPY_AND_ASSIGN(ExtensionSorting
);
224 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SORTING_H_