Chromium Code Reviews| Index: chrome/browser/ui/views/app_list/app_list_controller_win.cc |
| diff --git a/chrome/browser/ui/views/app_list/app_list_controller_win.cc b/chrome/browser/ui/views/app_list/app_list_controller_win.cc |
| index 5765389da53f8441e08333aecb1631008f18d858..605cf7a5c1f00e9221a21a77cfaa1643ad9ab082 100644 |
| --- a/chrome/browser/ui/views/app_list/app_list_controller_win.cc |
| +++ b/chrome/browser/ui/views/app_list/app_list_controller_win.cc |
| @@ -17,6 +17,7 @@ |
| #include "chrome/browser/extensions/extension_prefs.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/lifetime/application_lifetime.h" |
| +#include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/shell_integration.h" |
| @@ -27,6 +28,7 @@ |
| #include "chrome/browser/ui/views/browser_dialogs.h" |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/common/chrome_switches.h" |
| +#include "chrome/common/pref_names.h" |
| #include "chrome/installer/launcher_support/chrome_launcher_support.h" |
| #include "chrome/installer/util/util_constants.h" |
| #include "content/public/browser/browser_thread.h" |
| @@ -119,22 +121,46 @@ class AppListControllerDelegateWin : public AppListControllerDelegate { |
| // list to operate, and controls when the app list is opened and closed. |
| class AppListController { |
| public: |
| - AppListController() |
| - : current_view_(NULL), |
| - can_close_app_list_(true), |
| - app_list_is_showing_(false) {} |
| - ~AppListController() {} |
| + AppListController(); |
| void set_can_close(bool can_close) { can_close_app_list_ = can_close; } |
| bool can_close() { return can_close_app_list_; } |
| - void CreateAppList(); |
| - void ShowAppList(); |
| + |
| + // Creates the app list view and populates it from |profile|, but doesn't |
| + // show it. Does nothing if the view already exists. |
| + void InitView(Profile* profile); |
| + |
| + // Activates the app list at the current mouse cursor location, creating the |
| + // app list if necessary. |
| + void ShowAppList(Profile* profile); |
| + |
| + // Update the profile path stored in local prefs, load it (if not already |
| + // loaded), and show the app list. |
| + void UpdateProfilePath(const FilePath& profile_file_path); |
| + |
| void DismissAppList(); |
| void AppListClosing(); |
| void AppListActivationChanged(bool active); |
| app_list::AppListView* GetView() { return current_view_; } |
| private: |
| + // Updates the view from |profile_|. |
| + void UpdateFromProfile(); |
|
benwells
2013/01/18 06:18:46
This doesn't appear to be used.
koz (OOO until 15th September)
2013/01/20 23:32:00
Done.
|
| + |
| + // Loads a profile asynchronously and calls OnProfileLoaded() when done. |
| + void LoadProfileAsync(const FilePath& profile_file_path); |
| + |
| + // Callback for asynchronous profile load. |
| + void OnProfileLoaded(int profile_load_sequence_id, |
| + Profile* profile, |
| + Profile::CreateStatus status); |
| + |
| + // Create or recreate, and initialize |current_view_| from |profile_|. |
| + void PopulateViewFromProfile(); |
| + |
| + // Activate the app list at the the current on-screen cursor location. |
| + void ActivateAppList(); |
| + |
| // Utility methods for showing the app list. |
| bool SnapArrowLocationToTaskbarEdge( |
| const gfx::Display& display, |
| @@ -163,6 +189,8 @@ class AppListController { |
| app_list::PaginationModel pagination_model_; |
| + Profile* profile_; |
| + |
| // True if the controller can close the app list. |
| bool can_close_app_list_; |
| @@ -170,6 +198,9 @@ class AppListController { |
| // browser process keep-alives active. |
| bool app_list_is_showing_; |
| + // Incremented to indicate that pending profile loads are no longer valid. |
| + int profile_load_sequence_id_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(AppListController); |
| }; |
| @@ -242,15 +273,97 @@ void AppListControllerDelegateWin::LaunchApp( |
| profile, extension, NEW_FOREGROUND_TAB)); |
| } |
| -void AppListController::CreateAppList() { |
| +AppListController::AppListController() |
| + : current_view_(NULL), |
| + profile_(NULL), |
| + can_close_app_list_(true), |
| + app_list_is_showing_(false), |
| + profile_load_sequence_id_(0) { |
| +} |
| + |
| +void AppListController::UpdateProfilePath(const FilePath& profile_file_path) { |
| + g_browser_process->local_state()->SetString( |
| + prefs::kAppListProfile, |
| + profile_file_path.BaseName().MaybeAsASCII()); |
| + ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| + Profile* profile = profile_manager->GetProfileByPath(profile_file_path); |
| + |
| + |
| + if (!profile) { |
| + LoadProfileAsync(profile_file_path); |
| + return; |
| + } |
| + |
| + ShowAppList(profile); |
| +} |
| + |
| +void AppListController::LoadProfileAsync(const FilePath& profile_file_path) { |
| + // Invalidate any pending profile path loads. |
| + profile_load_sequence_id_++; |
| + |
| + ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| + profile_manager->CreateProfileAsync( |
| + profile_file_path, |
| + base::Bind(&AppListController::OnProfileLoaded, |
| + base::Unretained(this), profile_load_sequence_id_), |
|
benwells
2013/01/18 06:18:46
Can we use a weak pointer instead?
koz (OOO until 15th September)
2013/01/20 23:32:00
Done.
|
| + string16(), string16(), false); |
| +} |
| + |
| +void AppListController::OnProfileLoaded(int profile_load_sequence_id, |
| + Profile* profile, |
| + Profile::CreateStatus status) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| + // A profile has been shown since last time, so we don't care about this |
| + // profile loading anymore. |
| + if (profile_load_sequence_id != profile_load_sequence_id_) |
| + return; |
| + |
| + if (status == Profile::CREATE_STATUS_INITIALIZED) |
| + ShowAppList(profile); |
| +} |
| + |
| +void AppListController::ShowAppList(Profile* profile) { |
| #if !defined(USE_AURA) |
|
benwells
2013/01/18 06:18:46
This #if is not needed (it is just needed when HWN
koz (OOO until 15th September)
2013/01/20 23:32:00
Done.
|
| + DCHECK(profile); |
| + |
| + // Invalidate any pending profile path loads. |
| + profile_load_sequence_id_++; |
| + |
| + // Do nothing if the app list is already displaying |profile|. |
| + if (app_list_is_showing_ && (profile == profile_)) |
| + return; |
| + |
| + DismissAppList(); |
| + profile_ = profile; |
| + PopulateViewFromProfile(); |
| + |
| + if (!app_list_is_showing_) { |
| + app_list_is_showing_ = true; |
| + browser::StartKeepAlive(); |
| + } |
| + ActivateAppList(); |
| +#endif |
| +} |
| + |
| +void AppListController::InitView(Profile* profile) { |
| if (current_view_) |
| return; |
| + profile_ = profile; |
| + PopulateViewFromProfile(); |
| +} |
| +void AppListController::UpdateFromProfile() { |
| + PopulateViewFromProfile(); |
| + if (app_list_is_showing_) |
| + ActivateAppList(); |
| +} |
| + |
| +void AppListController::PopulateViewFromProfile() { |
| +#if !defined(USE_AURA) |
| // The controller will be owned by the view delegate, and the delegate is |
| // owned by the app list view. The app list view manages it's own lifetime. |
| current_view_ = new app_list::AppListView( |
| - new AppListViewDelegate(new AppListControllerDelegateWin())); |
| + new AppListViewDelegate(new AppListControllerDelegateWin(), profile_)); |
| gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); |
| current_view_->InitAsBubble(GetDesktopWindow(), |
| &pagination_model_, |
| @@ -272,20 +385,12 @@ void AppListController::CreateAppList() { |
| #endif |
| } |
| -void AppListController::ShowAppList() { |
| -#if !defined(USE_AURA) |
| - if (!current_view_) |
| - CreateAppList(); |
| - |
| - if (app_list_is_showing_) |
| - return; |
| - app_list_is_showing_ = true; |
| - browser::StartKeepAlive(); |
| +void AppListController::ActivateAppList() { |
|
benwells
2013/01/18 06:18:46
If UpdateFromProfile is not needed, can this move
koz (OOO until 15th September)
2013/01/20 23:32:00
Done.
|
| + CHECK(current_view_ && app_list_is_showing_); |
| gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); |
| UpdateArrowPositionAndAnchorPoint(cursor); |
| current_view_->Show(); |
| current_view_->GetWidget()->Activate(); |
| -#endif |
| } |
| void AppListController::DismissAppList() { |
| @@ -556,18 +661,18 @@ void CheckAppListTaskbarShortcutOnFileThread(const FilePath& user_data_dir, |
| } |
| } |
| -void CreateAppList() { |
| - g_app_list_controller.Get().CreateAppList(); |
| +void InitView(Profile* profile) { |
| + g_app_list_controller.Get().InitView(profile); |
| } |
| } // namespace |
| namespace chrome { |
| -void InitAppList() { |
| - // Check that the presence of the app list shortcut matches the flag |
| - // kShowAppListShortcut. This will either create or delete a shortcut |
| - // file in the user data directory. |
| +void InitAppList(Profile* profile) { |
| + // Check that the app list shortcut matches the flag kShowAppListShortcut. |
| + // This will either create or delete a shortcut file in the user data |
| + // directory. |
| // TODO(benwells): Remove this and the flag once the app list installation |
| // is implemented. |
| static bool checked_shortcut = false; |
| @@ -586,13 +691,38 @@ void InitAppList() { |
| const int kInitWindowDelay = 5; |
| MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| - base::Bind(&CreateAppList), |
| + base::Bind(&InitView, profile), |
| base::TimeDelta::FromSeconds(kInitWindowDelay)); |
| } |
| -void ShowAppList() { |
| +void ShowAppList(Profile* profile) { |
| // Create the App list. |
| - g_app_list_controller.Get().ShowAppList(); |
| + g_app_list_controller.Get().ShowAppList(profile); |
| +} |
| + |
| +void UpdateProfilePath(const FilePath& profile_file_path) { |
| + g_app_list_controller.Get().UpdateProfilePath(profile_file_path); |
| +} |
| + |
| +FilePath GetAppListProfilePath(const FilePath& user_data_dir) { |
| + PrefService* local_state = g_browser_process->local_state(); |
| + DCHECK(local_state); |
| + |
| + std::string app_list_profile; |
| + if (local_state->HasPrefPath(prefs::kAppListProfile)) |
| + app_list_profile = local_state->GetString(prefs::kAppListProfile); |
| + |
| + // If the user has no profile preference for the app launcher, default to the |
| + // last browser profile used. |
| + if (app_list_profile.empty() && |
| + local_state->HasPrefPath(prefs::kProfileLastUsed)) |
| + app_list_profile = local_state->GetString(prefs::kProfileLastUsed); |
| + |
| + std::string profile_path = app_list_profile.empty() ? |
| + chrome::kInitialProfile : |
| + app_list_profile; |
| + |
| + return user_data_dir.AppendASCII(profile_path); |
| } |
| } // namespace chrome |