14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string> 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/command_line.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/singleton.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/user_metrics.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/prefs/pref_service.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/media/media_stream_infobar_delegate.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/search/hotword_service.h" 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/search/hotword_service_factory.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/recommended_apps.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_observer.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service_factory.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/common/pref_names.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/url_constants.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_details.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/notification_observer.h" 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/notification_registrar.h" 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/notification_service.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/notification_source.h" 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_contents.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/web_contents_delegate.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system_provider.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/app_list/app_list_switches.h" 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::RecordAction; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction; 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace app_list { 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InSpeechRecognition(SpeechRecognitionState state) { 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return state == SPEECH_RECOGNITION_RECOGNIZING || 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state == SPEECH_RECOGNITION_IN_SPEECH; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class StartPageService::ProfileDestroyObserver 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : public content::NotificationObserver { 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit ProfileDestroyObserver(StartPageService* service) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : service_(service) { 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) registrar_.Add(this, 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::NOTIFICATION_PROFILE_DESTROYED, 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<Profile>(service_->profile())); 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~ProfileDestroyObserver() {} 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // content::NotificationObserver 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Observe(int type, 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const content::NotificationSource& source, 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const content::NotificationDetails& details) OVERRIDE { 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(service_->profile(), content::Source<Profile>(source).ptr()); 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) service_->Shutdown(); 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StartPageService* service_; // Owner of this class. 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::NotificationRegistrar registrar_; 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProfileDestroyObserver); 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class StartPageService::StartPageWebContentsDelegate 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : public content::WebContentsDelegate { 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StartPageWebContentsDelegate() {} 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~StartPageWebContentsDelegate() {} 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void RequestMediaAccessPermission( 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents* web_contents, 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::MediaStreamRequest& request, 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::MediaResponseCallback& callback) OVERRIDE { 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (MediaStreamInfoBarDelegate::Create(web_contents, request, callback)) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTREACHED() << "Media stream not allowed for WebUI"; 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool CheckMediaAccessPermission( 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::WebContents* web_contents, 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& security_origin, 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::MediaStreamType type) OVERRIDE { 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return MediaCaptureDevicesDispatcher::GetInstance() 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->CheckMediaAccessPermission(web_contents, security_origin, type); 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate); 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)StartPageService* StartPageService::Get(Profile* profile) { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return StartPageServiceFactory::GetForProfile(profile); 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)StartPageService::StartPageService(Profile* profile) 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : profile_(profile), 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_destroy_observer_(new ProfileDestroyObserver(this)), 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) recommended_apps_(new RecommendedApps(profile)), 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_(app_list::SPEECH_RECOGNITION_OFF), 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) speech_button_toggled_manually_(false), 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) speech_result_obtained_(false) { 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If experimental hotwording is enabled, then we're always "ready". 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Transitioning into the "hotword recognizing" state is handled by the 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // hotword extension. 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (HotwordService::IsExperimentalHotwordingEnabled()) 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = app_list::SPEECH_RECOGNITION_READY; 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (app_list::switches::IsExperimentalAppListEnabled()) 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LoadContents(); 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)StartPageService::~StartPageService() {} 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void StartPageService::AddObserver(StartPageObserver* observer) { 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observers_.AddObserver(observer); 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void StartPageService::RemoveObserver(StartPageObserver* observer) { 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observers_.RemoveObserver(observer); 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StartPageService::AppListShown() { 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!contents_) { 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LoadContents(); 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If experimental hotwording is enabled, don't enable hotwording in the 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // start page, since the hotword extension is taking care of this. 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool hotword_enabled = HotwordEnabled() && 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) !HotwordService::IsExperimentalHotwordingEnabled(); 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch contents_->GetWebUI()->CallJavascriptFunction( 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "appList.startPage.onAppListShown", 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::FundamentalValue(hotword_enabled)); 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StartPageService::AppListHidden() { 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch contents_->GetWebUI()->CallJavascriptFunction( 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "appList.startPage.onAppListHidden"); 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!app_list::switches::IsExperimentalAppListEnabled()) 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch UnloadContents(); 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void StartPageService::ToggleSpeechRecognition() { 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) speech_button_toggled_manually_ = true; 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) contents_->GetWebUI()->CallJavascriptFunction( 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "appList.startPage.toggleSpeechRecognition"); 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool StartPageService::HotwordEnabled() { 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (HotwordService::IsExperimentalHotwordingEnabled()) { 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return HotwordServiceFactory::IsServiceAvailable(profile_) && 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled); 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_CHROMEOS) 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return HotwordServiceFactory::IsServiceAvailable(profile_) && 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled); 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#else 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::WebContents* StartPageService::GetStartPageContents() { 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return app_list::switches::IsExperimentalAppListEnabled() ? contents_.get() 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : NULL; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::WebContents* StartPageService::GetSpeechRecognitionContents() { 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (app_list::switches::IsVoiceSearchEnabled()) { 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!contents_) 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LoadContents(); 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return contents_.get(); 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartPageService::OnSpeechResult( 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& query, bool is_final) { 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_final) { 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) speech_result_obtained_ = true; 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordAction(UserMetricsAction("AppList_SearchedBySpeech")); 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FOR_EACH_OBSERVER(StartPageObserver, 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) observers_, 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnSpeechResult(query, is_final)); 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartPageService::OnSpeechSoundLevelChanged(int16 level) { 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FOR_EACH_OBSERVER(StartPageObserver, 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) observers_, 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnSpeechSoundLevelChanged(level)); 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartPageService::OnSpeechRecognitionStateChanged( 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SpeechRecognitionState new_state) { 208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!InSpeechRecognition(state_) && InSpeechRecognition(new_state)) { 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!speech_button_toggled_manually_ && 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_ == SPEECH_RECOGNITION_HOTWORD_LISTENING) { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordAction(UserMetricsAction("AppList_HotwordRecognized")); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordAction(UserMetricsAction("AppList_VoiceSearchStartedManually")); 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (InSpeechRecognition(state_) && !InSpeechRecognition(new_state) && 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !speech_result_obtained_) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordAction(UserMetricsAction("AppList_VoiceSearchCanceled")); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) speech_button_toggled_manually_ = false; 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) speech_result_obtained_ = false; 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_ = new_state; 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FOR_EACH_OBSERVER(StartPageObserver, 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observers_, 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnSpeechRecognitionStateChanged(new_state)); 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageService::Shutdown() { 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch UnloadContents(); 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StartPageService::LoadContents() { 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch contents_.reset(content::WebContents::Create( 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch content::WebContents::CreateParams(profile_))); 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch contents_delegate_.reset(new StartPageWebContentsDelegate()); 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch contents_->SetDelegate(contents_delegate_.get()); 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GURL url(chrome::kChromeUIAppListStartPageURL); 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CommandLine* command_line = CommandLine::ForCurrentProcess(); 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (command_line->HasSwitch(::switches::kAppListStartPageURL)) { 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch url = GURL( 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch command_line->GetSwitchValueASCII(::switches::kAppListStartPageURL)); 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch contents_->GetController().LoadURL( 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch url, 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch content::Referrer(), 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string()); 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StartPageService::UnloadContents() { 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents_.reset(); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace app_list 256