OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/app_list/start_page_handler.h" | 5 #include "chrome/browser/ui/webui/app_list/start_page_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "base/version.h" | 13 #include "base/version.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/search/hotword_service.h" | |
16 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" | 15 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" |
17 #include "chrome/browser/ui/app_list/app_list_service.h" | 16 #include "chrome/browser/ui/app_list/app_list_service.h" |
18 #include "chrome/browser/ui/app_list/start_page_service.h" | 17 #include "chrome/browser/ui/app_list/start_page_service.h" |
19 #include "chrome/browser/ui/host_desktop.h" | 18 #include "chrome/browser/ui/host_desktop.h" |
20 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 19 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" |
21 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
22 #include "components/update_client/update_query_params.h" | 21 #include "components/update_client/update_query_params.h" |
23 #include "content/public/browser/web_ui.h" | 22 #include "content/public/browser/web_ui.h" |
24 #include "extensions/browser/extension_registry.h" | 23 #include "extensions/browser/extension_registry.h" |
25 #include "extensions/browser/extension_system.h" | 24 #include "extensions/browser/extension_system.h" |
26 #include "extensions/common/constants.h" | 25 #include "extensions/common/constants.h" |
27 #include "extensions/common/extension.h" | 26 #include "extensions/common/extension.h" |
28 #include "extensions/common/extension_icon_set.h" | 27 #include "extensions/common/extension_icon_set.h" |
29 #include "ui/app_list/app_list_switches.h" | 28 #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" | 29 #include "ui/events/event_constants.h" |
32 | 30 |
33 namespace app_list { | 31 namespace app_list { |
34 | 32 |
35 namespace { | 33 namespace { |
36 | 34 |
37 const char kAppListDoodleActionHistogram[] = "Apps.AppListDoodleAction"; | 35 const char kAppListDoodleActionHistogram[] = "Apps.AppListDoodleAction"; |
38 | 36 |
39 // Interactions a user has with the app list doodle. This enum must not have its | 37 // Interactions a user has with the app list doodle. This enum must not have its |
40 // order altered as it is used in histograms. | 38 // order altered as it is used in histograms. |
41 enum DoodleAction { | 39 enum DoodleAction { |
42 DOODLE_SHOWN = 0, | 40 DOODLE_SHOWN = 0, |
43 DOODLE_CLICKED, | 41 DOODLE_CLICKED, |
44 // Add values here. | 42 // Add values here. |
45 | 43 |
46 DOODLE_ACTION_LAST, | 44 DOODLE_ACTION_LAST, |
47 }; | 45 }; |
48 | 46 |
49 #if defined(OS_CHROMEOS) | |
50 const char kOldHotwordExtensionVersionString[] = "0.1.1.5023"; | |
51 #endif | |
52 | |
53 } // namespace | 47 } // namespace |
54 | 48 |
55 StartPageHandler::StartPageHandler() : extension_registry_observer_(this) { | 49 StartPageHandler::StartPageHandler() { |
56 } | 50 } |
57 | 51 |
58 StartPageHandler::~StartPageHandler() { | 52 StartPageHandler::~StartPageHandler() { |
59 } | 53 } |
60 | 54 |
61 void StartPageHandler::RegisterMessages() { | 55 void StartPageHandler::RegisterMessages() { |
62 web_ui()->RegisterMessageCallback( | 56 web_ui()->RegisterMessageCallback( |
63 "appListShown", base::Bind(&StartPageHandler::HandleAppListShown, | 57 "appListShown", base::Bind(&StartPageHandler::HandleAppListShown, |
64 base::Unretained(this))); | 58 base::Unretained(this))); |
65 web_ui()->RegisterMessageCallback( | 59 web_ui()->RegisterMessageCallback( |
66 "doodleClicked", base::Bind(&StartPageHandler::HandleDoodleClicked, | 60 "doodleClicked", base::Bind(&StartPageHandler::HandleDoodleClicked, |
67 base::Unretained(this))); | 61 base::Unretained(this))); |
68 web_ui()->RegisterMessageCallback( | 62 web_ui()->RegisterMessageCallback( |
69 "initialize", | 63 "initialize", |
70 base::Bind(&StartPageHandler::HandleInitialize, base::Unretained(this))); | 64 base::Bind(&StartPageHandler::HandleInitialize, base::Unretained(this))); |
71 web_ui()->RegisterMessageCallback( | 65 web_ui()->RegisterMessageCallback( |
72 "launchApp", | 66 "launchApp", |
73 base::Bind(&StartPageHandler::HandleLaunchApp, base::Unretained(this))); | 67 base::Bind(&StartPageHandler::HandleLaunchApp, base::Unretained(this))); |
74 web_ui()->RegisterMessageCallback( | |
75 "speechResult", | |
76 base::Bind(&StartPageHandler::HandleSpeechResult, | |
77 base::Unretained(this))); | |
78 web_ui()->RegisterMessageCallback( | |
79 "speechSoundLevel", | |
80 base::Bind(&StartPageHandler::HandleSpeechSoundLevel, | |
81 base::Unretained(this))); | |
82 web_ui()->RegisterMessageCallback( | |
83 "setSpeechRecognitionState", | |
84 base::Bind(&StartPageHandler::HandleSpeechRecognition, | |
85 base::Unretained(this))); | |
86 } | 68 } |
87 | 69 |
88 void StartPageHandler::OnExtensionLoaded( | |
89 content::BrowserContext* browser_context, | |
90 const extensions::Extension* extension) { | |
91 #if defined(OS_CHROMEOS) | |
92 DCHECK_EQ(Profile::FromWebUI(web_ui()), | |
93 Profile::FromBrowserContext(browser_context)); | |
94 if (extension->id() == extension_misc::kHotwordExtensionId) | |
95 OnHotwordEnabledChanged(); | |
96 #endif | |
97 } | |
98 | |
99 void StartPageHandler::OnExtensionUnloaded( | |
100 content::BrowserContext* browser_context, | |
101 const extensions::Extension* extension, | |
102 extensions::UnloadedExtensionInfo::Reason reason) { | |
103 #if defined(OS_CHROMEOS) | |
104 DCHECK_EQ(Profile::FromWebUI(web_ui()), | |
105 Profile::FromBrowserContext(browser_context)); | |
106 if (extension->id() == extension_misc::kHotwordExtensionId) | |
107 OnHotwordEnabledChanged(); | |
108 #endif | |
109 } | |
110 | |
111 #if defined(OS_CHROMEOS) | |
112 void StartPageHandler::OnHotwordEnabledChanged() { | |
113 // If the hotword extension is new enough, we should use the new | |
114 // hotwordPrivate API to provide the feature. | |
115 // TODO(mukai): remove this after everything gets stable. | |
116 Profile* profile = Profile::FromWebUI(web_ui()); | |
117 | |
118 extensions::ExtensionRegistry* registry = | |
119 extensions::ExtensionRegistry::Get(profile); | |
120 const extensions::Extension* hotword_extension = | |
121 registry->GetExtensionById(extension_misc::kHotwordExtensionId, | |
122 extensions::ExtensionRegistry::ENABLED); | |
123 if (hotword_extension && | |
124 hotword_extension->version()->CompareTo( | |
125 base::Version(kOldHotwordExtensionVersionString)) <= 0 && | |
126 !HotwordService::IsExperimentalHotwordingEnabled()) { | |
127 StartPageService* service = StartPageService::Get(profile); | |
128 web_ui()->CallJavascriptFunction( | |
129 "appList.startPage.setHotwordEnabled", | |
130 base::FundamentalValue(service && service->HotwordEnabled())); | |
131 } | |
132 } | |
133 #endif | |
134 | |
135 void StartPageHandler::HandleAppListShown(const base::ListValue* args) { | 70 void StartPageHandler::HandleAppListShown(const base::ListValue* args) { |
136 bool doodle_shown = false; | 71 bool doodle_shown = false; |
137 if (args->GetBoolean(0, &doodle_shown) && doodle_shown) { | 72 if (args->GetBoolean(0, &doodle_shown) && doodle_shown) { |
138 UMA_HISTOGRAM_ENUMERATION(kAppListDoodleActionHistogram, DOODLE_SHOWN, | 73 UMA_HISTOGRAM_ENUMERATION(kAppListDoodleActionHistogram, DOODLE_SHOWN, |
139 DOODLE_ACTION_LAST); | 74 DOODLE_ACTION_LAST); |
140 } | 75 } |
141 } | 76 } |
142 | 77 |
143 void StartPageHandler::HandleDoodleClicked(const base::ListValue* args) { | 78 void StartPageHandler::HandleDoodleClicked(const base::ListValue* args) { |
144 UMA_HISTOGRAM_ENUMERATION(kAppListDoodleActionHistogram, DOODLE_CLICKED, | 79 UMA_HISTOGRAM_ENUMERATION(kAppListDoodleActionHistogram, DOODLE_CLICKED, |
145 DOODLE_ACTION_LAST); | 80 DOODLE_ACTION_LAST); |
146 } | 81 } |
147 | 82 |
148 void StartPageHandler::HandleInitialize(const base::ListValue* args) { | 83 void StartPageHandler::HandleInitialize(const base::ListValue* args) { |
149 Profile* profile = Profile::FromWebUI(web_ui()); | 84 Profile* profile = Profile::FromWebUI(web_ui()); |
150 StartPageService* service = StartPageService::Get(profile); | 85 StartPageService* service = StartPageService::Get(profile); |
151 if (!service) | 86 if (!service) |
152 return; | 87 return; |
153 | 88 |
154 service->WebUILoaded(); | 89 service->WebUILoaded(); |
155 | |
156 #if defined(OS_CHROMEOS) | |
157 if (app_list::switches::IsVoiceSearchEnabled() && | |
158 HotwordService::DoesHotwordSupportLanguage(profile)) { | |
159 OnHotwordEnabledChanged(); | |
160 pref_change_registrar_.Init(profile->GetPrefs()); | |
161 pref_change_registrar_.RemoveAll(); | |
162 pref_change_registrar_.Add( | |
163 prefs::kHotwordSearchEnabled, | |
164 base::Bind(&StartPageHandler::OnHotwordEnabledChanged, | |
165 base::Unretained(this))); | |
166 | |
167 extension_registry_observer_.RemoveAll(); | |
168 extension_registry_observer_.Add( | |
169 extensions::ExtensionRegistry::Get(profile)); | |
170 } | |
171 | |
172 extensions::ExtensionRegistry* registry = | |
173 extensions::ExtensionRegistry::Get(profile); | |
174 const extensions::Extension* hotword_extension = | |
175 registry->GetExtensionById(extension_misc::kHotwordExtensionId, | |
176 extensions::ExtensionRegistry::ENABLED); | |
177 if (hotword_extension && | |
178 hotword_extension->version()->CompareTo( | |
179 base::Version(kOldHotwordExtensionVersionString)) <= 0) { | |
180 web_ui()->CallJavascriptFunction( | |
181 "appList.startPage.setNaclArch", | |
182 base::StringValue(update_client::UpdateQueryParams::GetNaclArch())); | |
183 } | |
184 #endif | |
185 | |
186 // If v2 hotwording is enabled, don't tell the start page that the app list is | |
187 // being shown. V2 hotwording doesn't use the start page for anything. | |
188 if (!app_list::switches::IsExperimentalAppListEnabled() && | |
189 !HotwordService::IsExperimentalHotwordingEnabled()) { | |
190 web_ui()->CallJavascriptFunction( | |
191 "appList.startPage.onAppListShown", | |
192 base::FundamentalValue(service->HotwordEnabled())); | |
193 } | |
194 } | 90 } |
195 | 91 |
196 void StartPageHandler::HandleLaunchApp(const base::ListValue* args) { | 92 void StartPageHandler::HandleLaunchApp(const base::ListValue* args) { |
197 std::string app_id; | 93 std::string app_id; |
198 CHECK(args->GetString(0, &app_id)); | 94 CHECK(args->GetString(0, &app_id)); |
199 | 95 |
200 Profile* profile = Profile::FromWebUI(web_ui()); | 96 Profile* profile = Profile::FromWebUI(web_ui()); |
201 const extensions::Extension* app = | 97 const extensions::Extension* app = |
202 extensions::ExtensionRegistry::Get(profile) | 98 extensions::ExtensionRegistry::Get(profile) |
203 ->GetExtensionById(app_id, extensions::ExtensionRegistry::EVERYTHING); | 99 ->GetExtensionById(app_id, extensions::ExtensionRegistry::EVERYTHING); |
204 if (!app) { | 100 if (!app) { |
205 NOTREACHED(); | 101 NOTREACHED(); |
206 return; | 102 return; |
207 } | 103 } |
208 | 104 |
209 AppListControllerDelegate* controller = AppListService::Get( | 105 AppListControllerDelegate* controller = AppListService::Get( |
210 chrome::GetHostDesktopTypeForNativeView( | 106 chrome::GetHostDesktopTypeForNativeView( |
211 web_ui()->GetWebContents()->GetNativeView()))-> | 107 web_ui()->GetWebContents()->GetNativeView()))-> |
212 GetControllerDelegate(); | 108 GetControllerDelegate(); |
213 controller->ActivateApp(profile, | 109 controller->ActivateApp(profile, |
214 app, | 110 app, |
215 AppListControllerDelegate::LAUNCH_FROM_APP_LIST, | 111 AppListControllerDelegate::LAUNCH_FROM_APP_LIST, |
216 ui::EF_NONE); | 112 ui::EF_NONE); |
217 } | 113 } |
218 | 114 |
219 void StartPageHandler::HandleSpeechResult(const base::ListValue* args) { | |
220 base::string16 query; | |
221 bool is_final = false; | |
222 CHECK(args->GetString(0, &query)); | |
223 CHECK(args->GetBoolean(1, &is_final)); | |
224 | |
225 StartPageService::Get(Profile::FromWebUI(web_ui()))->OnSpeechResult( | |
226 query, is_final); | |
227 } | |
228 | |
229 void StartPageHandler::HandleSpeechSoundLevel(const base::ListValue* args) { | |
230 double level; | |
231 CHECK(args->GetDouble(0, &level)); | |
232 | |
233 StartPageService* service = | |
234 StartPageService::Get(Profile::FromWebUI(web_ui())); | |
235 if (service) | |
236 service->OnSpeechSoundLevelChanged(static_cast<int16>(level)); | |
237 } | |
238 | |
239 void StartPageHandler::HandleSpeechRecognition(const base::ListValue* args) { | |
240 std::string state_string; | |
241 CHECK(args->GetString(0, &state_string)); | |
242 | |
243 SpeechRecognitionState new_state = SPEECH_RECOGNITION_OFF; | |
244 if (state_string == "READY") | |
245 new_state = SPEECH_RECOGNITION_READY; | |
246 else if (state_string == "HOTWORD_RECOGNIZING") | |
247 new_state = SPEECH_RECOGNITION_HOTWORD_LISTENING; | |
248 else if (state_string == "RECOGNIZING") | |
249 new_state = SPEECH_RECOGNITION_RECOGNIZING; | |
250 else if (state_string == "IN_SPEECH") | |
251 new_state = SPEECH_RECOGNITION_IN_SPEECH; | |
252 else if (state_string == "STOPPING") | |
253 new_state = SPEECH_RECOGNITION_STOPPING; | |
254 else if (state_string == "NETWORK_ERROR") | |
255 new_state = SPEECH_RECOGNITION_NETWORK_ERROR; | |
256 | |
257 StartPageService* service = | |
258 StartPageService::Get(Profile::FromWebUI(web_ui())); | |
259 if (service) | |
260 service->OnSpeechRecognitionStateChanged(new_state); | |
261 } | |
262 | |
263 } // namespace app_list | 115 } // namespace app_list |
OLD | NEW |