start_page_handler.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/webui/app_list/start_page_handler.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string> 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_service.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/search/hotword_service.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/search/hotword_service_factory.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_service.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/app_list/hotword_background_activity_monitor.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/recommended_apps.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h" 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/extensions/extension_icon_set.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/pref_names.h" 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/notification_details.h" 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/notification_source.h" 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/web_contents.h" 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/web_contents_view.h" 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_ui.h" 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/child_process_host.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/app_list/app_list_switches.h" 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/event_constants.h" 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace app_list { 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_ptr<base::DictionaryValue> CreateAppInfo( 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const extensions::Extension* app) { 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dict->SetString("appId", app->id()); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dict->SetString("textTitle", app->short_name()); 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dict->SetString("title", app->name()); 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const bool grayscale = false; 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool icon_exists = true; 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GURL icon_url = extensions::ExtensionIconSource::GetIconURL( 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app, 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension_misc::EXTENSION_ICON_MEDIUM, 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionIconSet::MATCH_BIGGER, 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) grayscale, 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &icon_exists); 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dict->SetString("iconUrl", icon_url.spec()); 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return dict.Pass(); 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)StartPageHandler::StartPageHandler() 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : recommended_apps_(NULL), 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_hotword_recognizer_(false), 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_state_(SPEECH_RECOGNITION_OFF) { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)StartPageHandler::~StartPageHandler() { 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (recommended_apps_) 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recommended_apps_->RemoveObserver(this); 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::RegisterMessages() { 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) web_ui()->RegisterMessageCallback( 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "initialize", 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&StartPageHandler::HandleInitialize, base::Unretained(this))); 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) web_ui()->RegisterMessageCallback( 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "launchApp", 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&StartPageHandler::HandleLaunchApp, base::Unretained(this))); 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_ui()->RegisterMessageCallback( 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "setHotwordRecognizerState", 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&StartPageHandler::HandleHotwordRecognizerState, 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this))); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) web_ui()->RegisterMessageCallback( 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "speechResult", 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&StartPageHandler::HandleSpeechResult, 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this))); 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) web_ui()->RegisterMessageCallback( 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "speechSoundLevel", 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&StartPageHandler::HandleSpeechSoundLevel, 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this))); 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_ui()->RegisterMessageCallback( 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "setSpeechRecognitionState", 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&StartPageHandler::HandleSpeechRecognition, 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(this))); 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void StartPageHandler::Observe(int type, 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const content::NotificationSource& source, 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const content::NotificationDetails& details) { 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(Profile::FromWebUI(web_ui()), 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::Source<Profile>(source).ptr()); 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (type) { 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_LOADED: { 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::Extension* extension = 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::Details<extensions::Extension>(details).ptr(); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (extension->id() == extension_misc::kHotwordExtensionId) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnHotwordEnabledChanged(); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::UnloadedExtensionInfo* info = 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::Details<extensions::UnloadedExtensionInfo>(details).ptr(); 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (info->extension->id() == extension_misc::kHotwordExtensionId) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnHotwordEnabledChanged(); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int StartPageHandler::GetRenderProcessID() { 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!web_ui()) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return content::ChildProcessHost::kInvalidUniqueID; 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::WebContents* web_contents = web_ui()->GetWebContents(); 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return web_contents->GetRenderProcessHost()->GetID(); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void StartPageHandler::OnHotwordBackgroundActivityChanged() { 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (has_hotword_recognizer_ && switches::IsHotwordAlwaysOnEnabled()) { 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) web_ui()->CallJavascriptFunction( 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (hotword_monitor_ && hotword_monitor_->IsHotwordBackgroundActive()) ? 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "appList.startPage.startHotwordRecognition" : 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "appList.startPage.stopHotwordRecognition"); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::OnRecommendedAppsChanged() { 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SendRecommendedApps(); 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::SendRecommendedApps() { 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const RecommendedApps::Apps& recommends = recommended_apps_->apps(); 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::ListValue recommended_list; 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < recommends.size(); ++i) { 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recommended_list.Append(CreateAppInfo(recommends[i].get()).release()); 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) web_ui()->CallJavascriptFunction("appList.startPage.setRecommendedApps", 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recommended_list); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool StartPageHandler::HotwordEnabled() { 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!HotwordService::DoesHotwordSupportLanguage(profile)) 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const PrefService::Preference* preference = 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) profile->GetPrefs()->FindPreference(prefs::kHotwordSearchEnabled); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!preference) 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!HotwordServiceFactory::IsServiceAvailable(profile)) 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // kHotwordSearchEnabled is off by default, but app-list is on by default. 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // To achieve this, we'll return true if it's in the default status. 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (preference->IsDefaultValue()) 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool isEnabled = false; 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return preference->GetValue()->GetAsBoolean(&isEnabled) && isEnabled; 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void StartPageHandler::OnHotwordEnabledChanged() { 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_ui()->CallJavascriptFunction( 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "appList.startPage.setHotwordEnabled", 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FundamentalValue(HotwordEnabled())); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::HandleInitialize(const base::ListValue* args) { 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StartPageService* service = StartPageService::Get(profile); 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!service) 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recommended_apps_ = service->recommended_apps(); 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recommended_apps_->AddObserver(this); 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SendRecommendedApps(); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (app_list::switches::IsVoiceSearchEnabled() && 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HotwordService::DoesHotwordSupportLanguage(profile)) { 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnHotwordEnabledChanged(); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Init(profile->GetPrefs()); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Add( 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs::kHotwordSearchEnabled, 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&StartPageHandler::OnHotwordEnabledChanged, 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this))); 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::Source<Profile>(profile)); 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::Source<Profile>(profile)); 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hotword_monitor_.reset(new HotwordBackgroundActivityMonitor(this)); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool StartPageHandler::ShouldRunHotwordBackground() { 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return has_hotword_recognizer_ && switches::IsHotwordAlwaysOnEnabled() && 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hotword_monitor_ && hotword_monitor_->IsHotwordBackgroundActive(); 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::HandleLaunchApp(const base::ListValue* args) { 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string app_id; 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CHECK(args->GetString(0, &app_id)); 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionService* service = 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extensions::ExtensionSystem::Get(profile)->extension_service(); 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const extensions::Extension* app = service->GetInstalledExtension(app_id); 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!app) { 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AppListControllerDelegate* controller = AppListService::Get( 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::GetHostDesktopTypeForNativeView( 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_ui()->GetWebContents()->GetView()->GetNativeView())) 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ->GetControllerDelegate(); 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) controller->ActivateApp(profile, 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app, 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AppListControllerDelegate::LAUNCH_FROM_APP_LIST, 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ui::EF_NONE); 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void StartPageHandler::HandleHotwordRecognizerState( 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::ListValue* args) { 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(args->GetBoolean(0, &has_hotword_recognizer_)); 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (last_state_ == SPEECH_RECOGNITION_READY && ShouldRunHotwordBackground()) { 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) web_ui()->CallJavascriptFunction( 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "appList.startPage.startHotwordRecognition"); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartPageHandler::HandleSpeechResult(const base::ListValue* args) { 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::string16 query; 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_final = false; 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(args->GetString(0, &query)); 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK(args->GetBoolean(1, &is_final)); 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StartPageService::Get(Profile::FromWebUI(web_ui()))->OnSpeechResult( 267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) query, is_final); 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void StartPageHandler::HandleSpeechSoundLevel(const base::ListValue* args) { 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) double level; 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK(args->GetDouble(0, &level)); 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StartPageService* service = 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StartPageService::Get(Profile::FromWebUI(web_ui())); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (service) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) service->OnSpeechSoundLevelChanged(static_cast<int16>(level)); 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void StartPageHandler::HandleSpeechRecognition(const base::ListValue* args) { 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string state_string; 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK(args->GetString(0, &state_string)); 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpeechRecognitionState new_state = SPEECH_RECOGNITION_OFF; 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (state_string == "READY") 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_state = SPEECH_RECOGNITION_READY; 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (state_string == "HOTWORD_RECOGNIZING") 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_state = SPEECH_RECOGNITION_HOTWORD_LISTENING; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (state_string == "RECOGNIZING") 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_state = SPEECH_RECOGNITION_RECOGNIZING; 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (state_string == "IN_SPEECH") 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new_state = SPEECH_RECOGNITION_IN_SPEECH; 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (state_string == "STOPPING") 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_state = SPEECH_RECOGNITION_STOPPING; 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_state_ = new_state; 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StartPageService* service = StartPageService::Get(profile); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (service) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) service->OnSpeechRecognitionStateChanged(new_state); 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (new_state == SPEECH_RECOGNITION_READY && ShouldRunHotwordBackground()) { 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) web_ui()->CallJavascriptFunction( 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "appList.startPage.startHotwordRecognition"); 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace app_list 309