1// Copyright 2013 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_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_H_ 6#define CHROME_BROWSER_UI_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_H_ 7 8#include <list> 9#include <map> 10#include <set> 11#include <string> 12#include <vector> 13 14#include "ash/display/display_controller.h" 15#include "ash/shelf/shelf_delegate.h" 16#include "ash/shelf/shelf_item_delegate.h" 17#include "ash/shelf/shelf_item_types.h" 18#include "ash/shelf/shelf_layout_manager_observer.h" 19#include "ash/shelf/shelf_model_observer.h" 20#include "ash/shelf/shelf_types.h" 21#include "ash/shell_observer.h" 22#include "base/basictypes.h" 23#include "base/compiler_specific.h" 24#include "base/memory/scoped_ptr.h" 25#include "base/memory/scoped_vector.h" 26#include "base/prefs/pref_change_registrar.h" 27#include "chrome/browser/extensions/app_icon_loader.h" 28#include "chrome/browser/prefs/pref_service_syncable_observer.h" 29#include "chrome/browser/ui/ash/app_sync_ui_state_observer.h" 30#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" 31#include "chrome/browser/ui/ash/launcher/chrome_launcher_types.h" 32#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" 33#include "chrome/common/extensions/extension_constants.h" 34#include "extensions/browser/extension_registry_observer.h" 35#include "ui/aura/window_observer.h" 36 37class AppSyncUIState; 38class Browser; 39class BrowserShortcutLauncherItemController; 40class BrowserStatusMonitor; 41class ExtensionEnableFlow; 42class GURL; 43class LauncherItemController; 44class Profile; 45class AppWindowLauncherController; 46class TabContents; 47 48namespace ash { 49class ShelfItemDelegateManager; 50class ShelfModel; 51} 52 53namespace aura { 54class Window; 55} 56 57namespace content { 58class BrowserContext; 59class WebContents; 60} 61 62namespace extensions { 63class Extension; 64} 65 66namespace ui { 67class BaseWindow; 68} 69 70// A list of the elements which makes up a simple menu description. 71typedef ScopedVector<ChromeLauncherAppMenuItem> ChromeLauncherAppMenuItems; 72 73// A class which needs to be overwritten dependent on the used OS to moitor 74// user switching. 75class ChromeLauncherControllerUserSwitchObserver { 76 public: 77 ChromeLauncherControllerUserSwitchObserver() {} 78 virtual ~ChromeLauncherControllerUserSwitchObserver() {} 79 80 private: 81 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserver); 82}; 83 84// ChromeLauncherController manages the launcher items needed for content 85// windows. Launcher items have a type, an optional app id, and a controller. 86// This incarnation groups running tabs/windows in application specific lists. 87// * Browser app windows have BrowserLauncherItemController, owned by the 88// BrowserView instance. 89// * App windows have AppWindowLauncherItemController, owned by 90// AppWindowLauncherController. 91// * Shortcuts have no LauncherItemController. 92class ChromeLauncherController : public ash::ShelfDelegate, 93 public ash::ShelfModelObserver, 94 public ash::ShellObserver, 95 public ash::DisplayController::Observer, 96 public extensions::ExtensionRegistryObserver, 97 public extensions::AppIconLoader::Delegate, 98 public PrefServiceSyncableObserver, 99 public AppSyncUIStateObserver, 100 public ExtensionEnableFlowDelegate, 101 public ash::ShelfLayoutManagerObserver { 102 public: 103 // Indicates if a shelf item is incognito or not. 104 enum IncognitoState { 105 STATE_INCOGNITO, 106 STATE_NOT_INCOGNITO, 107 }; 108 109 // Used to update the state of non plaform apps, as web contents change. 110 enum AppState { 111 APP_STATE_ACTIVE, 112 APP_STATE_WINDOW_ACTIVE, 113 APP_STATE_INACTIVE, 114 APP_STATE_REMOVED 115 }; 116 117 // Mockable interface to get app ids from tabs. 118 class AppTabHelper { 119 public: 120 virtual ~AppTabHelper() {} 121 122 // Returns the app id of the specified tab, or an empty string if there is 123 // no app. All known profiles will be queried for this. 124 virtual std::string GetAppID(content::WebContents* tab) = 0; 125 126 // Returns true if |id| is valid for the currently active profile. 127 // Used during restore to ignore no longer valid extensions. 128 // Note that already running applications are ignored by the restore 129 // process. 130 virtual bool IsValidIDForCurrentUser(const std::string& id) = 0; 131 132 // Sets the currently active profile for the usage of |GetAppID|. 133 virtual void SetCurrentUser(Profile* profile) = 0; 134 }; 135 136 ChromeLauncherController(Profile* profile, ash::ShelfModel* model); 137 virtual ~ChromeLauncherController(); 138 139 // Initializes this ChromeLauncherController. 140 void Init(); 141 142 // Creates an instance. 143 static ChromeLauncherController* CreateInstance(Profile* profile, 144 ash::ShelfModel* model); 145 146 // Returns the single ChromeLauncherController instance. 147 static ChromeLauncherController* instance() { return instance_; } 148 149 // Creates a new app item on the shelf for |controller|. 150 ash::ShelfID CreateAppLauncherItem(LauncherItemController* controller, 151 const std::string& app_id, 152 ash::ShelfItemStatus status); 153 154 // Updates the running status of an item. It will also update the status of 155 // browsers shelf item if needed. 156 void SetItemStatus(ash::ShelfID id, ash::ShelfItemStatus status); 157 158 // Updates the controller associated with id (which should be a shortcut). 159 // |controller| remains owned by caller. 160 void SetItemController(ash::ShelfID id, LauncherItemController* controller); 161 162 // Closes or unpins the shelf item. 163 void CloseLauncherItem(ash::ShelfID id); 164 165 // Pins the specified id. Currently only supports platform apps. 166 void Pin(ash::ShelfID id); 167 168 // Unpins the specified id, closing if not running. 169 void Unpin(ash::ShelfID id); 170 171 // Returns true if the item identified by |id| is pinned. 172 bool IsPinned(ash::ShelfID id); 173 174 // Pins/unpins the specified id. 175 void TogglePinned(ash::ShelfID id); 176 177 // Returns true if the specified item can be pinned or unpinned. Only apps can 178 // be pinned. 179 bool IsPinnable(ash::ShelfID id) const; 180 181 // Installs the specified id. Only valid if the id corresponds to an ephemeral 182 // app. 183 void Install(ash::ShelfID id); 184 185 // Returns true if the specified item can be installed. Only true for 186 // ephemeral apps. 187 bool CanInstall(ash::ShelfID id); 188 189 // If there is no shelf item in the shelf for application |app_id|, one 190 // gets created. The (existing or created) shelf items get then locked 191 // against a users un-pinning removal. 192 void LockV1AppWithID(const std::string& app_id); 193 194 // A previously locked shelf item of type |app_id| gets unlocked. If the 195 // lock count reaches 0 and the item is not pinned it will go away. 196 void UnlockV1AppWithID(const std::string& app_id); 197 198 // Requests that the shelf item controller specified by |id| open a new 199 // instance of the app. |event_flags| holds the flags of the event which 200 // triggered this command. 201 void Launch(ash::ShelfID id, int event_flags); 202 203 // Closes the specified item. 204 void Close(ash::ShelfID id); 205 206 // Returns true if the specified item is open. 207 bool IsOpen(ash::ShelfID id); 208 209 // Returns true if the specified item is for a platform app. 210 bool IsPlatformApp(ash::ShelfID id); 211 212 // Opens a new instance of the application identified by |app_id|. 213 // Used by the app-list, and by pinned-app shelf items. 214 void LaunchApp(const std::string& app_id, 215 ash::LaunchSource source, 216 int event_flags); 217 218 // If |app_id| is running, reactivates the app's most recently active window, 219 // otherwise launches and activates the app. 220 // Used by the app-list, and by pinned-app shelf items. 221 void ActivateApp(const std::string& app_id, 222 ash::LaunchSource source, 223 int event_flags); 224 225 // Returns the launch type of app for the specified id. 226 extensions::LaunchType GetLaunchType(ash::ShelfID id); 227 228 // Set the image for a specific shelf item (e.g. when set by the app). 229 void SetLauncherItemImage(ash::ShelfID shelf_id, const gfx::ImageSkia& image); 230 231 // Find out if the given application |id| is a windowed app item and not a 232 // pinned item in the shelf. 233 bool IsWindowedAppInLauncher(const std::string& app_id); 234 235 // Updates the launch type of the app for the specified id to |launch_type|. 236 void SetLaunchType(ash::ShelfID id, extensions::LaunchType launch_type); 237 238 // Returns true if the user is currently logged in as a guest. 239 // Makes virtual for unittest in LauncherContextMenuTest. 240 virtual bool IsLoggedInAsGuest(); 241 242 // Invoked when user clicks on button in the shelf and there is no last 243 // used window (or CTRL is held with the click). 244 void CreateNewWindow(); 245 246 // Invoked when the user clicks on button in the shelf to create a new 247 // incognito window. 248 void CreateNewIncognitoWindow(); 249 250 // Updates the pinned pref state. The pinned state consists of a list pref. 251 // Each item of the list is a dictionary. The key |kAppIDPath| gives the 252 // id of the app. 253 void PersistPinnedState(); 254 255 ash::ShelfModel* model(); 256 257 // Accessor to the currently loaded profile. Note that in multi profile use 258 // cases this might change over time. 259 Profile* profile(); 260 261 // Gets the shelf auto-hide behavior on |root_window|. 262 ash::ShelfAutoHideBehavior GetShelfAutoHideBehavior( 263 aura::Window* root_window) const; 264 265 // Returns |true| if the user is allowed to modify the shelf auto-hide 266 // behavior on |root_window|. 267 bool CanUserModifyShelfAutoHideBehavior(aura::Window* root_window) const; 268 269 // Toggles the shelf auto-hide behavior on |root_window|. Does nothing if the 270 // user is not allowed to modify the auto-hide behavior. 271 void ToggleShelfAutoHideBehavior(aura::Window* root_window); 272 273 // Notify the controller that the state of an non platform app's tabs 274 // have changed, 275 void UpdateAppState(content::WebContents* contents, AppState app_state); 276 277 // Returns ShelfID for |contents|. If |contents| is not an app or is not 278 // pinned, returns the id of browser shrotcut. 279 ash::ShelfID GetShelfIDForWebContents(content::WebContents* contents); 280 281 // Limits application refocusing to urls that match |url| for |id|. 282 void SetRefocusURLPatternForTest(ash::ShelfID id, const GURL& url); 283 284 // Returns the extension identified by |app_id|. 285 const extensions::Extension* GetExtensionForAppID( 286 const std::string& app_id) const; 287 288 // Activates a |window|. If |allow_minimize| is true and the system allows 289 // it, the the window will get minimized instead. 290 void ActivateWindowOrMinimizeIfActive(ui::BaseWindow* window, 291 bool allow_minimize); 292 293 // ash::ShelfDelegate overrides: 294 virtual void OnShelfCreated(ash::Shelf* shelf) OVERRIDE; 295 virtual void OnShelfDestroyed(ash::Shelf* shelf) OVERRIDE; 296 virtual ash::ShelfID GetShelfIDForAppID(const std::string& app_id) OVERRIDE; 297 virtual const std::string& GetAppIDForShelfID(ash::ShelfID id) OVERRIDE; 298 virtual void PinAppWithID(const std::string& app_id) OVERRIDE; 299 virtual bool IsAppPinned(const std::string& app_id) OVERRIDE; 300 virtual bool CanPin() const OVERRIDE; 301 virtual void UnpinAppWithID(const std::string& app_id) OVERRIDE; 302 303 // ash::ShelfModelObserver overrides: 304 virtual void ShelfItemAdded(int index) OVERRIDE; 305 virtual void ShelfItemRemoved(int index, ash::ShelfID id) OVERRIDE; 306 virtual void ShelfItemMoved(int start_index, int target_index) OVERRIDE; 307 virtual void ShelfItemChanged(int index, 308 const ash::ShelfItem& old_item) OVERRIDE; 309 virtual void ShelfStatusChanged() OVERRIDE; 310 311 // ash::ShellObserver overrides: 312 virtual void OnShelfAlignmentChanged(aura::Window* root_window) OVERRIDE; 313 314 // ash::DisplayController::Observer overrides: 315 virtual void OnDisplayConfigurationChanged() OVERRIDE; 316 317 // ExtensionRegistryObserver overrides: 318 virtual void OnExtensionLoaded( 319 content::BrowserContext* browser_context, 320 const extensions::Extension* extension) OVERRIDE; 321 virtual void OnExtensionUnloaded( 322 content::BrowserContext* browser_context, 323 const extensions::Extension* extension, 324 extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE; 325 326 // PrefServiceSyncableObserver overrides: 327 virtual void OnIsSyncingChanged() OVERRIDE; 328 329 // AppSyncUIStateObserver overrides: 330 virtual void OnAppSyncUIStatusChanged() OVERRIDE; 331 332 // ExtensionEnableFlowDelegate overrides: 333 virtual void ExtensionEnableFlowFinished() OVERRIDE; 334 virtual void ExtensionEnableFlowAborted(bool user_initiated) OVERRIDE; 335 336 // extensions::AppIconLoader overrides: 337 virtual void SetAppImage(const std::string& app_id, 338 const gfx::ImageSkia& image) OVERRIDE; 339 340 // ash::ShelfLayoutManagerObserver overrides: 341 virtual void OnAutoHideBehaviorChanged( 342 aura::Window* root_window, 343 ash::ShelfAutoHideBehavior new_behavior) OVERRIDE; 344 345 // Called when the active user has changed. 346 void ActiveUserChanged(const std::string& user_email); 347 348 // Called when a user got added to the session. 349 void AdditionalUserAddedToSession(Profile* profile); 350 351 // Get the list of all running incarnations of this item. 352 // |event_flags| specifies the flags which were set by the event which 353 // triggered this menu generation. It can be used to generate different lists. 354 ChromeLauncherAppMenuItems GetApplicationList(const ash::ShelfItem& item, 355 int event_flags); 356 357 // Get the list of all tabs which belong to a certain application type. 358 std::vector<content::WebContents*> GetV1ApplicationsFromAppId( 359 std::string app_id); 360 361 // Activates a specified shell application. 362 void ActivateShellApp(const std::string& app_id, int index); 363 364 // Checks if a given |web_contents| is known to be associated with an 365 // application of type |app_id|. 366 bool IsWebContentHandledByApplication(content::WebContents* web_contents, 367 const std::string& app_id); 368 369 // Check if the gMail app is loaded and it can handle the given web content. 370 // This special treatment is required to address crbug.com/234268. 371 bool ContentCanBeHandledByGmailApp(content::WebContents* web_contents); 372 373 // Get the favicon for the application list entry for |web_contents|. 374 // Note that for incognito windows the incognito icon will be returned. 375 // If |web_contents| has not loaded, returns the default favicon. 376 gfx::Image GetAppListIcon(content::WebContents* web_contents) const; 377 378 // Get the title for the applicatoin list entry for |web_contents|. 379 // If |web_contents| has not loaded, returns "Net Tab". 380 base::string16 GetAppListTitle(content::WebContents* web_contents) const; 381 382 // Returns the LauncherItemController of BrowserShortcut. 383 BrowserShortcutLauncherItemController* 384 GetBrowserShortcutLauncherItemController(); 385 386 LauncherItemController* GetLauncherItemController(const ash::ShelfID id); 387 388 // Returns true if |browser| is owned by the active user. 389 bool IsBrowserFromActiveUser(Browser* browser); 390 391 // Check if the shelf visibility (location, visibility) will change with a new 392 // user profile or not. However, since the full visibility calculation of the 393 // shelf cannot be performed here, this is only a probability used for 394 // animation predictions. 395 bool ShelfBoundsChangesProbablyWithUser(aura::Window* root_window, 396 const std::string& user_id) const; 397 398 // Access to the BrowserStatusMonitor for tests. 399 BrowserStatusMonitor* browser_status_monitor_for_test() { 400 return browser_status_monitor_.get(); 401 } 402 403 // Access to the AppWindowLauncherController for tests. 404 AppWindowLauncherController* app_window_controller_for_test() { 405 return app_window_controller_.get(); 406 } 407 408 protected: 409 // Creates a new app shortcut item and controller on the shelf at |index|. 410 // Use kInsertItemAtEnd to add a shortcut as the last item. 411 ash::ShelfID CreateAppShortcutLauncherItem(const std::string& app_id, 412 int index); 413 414 // Sets the AppTabHelper/AppIconLoader, taking ownership of the helper class. 415 // These are intended for testing. 416 void SetAppTabHelperForTest(AppTabHelper* helper); 417 void SetAppIconLoaderForTest(extensions::AppIconLoader* loader); 418 const std::string& GetAppIdFromShelfIdForTest(ash::ShelfID id); 419 420 // Sets the ash::ShelfItemDelegateManager only for unittests and doesn't 421 // take an ownership of it. 422 void SetShelfItemDelegateManagerForTest( 423 ash::ShelfItemDelegateManager* manager); 424 425 private: 426 friend class ChromeLauncherControllerTest; 427 friend class ShelfAppBrowserTest; 428 friend class LauncherPlatformAppBrowserTest; 429 430 typedef std::map<ash::ShelfID, LauncherItemController*> IDToItemControllerMap; 431 typedef std::map<content::WebContents*, std::string> WebContentsToAppIDMap; 432 433 // Remembers / restores list of running applications. 434 // Note that this order will neither be stored in the preference nor will it 435 // remember the order of closed applications since it is only temporary. 436 void RememberUnpinnedRunningApplicationOrder(); 437 void RestoreUnpinnedRunningApplicationOrder(const std::string& user_id); 438 439 // Creates a new app shortcut item and controller on the shelf at |index|. 440 // Use kInsertItemAtEnd to add a shortcut as the last item. 441 ash::ShelfID CreateAppShortcutLauncherItemWithType( 442 const std::string& app_id, 443 int index, 444 ash::ShelfItemType shelf_item_type); 445 446 // Invoked when the associated browser or app is closed. 447 void LauncherItemClosed(ash::ShelfID id); 448 449 // Internal helpers for pinning and unpinning that handle both 450 // client-triggered and internal pinning operations. 451 void DoPinAppWithID(const std::string& app_id); 452 void DoUnpinAppWithID(const std::string& app_id); 453 454 // Pin a running app with |shelf_id| internally to |index|. It returns 455 // the index where the item was pinned. 456 int PinRunningAppInternal(int index, ash::ShelfID shelf_id); 457 458 // Unpin a locked application. This is an internal call which converts the 459 // model type of the given app index from a shortcut into an unpinned running 460 // app. 461 void UnpinRunningAppInternal(int index); 462 463 // Re-syncs shelf model with prefs::kPinnedLauncherApps. 464 void UpdateAppLaunchersFromPref(); 465 466 // Persists the shelf auto-hide behavior to prefs. 467 void SetShelfAutoHideBehaviorPrefs(ash::ShelfAutoHideBehavior behavior, 468 aura::Window* root_window); 469 470 // Sets the shelf auto-hide behavior from prefs. 471 void SetShelfAutoHideBehaviorFromPrefs(); 472 473 // Sets the shelf alignment from prefs. 474 void SetShelfAlignmentFromPrefs(); 475 476 // Sets both of auto-hide behavior and alignment from prefs. 477 void SetShelfBehaviorsFromPrefs(); 478 479#if defined(OS_CHROMEOS) 480 // Sets whether the virtual keyboard is enabled from prefs. 481 void SetVirtualKeyboardBehaviorFromPrefs(); 482#endif // defined(OS_CHROMEOS) 483 484 // Returns the shelf item status for the given |app_id|, which can be either 485 // STATUS_ACTIVE (if the app is active), STATUS_RUNNING (if there is such an 486 // app) or STATUS_CLOSED. 487 ash::ShelfItemStatus GetAppState(const std::string& app_id); 488 489 // Creates an app launcher to insert at |index|. Note that |index| may be 490 // adjusted by the model to meet ordering constraints. 491 // The |shelf_item_type| will be set into the ShelfModel. 492 ash::ShelfID InsertAppLauncherItem(LauncherItemController* controller, 493 const std::string& app_id, 494 ash::ShelfItemStatus status, 495 int index, 496 ash::ShelfItemType shelf_item_type); 497 498 bool HasItemController(ash::ShelfID id) const; 499 500 // Enumerate all Web contents which match a given shortcut |controller|. 501 std::vector<content::WebContents*> GetV1ApplicationsFromController( 502 LauncherItemController* controller); 503 504 // Create ShelfItem for Browser Shortcut. 505 ash::ShelfID CreateBrowserShortcutLauncherItem(); 506 507 // Check if the given |web_contents| is in incognito mode. 508 bool IsIncognito(const content::WebContents* web_contents) const; 509 510 // Update browser shortcut's index. 511 void PersistChromeItemIndex(int index); 512 513 // Get browser shortcut's index from pref. 514 int GetChromeIconIndexFromPref() const; 515 516 // Depending on the provided flags, move either the chrome icon, the app icon 517 // or none to the given |target_index|. The provided |chrome_index| and 518 // |app_list_index| locations will get adjusted within this call to finalize 519 // the action and to make sure that the other item can still be moved 520 // afterwards (index adjustments). 521 void MoveChromeOrApplistToFinalPosition( 522 bool is_chrome, 523 bool is_app_list, 524 int target_index, 525 int* chrome_index, 526 int* app_list_index); 527 528 // Finds the index of where to insert the next item. 529 int FindInsertionPoint(bool is_app_list); 530 531 // Get the browser shortcut's index in the shelf using the current's systems 532 // configuration of pinned and known (but not running) apps. 533 int GetChromeIconIndexForCreation(); 534 535 // Get the list of pinned programs from the preferences. 536 std::vector<std::string> GetListOfPinnedAppsAndBrowser(); 537 538 // Close all windowed V1 applications of a certain extension which was already 539 // deleted. 540 void CloseWindowedAppsFromRemovedExtension(const std::string& app_id, 541 const Profile* profile); 542 543 // Set ShelfItemDelegate |item_delegate| for |id| and take an ownership. 544 // TODO(simon.hong81): Make this take a scoped_ptr of |item_delegate|. 545 void SetShelfItemDelegate(ash::ShelfID id, 546 ash::ShelfItemDelegate* item_delegate); 547 548 // Attach to a specific profile. 549 void AttachProfile(Profile* proifile); 550 551 // Forget the current profile to allow attaching to a new one. 552 void ReleaseProfile(); 553 554 // Returns true if |app_id| is a Packaged App that has already launched on the 555 // native desktop and, if so, executes it as a desktop shortcut to activate 556 // desktop mode and send another OnLaunched event to the Extension. 557 bool LaunchedInNativeDesktop(const std::string& app_id); 558 559 static ChromeLauncherController* instance_; 560 561 ash::ShelfModel* model_; 562 563 ash::ShelfItemDelegateManager* item_delegate_manager_; 564 565 // Profile used for prefs and loading extensions. This is NOT necessarily the 566 // profile new windows are created with. 567 Profile* profile_; 568 569 IDToItemControllerMap id_to_item_controller_map_; 570 571 // Direct access to app_id for a web contents. 572 WebContentsToAppIDMap web_contents_to_app_id_; 573 574 // Used to track app windows. 575 scoped_ptr<AppWindowLauncherController> app_window_controller_; 576 577 // Used to get app info for tabs. 578 scoped_ptr<AppTabHelper> app_tab_helper_; 579 580 // Used to load the image for an app item. 581 scoped_ptr<extensions::AppIconLoader> app_icon_loader_; 582 583 PrefChangeRegistrar pref_change_registrar_; 584 585 AppSyncUIState* app_sync_ui_state_; 586 587 scoped_ptr<ExtensionEnableFlow> extension_enable_flow_; 588 589 // Shelves that are currently being observed. 590 std::set<ash::Shelf*> shelves_; 591 592 // The owned browser status monitor. 593 scoped_ptr<BrowserStatusMonitor> browser_status_monitor_; 594 595 // A special observer class to detect user switches. 596 scoped_ptr<ChromeLauncherControllerUserSwitchObserver> user_switch_observer_; 597 598 // If true, incoming pinned state changes should be ignored. 599 bool ignore_persist_pinned_state_change_; 600 601 // True if each user has an own desktop. 602 bool multi_profile_desktop_separation_; 603 604 // The list of running & un-pinned applications for different users on hidden 605 // desktops. 606 typedef std::vector<std::string> RunningAppListIds; 607 typedef std::map<std::string, RunningAppListIds> RunningAppListIdMap; 608 RunningAppListIdMap last_used_running_application_order_; 609 610 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherController); 611}; 612 613#endif // CHROME_BROWSER_UI_ASH_LAUNCHER_CHROME_LAUNCHER_CONTROLLER_H_ 614