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/app_list/start_page_service.h" | 5 #include "chrome/browser/ui/app_list/start_page_service.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/bind.h" |
9 #include "base/command_line.h" | 10 #include "base/command_line.h" |
10 #include "base/memory/singleton.h" | 11 #include "base/memory/singleton.h" |
11 #include "base/metrics/user_metrics.h" | 12 #include "base/metrics/user_metrics.h" |
12 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
13 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
14 #include "chrome/browser/media/media_stream_infobar_delegate.h" | 15 #include "chrome/browser/media/media_stream_infobar_delegate.h" |
15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/search/hotword_service.h" | 17 #include "chrome/browser/search/hotword_service.h" |
17 #include "chrome/browser/search/hotword_service_factory.h" | 18 #include "chrome/browser/search/hotword_service_factory.h" |
18 #include "chrome/browser/ui/app_list/recommended_apps.h" | 19 #include "chrome/browser/ui/app_list/recommended_apps.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 StartPageService* StartPageService::Get(Profile* profile) { | 105 StartPageService* StartPageService::Get(Profile* profile) { |
105 return StartPageServiceFactory::GetForProfile(profile); | 106 return StartPageServiceFactory::GetForProfile(profile); |
106 } | 107 } |
107 | 108 |
108 StartPageService::StartPageService(Profile* profile) | 109 StartPageService::StartPageService(Profile* profile) |
109 : profile_(profile), | 110 : profile_(profile), |
110 profile_destroy_observer_(new ProfileDestroyObserver(this)), | 111 profile_destroy_observer_(new ProfileDestroyObserver(this)), |
111 recommended_apps_(new RecommendedApps(profile)), | 112 recommended_apps_(new RecommendedApps(profile)), |
112 state_(app_list::SPEECH_RECOGNITION_OFF), | 113 state_(app_list::SPEECH_RECOGNITION_OFF), |
113 speech_button_toggled_manually_(false), | 114 speech_button_toggled_manually_(false), |
114 speech_result_obtained_(false) { | 115 speech_result_obtained_(false), |
| 116 webui_finished_loading_(false) { |
115 // If experimental hotwording is enabled, then we're always "ready". | 117 // If experimental hotwording is enabled, then we're always "ready". |
116 // Transitioning into the "hotword recognizing" state is handled by the | 118 // Transitioning into the "hotword recognizing" state is handled by the |
117 // hotword extension. | 119 // hotword extension. |
118 if (HotwordService::IsExperimentalHotwordingEnabled()) | 120 if (HotwordService::IsExperimentalHotwordingEnabled()) |
119 state_ = app_list::SPEECH_RECOGNITION_READY; | 121 state_ = app_list::SPEECH_RECOGNITION_READY; |
120 | 122 |
121 if (app_list::switches::IsExperimentalAppListEnabled()) | 123 if (app_list::switches::IsExperimentalAppListEnabled()) |
122 LoadContents(); | 124 LoadContents(); |
123 } | 125 } |
124 | 126 |
(...skipping 22 matching lines...) Expand all Loading... |
147 } | 149 } |
148 | 150 |
149 void StartPageService::AppListHidden() { | 151 void StartPageService::AppListHidden() { |
150 contents_->GetWebUI()->CallJavascriptFunction( | 152 contents_->GetWebUI()->CallJavascriptFunction( |
151 "appList.startPage.onAppListHidden"); | 153 "appList.startPage.onAppListHidden"); |
152 if (!app_list::switches::IsExperimentalAppListEnabled()) | 154 if (!app_list::switches::IsExperimentalAppListEnabled()) |
153 UnloadContents(); | 155 UnloadContents(); |
154 } | 156 } |
155 | 157 |
156 void StartPageService::ToggleSpeechRecognition() { | 158 void StartPageService::ToggleSpeechRecognition() { |
| 159 DCHECK(contents_); |
157 speech_button_toggled_manually_ = true; | 160 speech_button_toggled_manually_ = true; |
158 contents_->GetWebUI()->CallJavascriptFunction( | 161 if (webui_finished_loading_) { |
159 "appList.startPage.toggleSpeechRecognition"); | 162 contents_->GetWebUI()->CallJavascriptFunction( |
| 163 "appList.startPage.toggleSpeechRecognition"); |
| 164 } else { |
| 165 pending_webui_callbacks_.push_back( |
| 166 base::Bind(&StartPageService::ToggleSpeechRecognition, |
| 167 base::Unretained(this))); |
| 168 } |
160 } | 169 } |
161 | 170 |
162 bool StartPageService::HotwordEnabled() { | 171 bool StartPageService::HotwordEnabled() { |
163 if (HotwordService::IsExperimentalHotwordingEnabled()) { | 172 if (HotwordService::IsExperimentalHotwordingEnabled()) { |
164 return HotwordServiceFactory::IsServiceAvailable(profile_) && | 173 return HotwordServiceFactory::IsServiceAvailable(profile_) && |
165 profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled); | 174 profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled); |
166 } | 175 } |
167 #if defined(OS_CHROMEOS) | 176 #if defined(OS_CHROMEOS) |
168 return HotwordServiceFactory::IsServiceAvailable(profile_) && | 177 return HotwordServiceFactory::IsServiceAvailable(profile_) && |
169 profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled); | 178 profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 state_ = new_state; | 230 state_ = new_state; |
222 FOR_EACH_OBSERVER(StartPageObserver, | 231 FOR_EACH_OBSERVER(StartPageObserver, |
223 observers_, | 232 observers_, |
224 OnSpeechRecognitionStateChanged(new_state)); | 233 OnSpeechRecognitionStateChanged(new_state)); |
225 } | 234 } |
226 | 235 |
227 void StartPageService::Shutdown() { | 236 void StartPageService::Shutdown() { |
228 UnloadContents(); | 237 UnloadContents(); |
229 } | 238 } |
230 | 239 |
| 240 void StartPageService::WebUILoaded() { |
| 241 // There's a race condition between the WebUI loading, and calling its JS |
| 242 // functions. Specifically, calling LoadContents() doesn't mean that the page |
| 243 // has loaded, but several code paths make this assumption. This function |
| 244 // allows us to defer calling JS functions until after the page has finished |
| 245 // loading. |
| 246 webui_finished_loading_ = true; |
| 247 for (const auto& cb : pending_webui_callbacks_) |
| 248 cb.Run(); |
| 249 pending_webui_callbacks_.clear(); |
| 250 } |
| 251 |
231 void StartPageService::LoadContents() { | 252 void StartPageService::LoadContents() { |
232 contents_.reset(content::WebContents::Create( | 253 contents_.reset(content::WebContents::Create( |
233 content::WebContents::CreateParams(profile_))); | 254 content::WebContents::CreateParams(profile_))); |
234 contents_delegate_.reset(new StartPageWebContentsDelegate()); | 255 contents_delegate_.reset(new StartPageWebContentsDelegate()); |
235 contents_->SetDelegate(contents_delegate_.get()); | 256 contents_->SetDelegate(contents_delegate_.get()); |
236 | 257 |
237 GURL url(chrome::kChromeUIAppListStartPageURL); | 258 GURL url(chrome::kChromeUIAppListStartPageURL); |
238 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 259 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
239 if (command_line->HasSwitch(::switches::kAppListStartPageURL)) { | 260 if (command_line->HasSwitch(::switches::kAppListStartPageURL)) { |
240 url = GURL( | 261 url = GURL( |
241 command_line->GetSwitchValueASCII(::switches::kAppListStartPageURL)); | 262 command_line->GetSwitchValueASCII(::switches::kAppListStartPageURL)); |
242 } | 263 } |
243 | 264 |
244 contents_->GetController().LoadURL( | 265 contents_->GetController().LoadURL( |
245 url, | 266 url, |
246 content::Referrer(), | 267 content::Referrer(), |
247 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, | 268 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, |
248 std::string()); | 269 std::string()); |
249 } | 270 } |
250 | 271 |
251 void StartPageService::UnloadContents() { | 272 void StartPageService::UnloadContents() { |
252 contents_.reset(); | 273 contents_.reset(); |
| 274 webui_finished_loading_ = false; |
253 } | 275 } |
254 | 276 |
255 } // namespace app_list | 277 } // namespace app_list |
OLD | NEW |