OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef CHROME_BROWSER_UI_VIEWS_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_H_ | |
6 #define CHROME_BROWSER_UI_VIEWS_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_H_ | |
7 | |
8 #include <list> | |
9 #include <map> | |
10 #include <string> | |
11 | |
12 #include "ash/launcher/launcher_delegate.h" | |
13 #include "ash/launcher/launcher_model_observer.h" | |
14 #include "ash/launcher/launcher_types.h" | |
15 #include "ash/shell_observer.h" | |
16 #include "ash/wm/shelf_types.h" | |
17 #include "base/basictypes.h" | |
18 #include "base/compiler_specific.h" | |
19 #include "base/memory/scoped_ptr.h" | |
20 #include "chrome/browser/extensions/extension_prefs.h" | |
21 #include "chrome/browser/extensions/shell_window_registry.h" | |
22 #include "chrome/browser/prefs/pref_change_registrar.h" | |
23 #include "content/public/browser/notification_observer.h" | |
24 #include "content/public/browser/notification_registrar.h" | |
25 #include "ui/aura/client/activation_change_observer.h" | |
26 #include "ui/aura/window_observer.h" | |
27 | |
28 namespace ash { | |
29 class LauncherModel; | |
30 } | |
31 | |
32 namespace aura { | |
33 class Window; | |
34 | |
35 namespace client { | |
36 class ActivationClient; | |
37 } | |
38 | |
39 } | |
40 | |
41 class BrowserLauncherItemController; | |
42 class BrowserLauncherItemControllerTest; | |
43 class PrefService; | |
44 class Profile; | |
45 class TabContents; | |
46 | |
47 // ChromeLauncherController manages the launcher items needed for tabbed | |
48 // browsers (BrowserLauncherItemController) and browser shortcuts. | |
49 class ChromeLauncherController | |
50 : public ash::LauncherDelegate, | |
51 public ash::LauncherModelObserver, | |
52 public ash::ShellObserver, | |
53 public content::NotificationObserver, | |
54 public ShellWindowRegistry::Observer, | |
55 public aura::client::ActivationChangeObserver, | |
56 public aura::WindowObserver { | |
57 public: | |
58 // Indicates if a launcher item is incognito or not. | |
59 enum IncognitoState { | |
60 STATE_INCOGNITO, | |
61 STATE_NOT_INCOGNITO, | |
62 }; | |
63 | |
64 // Used to update the state of non plaform apps, as tab contents change. | |
65 enum AppState { | |
66 APP_STATE_ACTIVE, | |
67 APP_STATE_WINDOW_ACTIVE, | |
68 APP_STATE_INACTIVE, | |
69 APP_STATE_REMOVED | |
70 }; | |
71 | |
72 // Mockable interface to get app ids from tabs. | |
73 class AppTabHelper { | |
74 public: | |
75 virtual ~AppTabHelper() {} | |
76 | |
77 // Returns the app id of the specified tab, or an empty string if there is | |
78 // no app. | |
79 virtual std::string GetAppID(TabContents* tab) = 0; | |
80 | |
81 // Returns true if |id| is valid. Used during restore to ignore no longer | |
82 // valid extensions. | |
83 virtual bool IsValidID(const std::string& id) = 0; | |
84 }; | |
85 | |
86 // Interface used to load app icons. This is in it's own class so that it can | |
87 // be mocked. | |
88 class AppIconLoader { | |
89 public: | |
90 virtual ~AppIconLoader() {} | |
91 | |
92 // Fetches the image for the specified id. When done (which may be | |
93 // synchronous), this should invoke SetAppImage() on the LauncherUpdater. | |
94 virtual void FetchImage(const std::string& id) = 0; | |
95 }; | |
96 | |
97 ChromeLauncherController(Profile* profile, ash::LauncherModel* model); | |
98 virtual ~ChromeLauncherController(); | |
99 | |
100 // Initializes this ChromeLauncherController. | |
101 void Init(); | |
102 | |
103 // Returns the single ChromeLauncherController instnace. | |
104 static ChromeLauncherController* instance() { return instance_; } | |
105 | |
106 // Creates a new tabbed item on the launcher for |controller|. | |
107 ash::LauncherID CreateTabbedLauncherItem( | |
108 BrowserLauncherItemController* controller, | |
109 IncognitoState is_incognito, | |
110 ash::LauncherItemStatus status); | |
111 | |
112 // Creates a new app item on the launcher for |controller|. | |
113 ash::LauncherID CreateAppLauncherItem( | |
114 BrowserLauncherItemController* controller, | |
115 const std::string& app_id, | |
116 ash::LauncherItemStatus status); | |
117 | |
118 // Updates the running status of an item. | |
119 void SetItemStatus(ash::LauncherID id, ash::LauncherItemStatus status); | |
120 | |
121 // Invoked when the underlying browser/app is closed. | |
122 void LauncherItemClosed(ash::LauncherID id); | |
123 | |
124 // Pins the specified id. Currently only supports platform apps. | |
125 void Pin(ash::LauncherID id); | |
126 | |
127 // Unpins the specified id, closing if not running. | |
128 void Unpin(ash::LauncherID id); | |
129 | |
130 // Returns true if the item identified by |id| is pinned. | |
131 bool IsPinned(ash::LauncherID id); | |
132 | |
133 // Pins/unpins the specified id. | |
134 void TogglePinned(ash::LauncherID id); | |
135 | |
136 // Returns true if the specified item can be pinned or unpinned. Only apps can | |
137 // be pinned. | |
138 bool IsPinnable(ash::LauncherID id) const; | |
139 | |
140 // Opens the specified item. |event_flags| holds the flags of the | |
141 // event which triggered this command. | |
142 void Open(ash::LauncherID id, int event_flags); | |
143 | |
144 // Opens the application identified by |app_id|. If already running | |
145 // reactivates the most recently used window or tab owned by the app. | |
146 void OpenAppID(const std::string& app_id, int event_flags); | |
147 | |
148 // Closes the specified item. | |
149 void Close(ash::LauncherID id); | |
150 | |
151 // Returns true if the specified item is open. | |
152 bool IsOpen(ash::LauncherID id); | |
153 | |
154 // Returns the launch type of app for the specified id. | |
155 extensions::ExtensionPrefs::LaunchType GetLaunchType(ash::LauncherID id); | |
156 | |
157 // Returns the id of the app for the specified tab. | |
158 std::string GetAppID(TabContents* tab); | |
159 | |
160 ash::LauncherID GetLauncherIDForAppID(const std::string& app_id); | |
161 | |
162 // Sets the image for an app tab. This is intended to be invoked from the | |
163 // AppIconLoader. | |
164 void SetAppImage(const std::string& app_id, const gfx::ImageSkia& image); | |
165 | |
166 // Returns true if a pinned launcher item with given |app_id| could be found. | |
167 bool IsAppPinned(const std::string& app_id); | |
168 | |
169 // Pins an app with |app_id| to launcher. If there is a running instance in | |
170 // launcher, the running instance is pinned. If there is no running instance, | |
171 // a new launcher item is created and pinned. | |
172 void PinAppWithID(const std::string& app_id); | |
173 | |
174 // Updates the launche type of the app for the specified id to |launch_type|. | |
175 void SetLaunchType(ash::LauncherID id, | |
176 extensions::ExtensionPrefs::LaunchType launch_type); | |
177 | |
178 // Unpins any app items whose id is |app_id|. | |
179 void UnpinAppsWithID(const std::string& app_id); | |
180 | |
181 // Returns true if the user is currently logged in as a guest. | |
182 bool IsLoggedInAsGuest(); | |
183 | |
184 // Invoked when the user clicks on button in the launcher to create a new | |
185 // incognito window. | |
186 void CreateNewIncognitoWindow(); | |
187 | |
188 // Checks whether the user is allowed to pin apps. Pinning may be disallowed | |
189 // by policy in case there is a pre-defined set of pinned apps. | |
190 bool CanPin() const; | |
191 | |
192 // Updates the pinned pref state. The pinned state consists of a list pref. | |
193 // Each item of the list is a dictionary. The key |kAppIDPath| gives the | |
194 // id of the app. | |
195 void PersistPinnedState(); | |
196 | |
197 ash::LauncherModel* model() { return model_; } | |
198 | |
199 Profile* profile() { return profile_; } | |
200 | |
201 void SetAutoHideBehavior(ash::ShelfAutoHideBehavior behavior); | |
202 | |
203 // The tab no longer represents its previously identified application. | |
204 void RemoveTabFromRunningApp(TabContents* tab, const std::string& app_id); | |
205 | |
206 // Notify the controller that the state of an non platform app's tabs | |
207 // have changed, | |
208 void UpdateAppState(TabContents* tab, AppState app_state); | |
209 | |
210 // ash::LauncherDelegate overrides: | |
211 virtual void CreateNewTab() OVERRIDE; | |
212 virtual void CreateNewWindow() OVERRIDE; | |
213 virtual void ItemClicked(const ash::LauncherItem& item, | |
214 int event_flags) OVERRIDE; | |
215 virtual int GetBrowserShortcutResourceId() OVERRIDE; | |
216 virtual string16 GetTitle(const ash::LauncherItem& item) OVERRIDE; | |
217 virtual ui::MenuModel* CreateContextMenu( | |
218 const ash::LauncherItem& item) OVERRIDE; | |
219 virtual ui::MenuModel* CreateContextMenuForLauncher() OVERRIDE; | |
220 virtual ash::LauncherID GetIDByWindow(aura::Window* window) OVERRIDE; | |
221 virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE; | |
222 | |
223 // ash::LauncherModelObserver overrides: | |
224 virtual void LauncherItemAdded(int index) OVERRIDE; | |
225 virtual void LauncherItemRemoved(int index, ash::LauncherID id) OVERRIDE; | |
226 virtual void LauncherItemMoved(int start_index, int target_index) OVERRIDE; | |
227 virtual void LauncherItemChanged(int index, | |
228 const ash::LauncherItem& old_item) OVERRIDE; | |
229 | |
230 // Overridden from content::NotificationObserver: | |
231 virtual void Observe(int type, | |
232 const content::NotificationSource& source, | |
233 const content::NotificationDetails& details) OVERRIDE; | |
234 | |
235 // Overridden from ShellWindowRegistry::Observer: | |
236 virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE; | |
237 virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE; | |
238 | |
239 // Overriden from client::ActivationChangeObserver: | |
240 virtual void OnWindowActivated( | |
241 aura::Window* active, | |
242 aura::Window* old_active) OVERRIDE; | |
243 | |
244 // Overriden from aura::WindowObserver: | |
245 virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE; | |
246 | |
247 // Overriden from ash::ShellObserver: | |
248 virtual void OnShelfAlignmentChanged() OVERRIDE; | |
249 | |
250 private: | |
251 friend class BrowserLauncherItemControllerTest; | |
252 friend class ChromeLauncherControllerTest; | |
253 | |
254 enum ItemType { | |
255 TYPE_APP, | |
256 TYPE_TABBED_BROWSER | |
257 }; | |
258 | |
259 // Used to identity an item on the launcher. | |
260 struct Item { | |
261 Item(); | |
262 ~Item(); | |
263 | |
264 // Type of item. | |
265 ItemType item_type; | |
266 | |
267 // ID of the app. | |
268 std::string app_id; | |
269 | |
270 // The BrowserLauncherItemController this item came from. NULL if a | |
271 // shortcut. | |
272 BrowserLauncherItemController* controller; | |
273 }; | |
274 | |
275 typedef std::map<ash::LauncherID, Item> IDToItemMap; | |
276 typedef std::map<aura::Window*, ash::LauncherID> WindowToIDMap; | |
277 typedef std::list<aura::Window*> WindowList; | |
278 typedef std::list<TabContents*> TabContentsList; | |
279 typedef std::map<std::string, TabContentsList> AppIDToTabContentsListMap; | |
280 typedef std::map<TabContents*, std::string> TabContentsToAppIDMap; | |
281 | |
282 // Sets the AppTabHelper/AppIconLoader, taking ownership of the helper class. | |
283 // These are intended for testing. | |
284 void SetAppTabHelperForTest(AppTabHelper* helper); | |
285 void SetAppIconLoaderForTest(AppIconLoader* loader); | |
286 | |
287 // Returns the profile used for new windows. | |
288 Profile* GetProfileForNewWindows(); | |
289 | |
290 // Returns item status for given |id|. | |
291 ash::LauncherItemStatus GetItemStatus(ash::LauncherID id) const; | |
292 | |
293 // Finds the launcher item that represents given |app_id| and updates the | |
294 // pending state. | |
295 void MarkAppPending(const std::string& app_id); | |
296 | |
297 // Internal helpers for pinning and unpinning that handle both | |
298 // client-triggered and internal pinning operations. | |
299 void DoPinAppWithID(const std::string& app_id); | |
300 void DoUnpinAppsWithID(const std::string& app_id); | |
301 | |
302 // Re-syncs launcher model with prefs::kPinnedLauncherApps. | |
303 void UpdateAppLaunchersFromPref(); | |
304 | |
305 // Sets the shelf auto-hide behavior from prefs. | |
306 void SetShelfAutoHideBehaviorFromPrefs(); | |
307 | |
308 // Sets the shelf alignment from prefs. | |
309 void SetShelfAlignmentFromPrefs(); | |
310 | |
311 // Returns the most recently active tab contents for an app. | |
312 TabContents* GetLastActiveTabContents(const std::string& app_id); | |
313 | |
314 // Creates an app launcher to insert at |index|. Note that |index| may be | |
315 // adjusted by the model to meet ordering constraints. | |
316 ash::LauncherID InsertAppLauncherItem( | |
317 BrowserLauncherItemController* controller, | |
318 const std::string& app_id, | |
319 ash::LauncherItemStatus status, | |
320 int index); | |
321 | |
322 static ChromeLauncherController* instance_; | |
323 | |
324 ash::LauncherModel* model_; | |
325 | |
326 // Profile used for prefs and loading extensions. This is NOT necessarily the | |
327 // profile new windows are created with. | |
328 Profile* profile_; | |
329 | |
330 IDToItemMap id_to_item_map_; | |
331 | |
332 // Maintains activation order of tab contents for each app. | |
333 AppIDToTabContentsListMap app_id_to_tab_contents_list_; | |
334 | |
335 // Direct access to app_id for a tab contents. | |
336 TabContentsToAppIDMap tab_contents_to_app_id_; | |
337 | |
338 // Allows us to get from an aura::Window to the id of a launcher item. | |
339 // Currently only used for platform app windows. | |
340 WindowToIDMap window_to_id_map_; | |
341 | |
342 // Maintains the activation order. The first element is most recent. | |
343 // Currently only used for platform app windows. | |
344 WindowList platform_app_windows_; | |
345 | |
346 // Used to get app info for tabs. | |
347 scoped_ptr<AppTabHelper> app_tab_helper_; | |
348 | |
349 // Used to load the image for an app item. | |
350 scoped_ptr<AppIconLoader> app_icon_loader_; | |
351 | |
352 content::NotificationRegistrar notification_registrar_; | |
353 | |
354 PrefChangeRegistrar pref_change_registrar_; | |
355 aura::client::ActivationClient* activation_client_; | |
356 | |
357 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherController); | |
358 }; | |
359 | |
360 #endif // CHROME_BROWSER_UI_VIEWS_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_H_ | |
OLD | NEW |