app_list_view_delegate.cc revision f2477e01787aa58f445919b809d89e252beef54f
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#include "chrome/browser/ui/app_list/app_list_view_delegate.h" 6 7#include <vector> 8 9#include "base/callback.h" 10#include "base/files/file_path.h" 11#include "base/stl_util.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/chrome_notification_types.h" 14#include "chrome/browser/extensions/extension_service.h" 15#include "chrome/browser/feedback/feedback_util.h" 16#include "chrome/browser/profiles/profile_info_cache.h" 17#include "chrome/browser/profiles/profile_manager.h" 18#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" 19#include "chrome/browser/ui/app_list/app_list_service.h" 20#include "chrome/browser/ui/app_list/app_list_syncable_service.h" 21#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" 22#include "chrome/browser/ui/app_list/search/search_controller.h" 23#include "chrome/browser/ui/app_list/start_page_service.h" 24#include "chrome/browser/ui/browser_finder.h" 25#include "chrome/browser/ui/chrome_pages.h" 26#include "chrome/browser/ui/host_desktop.h" 27#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 28#include "chrome/browser/ui/web_applications/web_app_ui.h" 29#include "chrome/browser/web_applications/web_app.h" 30#include "chrome/common/extensions/extension_constants.h" 31#include "chrome/common/url_constants.h" 32#include "content/public/browser/browser_thread.h" 33#include "content/public/browser/notification_service.h" 34#include "content/public/browser/notification_source.h" 35#include "content/public/browser/page_navigator.h" 36#include "content/public/browser/user_metrics.h" 37#include "ui/app_list/search_box_model.h" 38 39#if defined(USE_ASH) 40#include "chrome/browser/ui/ash/app_list/app_sync_ui_state_watcher.h" 41#endif 42 43#if defined(OS_WIN) 44#include "chrome/browser/web_applications/web_app_win.h" 45#endif 46 47namespace { 48 49#if defined(OS_WIN) 50void CreateShortcutInWebAppDir( 51 const base::FilePath& app_data_dir, 52 base::Callback<void(const base::FilePath&)> callback, 53 const ShellIntegration::ShortcutInfo& info) { 54 content::BrowserThread::PostTaskAndReplyWithResult( 55 content::BrowserThread::FILE, 56 FROM_HERE, 57 base::Bind(web_app::CreateShortcutInWebAppDir, app_data_dir, info), 58 callback); 59} 60#endif 61 62void PopulateUsers(const ProfileInfoCache& profile_info, 63 const base::FilePath& active_profile_path, 64 app_list::AppListViewDelegate::Users* users) { 65 users->clear(); 66 const size_t count = profile_info.GetNumberOfProfiles(); 67 for (size_t i = 0; i < count; ++i) { 68 // Don't display managed users. 69 if (profile_info.ProfileIsManagedAtIndex(i)) 70 continue; 71 72 app_list::AppListViewDelegate::User user; 73 user.name = profile_info.GetNameOfProfileAtIndex(i); 74 user.email = profile_info.GetUserNameOfProfileAtIndex(i); 75 user.profile_path = profile_info.GetPathOfProfileAtIndex(i); 76 user.active = active_profile_path == user.profile_path; 77 users->push_back(user); 78 } 79} 80 81} // namespace 82 83AppListViewDelegate::AppListViewDelegate(Profile* profile, 84 AppListControllerDelegate* controller) 85 : controller_(controller), 86 profile_(profile), 87 model_(NULL) { 88 CHECK(controller_); 89 RegisterForNotifications(); 90 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this); 91 OnProfileChanged(); // sets model_ 92 app_list::StartPageService* service = 93 app_list::StartPageService::Get(profile_); 94 if (service) 95 service->AddObserver(this); 96} 97 98AppListViewDelegate::~AppListViewDelegate() { 99 app_list::StartPageService* service = 100 app_list::StartPageService::Get(profile_); 101 if (service) 102 service->RemoveObserver(this); 103 g_browser_process-> 104 profile_manager()->GetProfileInfoCache().RemoveObserver(this); 105} 106 107void AppListViewDelegate::RegisterForNotifications() { 108 registrar_.RemoveAll(); 109 DCHECK(profile_); 110 111 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 112 content::NotificationService::AllSources()); 113 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED, 114 content::NotificationService::AllSources()); 115 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 116 content::NotificationService::AllSources()); 117} 118 119void AppListViewDelegate::OnProfileChanged() { 120 model_ = app_list::AppListSyncableServiceFactory::GetForProfile( 121 profile_)->model(); 122 123 search_controller_.reset(new app_list::SearchController( 124 profile_, model_->search_box(), model_->results(), controller_)); 125 126 signin_delegate_.SetProfile(profile_); 127 128#if defined(USE_ASH) 129 app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_)); 130#endif 131 132 model_->SetSignedIn(!GetSigninDelegate()->NeedSignin()); 133 134 // Don't populate the app list users if we are on the ash desktop. 135 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow( 136 controller_->GetAppListWindow()); 137 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH) 138 return; 139 140 // Populate the app list users. 141 PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(), 142 profile_->GetPath(), &users_); 143} 144 145bool AppListViewDelegate::ForceNativeDesktop() const { 146 return controller_->ForceNativeDesktop(); 147} 148 149void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) { 150 DCHECK(model_); 151 152 // The profile must be loaded before this is called. 153 profile_ = 154 g_browser_process->profile_manager()->GetProfileByPath(profile_path); 155 DCHECK(profile_); 156 157 RegisterForNotifications(); 158 159 OnProfileChanged(); 160 161 // Clear search query. 162 model_->search_box()->SetText(base::string16()); 163} 164 165app_list::AppListModel* AppListViewDelegate::GetModel() { 166 return model_; 167} 168 169app_list::SigninDelegate* AppListViewDelegate::GetSigninDelegate() { 170 return &signin_delegate_; 171} 172 173void AppListViewDelegate::GetShortcutPathForApp( 174 const std::string& app_id, 175 const base::Callback<void(const base::FilePath&)>& callback) { 176#if defined(OS_WIN) 177 ExtensionService* service = profile_->GetExtensionService(); 178 DCHECK(service); 179 const extensions::Extension* extension = 180 service->GetInstalledExtension(app_id); 181 if (!extension) { 182 callback.Run(base::FilePath()); 183 return; 184 } 185 186 base::FilePath app_data_dir( 187 web_app::GetWebAppDataDirectory(profile_->GetPath(), 188 extension->id(), 189 GURL())); 190 191 web_app::UpdateShortcutInfoAndIconForApp( 192 *extension, 193 profile_, 194 base::Bind(CreateShortcutInWebAppDir, app_data_dir, callback)); 195#else 196 callback.Run(base::FilePath()); 197#endif 198} 199 200void AppListViewDelegate::StartSearch() { 201 if (search_controller_) 202 search_controller_->Start(); 203} 204 205void AppListViewDelegate::StopSearch() { 206 if (search_controller_) 207 search_controller_->Stop(); 208} 209 210void AppListViewDelegate::OpenSearchResult( 211 app_list::SearchResult* result, 212 int event_flags) { 213 search_controller_->OpenResult(result, event_flags); 214} 215 216void AppListViewDelegate::InvokeSearchResultAction( 217 app_list::SearchResult* result, 218 int action_index, 219 int event_flags) { 220 search_controller_->InvokeResultAction(result, action_index, event_flags); 221} 222 223void AppListViewDelegate::Dismiss() { 224 controller_->DismissView(); 225} 226 227void AppListViewDelegate::ViewClosing() { 228 controller_->ViewClosing(); 229} 230 231gfx::ImageSkia AppListViewDelegate::GetWindowIcon() { 232 return controller_->GetWindowIcon(); 233} 234 235void AppListViewDelegate::OpenSettings() { 236 ExtensionService* service = profile_->GetExtensionService(); 237 DCHECK(service); 238 const extensions::Extension* extension = service->GetInstalledExtension( 239 extension_misc::kSettingsAppId); 240 DCHECK(extension); 241 controller_->ActivateApp(profile_, 242 extension, 243 AppListControllerDelegate::LAUNCH_FROM_UNKNOWN, 244 0); 245} 246 247void AppListViewDelegate::OpenHelp() { 248 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow( 249 controller_->GetAppListWindow()); 250 chrome::ScopedTabbedBrowserDisplayer displayer(profile_, desktop); 251 content::OpenURLParams params(GURL(chrome::kAppLauncherHelpURL), 252 content::Referrer(), 253 NEW_FOREGROUND_TAB, 254 content::PAGE_TRANSITION_LINK, 255 false); 256 displayer.browser()->OpenURL(params); 257} 258 259void AppListViewDelegate::OpenFeedback() { 260 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow( 261 controller_->GetAppListWindow()); 262 Browser* browser = chrome::FindTabbedBrowser(profile_, false, desktop); 263 chrome::ShowFeedbackPage(browser, std::string(), 264 chrome::kAppLauncherCategoryTag); 265} 266 267void AppListViewDelegate::ToggleSpeechRecognition() { 268 app_list::StartPageService* service = 269 app_list::StartPageService::Get(profile_); 270 if (service) 271 service->ToggleSpeechRecognition(); 272} 273 274void AppListViewDelegate::ShowForProfileByPath( 275 const base::FilePath& profile_path) { 276 controller_->ShowForProfileByPath(profile_path); 277} 278 279void AppListViewDelegate::OnSearch(const base::string16& query) { 280 model_->search_box()->SetText(query); 281} 282 283void AppListViewDelegate::OnSpeechRecognitionStateChanged(bool recognizing) { 284 model_->search_box()->SetSpeechRecognitionButtonState(recognizing); 285} 286 287void AppListViewDelegate::Observe( 288 int type, 289 const content::NotificationSource& source, 290 const content::NotificationDetails& details) { 291 OnProfileChanged(); 292} 293 294void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) { 295 OnProfileChanged(); 296} 297 298void AppListViewDelegate::OnProfileWasRemoved( 299 const base::FilePath& profile_path, const base::string16& profile_name) { 300 OnProfileChanged(); 301} 302 303void AppListViewDelegate::OnProfileNameChanged( 304 const base::FilePath& profile_path, 305 const base::string16& old_profile_name) { 306 OnProfileChanged(); 307} 308 309content::WebContents* AppListViewDelegate::GetStartPageContents() { 310 app_list::StartPageService* service = 311 app_list::StartPageService::Get(profile_); 312 if (!service) 313 return NULL; 314 315 return service->contents(); 316} 317 318const app_list::AppListViewDelegate::Users& 319AppListViewDelegate::GetUsers() const { 320 return users_; 321} 322