NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / app_list / start_page_service.cc
blob0f6c70a843d9ef03845b65cb327ff826ff5f70b2
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.
5 #include "chrome/browser/ui/app_list/start_page_service.h"
7 #include <string>
9 #include "base/command_line.h"
10 #include "base/memory/singleton.h"
11 #include "base/metrics/user_metrics.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/media/media_stream_infobar_delegate.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/app_list/recommended_apps.h"
16 #include "chrome/browser/ui/app_list/start_page_observer.h"
17 #include "chrome/browser/ui/app_list/start_page_service_factory.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/url_constants.h"
20 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_registrar.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/notification_source.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/browser/web_contents_delegate.h"
27 #include "extensions/browser/extension_system_provider.h"
28 #include "extensions/browser/extensions_browser_client.h"
29 #include "extensions/common/extension.h"
30 #include "ui/app_list/app_list_switches.h"
32 using base::RecordAction;
33 using base::UserMetricsAction;
35 namespace app_list {
37 namespace {
39 bool InSpeechRecognition(SpeechRecognitionState state) {
40 return state == SPEECH_RECOGNITION_RECOGNIZING ||
41 state == SPEECH_RECOGNITION_IN_SPEECH;
46 class StartPageService::ProfileDestroyObserver
47 : public content::NotificationObserver {
48 public:
49 explicit ProfileDestroyObserver(StartPageService* service)
50 : service_(service) {
51 registrar_.Add(this,
52 chrome::NOTIFICATION_PROFILE_DESTROYED,
53 content::Source<Profile>(service_->profile()));
55 virtual ~ProfileDestroyObserver() {}
57 private:
58 // content::NotificationObserver
59 virtual void Observe(int type,
60 const content::NotificationSource& source,
61 const content::NotificationDetails& details) OVERRIDE {
62 DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type);
63 DCHECK_EQ(service_->profile(), content::Source<Profile>(source).ptr());
64 service_->Shutdown();
67 StartPageService* service_; // Owner of this class.
68 content::NotificationRegistrar registrar_;
70 DISALLOW_COPY_AND_ASSIGN(ProfileDestroyObserver);
73 class StartPageService::StartPageWebContentsDelegate
74 : public content::WebContentsDelegate {
75 public:
76 StartPageWebContentsDelegate() {}
77 virtual ~StartPageWebContentsDelegate() {}
79 virtual void RequestMediaAccessPermission(
80 content::WebContents* web_contents,
81 const content::MediaStreamRequest& request,
82 const content::MediaResponseCallback& callback) OVERRIDE {
83 if (MediaStreamInfoBarDelegate::Create(web_contents, request, callback))
84 NOTREACHED() << "Media stream not allowed for WebUI";
87 private:
88 DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate);
91 // static
92 StartPageService* StartPageService::Get(Profile* profile) {
93 return StartPageServiceFactory::GetForProfile(profile);
96 StartPageService::StartPageService(Profile* profile)
97 : profile_(profile),
98 profile_destroy_observer_(new ProfileDestroyObserver(this)),
99 recommended_apps_(new RecommendedApps(profile)),
100 state_(app_list::SPEECH_RECOGNITION_OFF),
101 speech_button_toggled_manually_(false),
102 speech_result_obtained_(false) {
103 #if defined(OS_CHROMEOS)
104 // Updates the default state to hotword listening, because this is
105 // the default behavior. This will be updated when the page is loaded and
106 // the nacl module is loaded.
107 if (app_list::switches::IsVoiceSearchEnabled())
108 state_ = app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING;
109 #endif
111 contents_.reset(content::WebContents::Create(
112 content::WebContents::CreateParams(profile_)));
113 contents_delegate_.reset(new StartPageWebContentsDelegate());
114 contents_->SetDelegate(contents_delegate_.get());
116 GURL url(chrome::kChromeUIAppListStartPageURL);
117 CommandLine* command_line = CommandLine::ForCurrentProcess();
118 if (command_line->HasSwitch(::switches::kAppListStartPageURL)) {
119 url = GURL(
120 command_line->GetSwitchValueASCII(::switches::kAppListStartPageURL));
123 contents_->GetController().LoadURL(
124 url,
125 content::Referrer(),
126 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
127 std::string());
130 StartPageService::~StartPageService() {}
132 void StartPageService::AddObserver(StartPageObserver* observer) {
133 observers_.AddObserver(observer);
136 void StartPageService::RemoveObserver(StartPageObserver* observer) {
137 observers_.RemoveObserver(observer);
140 void StartPageService::ToggleSpeechRecognition() {
141 speech_button_toggled_manually_ = true;
142 contents_->GetWebUI()->CallJavascriptFunction(
143 "appList.startPage.toggleSpeechRecognition");
146 content::WebContents* StartPageService::GetStartPageContents() {
147 return CommandLine::ForCurrentProcess()->HasSwitch(
148 ::switches::kShowAppListStartPage) ? contents_.get() : NULL;
151 content::WebContents* StartPageService::GetSpeechRecognitionContents() {
152 return app_list::switches::IsVoiceSearchEnabled() ? contents_.get() : NULL;
155 void StartPageService::OnSpeechResult(
156 const base::string16& query, bool is_final) {
157 if (is_final) {
158 speech_result_obtained_ = true;
159 RecordAction(UserMetricsAction("AppList_SearchedBySpeech"));
161 FOR_EACH_OBSERVER(StartPageObserver,
162 observers_,
163 OnSpeechResult(query, is_final));
166 void StartPageService::OnSpeechSoundLevelChanged(int16 level) {
167 FOR_EACH_OBSERVER(StartPageObserver,
168 observers_,
169 OnSpeechSoundLevelChanged(level));
172 void StartPageService::OnSpeechRecognitionStateChanged(
173 SpeechRecognitionState new_state) {
174 if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) {
175 if (!speech_button_toggled_manually_ &&
176 state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) {
177 RecordAction(UserMetricsAction("AppList_HotwordRecognized"));
178 } else {
179 RecordAction(UserMetricsAction("AppList_VoiceSearchStartedManually"));
181 } else if (InSpeechRecognition(state_) && !InSpeechRecognition(new_state) &&
182 !speech_result_obtained_) {
183 RecordAction(UserMetricsAction("AppList_VoiceSearchCanceled"));
185 speech_button_toggled_manually_ = false;
186 speech_result_obtained_ = false;
187 state_ = new_state;
188 FOR_EACH_OBSERVER(StartPageObserver,
189 observers_,
190 OnSpeechRecognitionStateChanged(new_state));
193 void StartPageService::Shutdown() {
194 contents_.reset();
197 } // namespace app_list