start_page_handler.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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#include "chrome/browser/ui/webui/app_list/start_page_handler.h" 6 7#include <string> 8 9#include "base/bind.h" 10#include "base/memory/scoped_ptr.h" 11#include "base/prefs/pref_service.h" 12#include "base/sys_info.h" 13#include "base/values.h" 14#include "chrome/browser/extensions/extension_service.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/browser/search/hotword_service.h" 17#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" 18#include "chrome/browser/ui/app_list/app_list_service.h" 19#include "chrome/browser/ui/app_list/recommended_apps.h" 20#include "chrome/browser/ui/app_list/start_page_service.h" 21#include "chrome/browser/ui/host_desktop.h" 22#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 23#include "chrome/common/extensions/extension_icon_set.h" 24#include "chrome/common/pref_names.h" 25#include "content/public/browser/web_contents_view.h" 26#include "content/public/browser/web_ui.h" 27#include "extensions/browser/extension_system.h" 28#include "extensions/common/extension.h" 29#include "ui/app_list/app_list_switches.h" 30#include "ui/app_list/speech_ui_model_observer.h" 31#include "ui/events/event_constants.h" 32 33namespace app_list { 34 35namespace { 36 37scoped_ptr<base::DictionaryValue> CreateAppInfo( 38 const extensions::Extension* app) { 39 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); 40 dict->SetString("appId", app->id()); 41 dict->SetString("textTitle", app->short_name()); 42 dict->SetString("title", app->name()); 43 44 const bool grayscale = false; 45 bool icon_exists = true; 46 GURL icon_url = extensions::ExtensionIconSource::GetIconURL( 47 app, 48 extension_misc::EXTENSION_ICON_MEDIUM, 49 ExtensionIconSet::MATCH_BIGGER, 50 grayscale, 51 &icon_exists); 52 dict->SetString("iconUrl", icon_url.spec()); 53 54 return dict.Pass(); 55} 56 57} // namespace 58 59StartPageHandler::StartPageHandler() : recommended_apps_(NULL) {} 60 61StartPageHandler::~StartPageHandler() { 62 if (recommended_apps_) 63 recommended_apps_->RemoveObserver(this); 64} 65 66void StartPageHandler::RegisterMessages() { 67 web_ui()->RegisterMessageCallback( 68 "initialize", 69 base::Bind(&StartPageHandler::HandleInitialize, base::Unretained(this))); 70 web_ui()->RegisterMessageCallback( 71 "launchApp", 72 base::Bind(&StartPageHandler::HandleLaunchApp, base::Unretained(this))); 73 web_ui()->RegisterMessageCallback( 74 "speechResult", 75 base::Bind(&StartPageHandler::HandleSpeechResult, 76 base::Unretained(this))); 77 web_ui()->RegisterMessageCallback( 78 "speechSoundLevel", 79 base::Bind(&StartPageHandler::HandleSpeechSoundLevel, 80 base::Unretained(this))); 81 web_ui()->RegisterMessageCallback( 82 "setSpeechRecognitionState", 83 base::Bind(&StartPageHandler::HandleSpeechRecognition, 84 base::Unretained(this))); 85} 86 87void StartPageHandler::OnRecommendedAppsChanged() { 88 SendRecommendedApps(); 89} 90 91void StartPageHandler::SendRecommendedApps() { 92 const RecommendedApps::Apps& recommends = recommended_apps_->apps(); 93 94 base::ListValue recommended_list; 95 for (size_t i = 0; i < recommends.size(); ++i) { 96 recommended_list.Append(CreateAppInfo(recommends[i].get()).release()); 97 } 98 99 web_ui()->CallJavascriptFunction("appList.startPage.setRecommendedApps", 100 recommended_list); 101} 102 103#if defined(OS_CHROMEOS) 104bool StartPageHandler::HotwordEnabled() { 105 Profile* profile = Profile::FromWebUI(web_ui()); 106 return HotwordService::DoesHotwordSupportLanguage(profile) && 107 profile->GetPrefs()->GetBoolean(prefs::kHotwordAppListEnabled); 108} 109 110void StartPageHandler::OnHotwordEnabledChanged() { 111 web_ui()->CallJavascriptFunction( 112 "appList.startPage.setHotwordEnabled", 113 base::FundamentalValue(HotwordEnabled())); 114} 115 116void StartPageHandler::SynchronizeHotwordEnabled() { 117 Profile* profile = Profile::FromWebUI(web_ui()); 118 PrefService* pref_service = profile->GetPrefs(); 119 const PrefService::Preference* pref = 120 pref_service->FindPreference(prefs::kHotwordSearchEnabled); 121 if (!pref || pref->IsDefaultValue()) 122 return; 123 124 bool search_enabled = false; 125 if (!pref->GetValue()->GetAsBoolean(&search_enabled)) 126 return; 127 128 if (pref_service->GetBoolean(prefs::kHotwordAppListEnabled) != search_enabled) 129 pref_service->SetBoolean(prefs::kHotwordAppListEnabled, search_enabled); 130} 131#endif 132 133void StartPageHandler::HandleInitialize(const base::ListValue* args) { 134 Profile* profile = Profile::FromWebUI(web_ui()); 135 StartPageService* service = StartPageService::Get(profile); 136 if (!service) 137 return; 138 139 recommended_apps_ = service->recommended_apps(); 140 recommended_apps_->AddObserver(this); 141 142 SendRecommendedApps(); 143 144#if defined(OS_CHROMEOS) 145 if (app_list::switches::IsVoiceSearchEnabled() && 146 HotwordService::DoesHotwordSupportLanguage(profile) && 147 base::SysInfo::IsRunningOnChromeOS()) { 148 SynchronizeHotwordEnabled(); 149 OnHotwordEnabledChanged(); 150 pref_change_registrar_.Init(profile->GetPrefs()); 151 pref_change_registrar_.Add( 152 prefs::kHotwordSearchEnabled, 153 base::Bind(&StartPageHandler::SynchronizeHotwordEnabled, 154 base::Unretained(this))); 155 pref_change_registrar_.Add( 156 prefs::kHotwordAppListEnabled, 157 base::Bind(&StartPageHandler::OnHotwordEnabledChanged, 158 base::Unretained(this))); 159 } 160#endif 161} 162 163void StartPageHandler::HandleLaunchApp(const base::ListValue* args) { 164 std::string app_id; 165 CHECK(args->GetString(0, &app_id)); 166 167 Profile* profile = Profile::FromWebUI(web_ui()); 168 ExtensionService* service = 169 extensions::ExtensionSystem::Get(profile)->extension_service(); 170 const extensions::Extension* app = service->GetInstalledExtension(app_id); 171 if (!app) { 172 NOTREACHED(); 173 return; 174 } 175 176 AppListControllerDelegate* controller = AppListService::Get( 177 chrome::GetHostDesktopTypeForNativeView( 178 web_ui()->GetWebContents()->GetView()->GetNativeView())) 179 ->GetControllerDelegate(); 180 controller->ActivateApp(profile, 181 app, 182 AppListControllerDelegate::LAUNCH_FROM_APP_LIST, 183 ui::EF_NONE); 184} 185 186void StartPageHandler::HandleSpeechResult(const base::ListValue* args) { 187 base::string16 query; 188 bool is_final = false; 189 CHECK(args->GetString(0, &query)); 190 CHECK(args->GetBoolean(1, &is_final)); 191 192 StartPageService::Get(Profile::FromWebUI(web_ui()))->OnSpeechResult( 193 query, is_final); 194} 195 196void StartPageHandler::HandleSpeechSoundLevel(const base::ListValue* args) { 197 double level; 198 CHECK(args->GetDouble(0, &level)); 199 200 StartPageService* service = 201 StartPageService::Get(Profile::FromWebUI(web_ui())); 202 if (service) 203 service->OnSpeechSoundLevelChanged(static_cast<int16>(level)); 204} 205 206void StartPageHandler::HandleSpeechRecognition(const base::ListValue* args) { 207 std::string state_string; 208 CHECK(args->GetString(0, &state_string)); 209 210 SpeechRecognitionState new_state = SPEECH_RECOGNITION_OFF; 211 if (state_string == "READY") 212 new_state = SPEECH_RECOGNITION_READY; 213 else if (state_string == "HOTWORD_RECOGNIZING") 214 new_state = SPEECH_RECOGNITION_HOTWORD_LISTENING; 215 else if (state_string == "RECOGNIZING") 216 new_state = SPEECH_RECOGNITION_RECOGNIZING; 217 else if (state_string == "IN_SPEECH") 218 new_state = SPEECH_RECOGNITION_IN_SPEECH; 219 else if (state_string == "STOPPING") 220 new_state = SPEECH_RECOGNITION_STOPPING; 221 222 StartPageService* service = 223 StartPageService::Get(Profile::FromWebUI(web_ui())); 224 if (service) 225 service->OnSpeechRecognitionStateChanged(new_state); 226} 227 228} // namespace app_list 229