start_page_handler.cc revision f2477e01787aa58f445919b809d89e252beef54f
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"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_service.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/recommended_apps.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/extensions/extension_icon_set.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_ui.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/event_constants.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace app_list {
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_ptr<base::DictionaryValue> CreateAppInfo(
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const extensions::Extension* app) {
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->SetString("appId", app->id());
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->SetString("textTitle", app->short_name());
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->SetString("title", app->name());
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const bool grayscale = false;
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool icon_exists = true;
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GURL icon_url = extensions::ExtensionIconSource::GetIconURL(
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      app,
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      extension_misc::EXTENSION_ICON_MEDIUM,
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ExtensionIconSet::MATCH_BIGGER,
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      grayscale,
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      &icon_exists);
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->SetString("iconUrl", icon_url.spec());
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return dict.Pass();
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)StartPageHandler::StartPageHandler() : recommended_apps_(NULL) {}
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)StartPageHandler::~StartPageHandler() {
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (recommended_apps_)
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    recommended_apps_->RemoveObserver(this);
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::RegisterMessages() {
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "initialize",
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&StartPageHandler::HandleInitialize, base::Unretained(this)));
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "launchApp",
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&StartPageHandler::HandleLaunchApp, base::Unretained(this)));
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "search",
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&StartPageHandler::HandleSearch, base::Unretained(this)));
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "setSpeechRecognitionState",
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&StartPageHandler::HandleSpeechRecognition,
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(this)));
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::OnRecommendedAppsChanged() {
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SendRecommendedApps();
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::SendRecommendedApps() {
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const RecommendedApps::Apps& recommends = recommended_apps_->apps();
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ListValue recommended_list;
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < recommends.size(); ++i) {
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    recommended_list.Append(CreateAppInfo(recommends[i].get()).release());
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_ui()->CallJavascriptFunction("appList.startPage.setRecommendedApps",
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   recommended_list);
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::HandleInitialize(const base::ListValue* args) {
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui());
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StartPageService* service = StartPageService::Get(profile);
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!service)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  recommended_apps_ = service->recommended_apps();
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  recommended_apps_->AddObserver(this);
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SendRecommendedApps();
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StartPageHandler::HandleLaunchApp(const base::ListValue* args) {
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string app_id;
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(args->GetString(0, &app_id));
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui());
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ExtensionService* service =
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile)->extension_service();
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const extensions::Extension* app = service->GetInstalledExtension(app_id);
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!app) {
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NOTREACHED();
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AppListControllerDelegate* controller = AppListService::Get(
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      chrome::GetHostDesktopTypeForNativeView(
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          web_ui()->GetWebContents()->GetView()->GetNativeView()))
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ->GetControllerDelegate();
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller->ActivateApp(profile,
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          app,
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          AppListControllerDelegate::LAUNCH_FROM_APP_LIST,
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          ui::EF_NONE);
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void StartPageHandler::HandleSearch(const base::ListValue* args) {
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::string16 query;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(args->GetString(0, &query));
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StartPageService::Get(Profile::FromWebUI(web_ui()))->OnSearch(query);
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void StartPageHandler::HandleSpeechRecognition(const base::ListValue* args) {
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool recognizing;
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CHECK(args->GetBoolean(0, &recognizing));
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StartPageService* service =
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      StartPageService::Get(Profile::FromWebUI(web_ui()));
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  service->OnSpeechRecognitionStateChanged(recognizing);
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace app_list
144